Compare commits

..

2 Commits

Author SHA1 Message Date
2d42e3016d Merge branch 'master' into dist/eole/2.7.0/master 2020-05-12 11:35:36 +02:00
ba4acc1b89 ajout repertoire debian 2020-05-12 09:49:53 +02:00
65 changed files with 269 additions and 4254 deletions

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
7

24
debian/control vendored Normal file
View File

@@ -0,0 +1,24 @@
Source: eole-schedule
Section: web
Priority: optional
Maintainer: Cadoles <contact@cadoles.com>
Build-Depends: debhelper (>= 7.0.50)
Standards-Version: 3.8.4
Homepage: https://forge.cadoles.com/Cadoles/schedule
Vcs-Git: https://forge.cadoles.com/Cadoles/schedule
Vcs-Browser: https://forge.cadoles.com/Cadoles/schedule
Package: schedule-sso
Architecture: all
Depends: ${misc:Depends}, eole-sso
Description: Filtre SSO pour schedule "EOLE".
Package: eole-schedule
Architecture: all
Depends: ${misc:Depends}, eole-envole-dependances, schedule-sso
Description: Eolisation de l'application schedule.
Package: schedule-apps
Architecture: all
Depends: ${misc:Depends}, envole-dependances-apps
Description: Sources pour schedule "EOLE".

44
debian/copyright vendored Normal file
View File

@@ -0,0 +1,44 @@
Format: http://dep.debian.net/deps/dep5
Upstream-Name: {PROJECT}
Source: {URL}
Files: *
Copyright: YEAR {UPSTREAM} {AUTHOR} <{MAIL}>
License: {UPSTREAM LICENSE}
Files: debian/*
Copyright: 2012 Équipe EOLE <eole@ac-dijon.fr>
License: CeCILL-2
License: {UPSTREAM LICENSE}
{TEXT OF THE LICENSE}
License: CeCILL-2
This software is governed by the CeCILL-2 license under French law and
abiding by the rules of distribution of free software. You can use,
modify and or redistribute the software under the terms of the CeCILL-2
license as circulated by CEA, CNRS and INRIA at the following URL
"http://www.cecill.info";.
.
As a counterpart to the access to the source code and rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty and the software's author, the holder of the
economic rights, and the successive licensors have only limited
liability.
.
In this respect, the user's attention is drawn to the risks associated
with loading, using, modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean that it is complicated to manipulate, and that also
therefore means that it is reserved for developers and experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and, more generally, to use and operate it in the
same conditions as regards security.
.
The fact that you are presently reading this means that you have had
knowledge of the CeCILL-2 license and that you accept its terms.
.
On Eole systems, the complete text of the CeCILL-2 License can be found
in '/usr/share/common-licenses/CeCILL-2-en'.

1
debian/eole-schedule.install vendored Normal file
View File

@@ -0,0 +1 @@
usr/share/eole

3
debian/gbp.conf vendored Normal file
View File

@@ -0,0 +1,3 @@
# Set per distribution debian tag
[DEFAULT]
debian-tag = debian/envole/%(version)s

8
debian/rules vendored Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@

1
debian/schedule-apps.install vendored Normal file
View File

@@ -0,0 +1 @@
var/www/html

1
debian/schedule-sso.install vendored Normal file
View File

@@ -0,0 +1 @@
usr/share/sso

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (native)

View File

@@ -6,9 +6,7 @@
<containers> <containers>
<container name='web'> <container name='web'>
<!-- <package>schedule-apps</package>
<package>schedule-apps</package>
-->
<!-- service de configuration apache --> <!-- service de configuration apache -->
<service method="apache" servicelist="schedule">schedule</service> <service method="apache" servicelist="schedule">schedule</service>
@@ -34,7 +32,6 @@
<variable type='string' name='schedule_allow_hosts' description="Hôtes authorisés à utiliser la base de données" multi='True'/> <variable type='string' name='schedule_allow_hosts' description="Hôtes authorisés à utiliser la base de données" multi='True'/>
<variable type='string' name='schedule_dbuser' description='Utilisateur du serveur de base de données'/> <variable type='string' name='schedule_dbuser' description='Utilisateur du serveur de base de données'/>
<variable type='string' name='schedule_dbpass' description='Fichier de mot de passe du serveur'/> <variable type='string' name='schedule_dbpass' description='Fichier de mot de passe du serveur'/>
<variable type='mail' name='schedule_email_global_notif' description='Email pour envoie de notifications'/>
</family> </family>
</variables> </variables>

View File

@@ -32,16 +32,6 @@ APP_NAME=Schedule
APP_ENV=PROD APP_ENV=PROD
APP_CRON=false APP_CRON=false
# Office hours
OFFICE_HOUR_START=09:00
OFFICE_HOUR_END=17:30
# MAIL sendmail / smtp
MAILER_METHOD=sendmail
MAILER_URL=
MAILER_NOREPLY=noreply@noreply.fr
MAILER_DEFAULT_NOTIF=
# BDD # BDD
DATABASE_NAME= DATABASE_NAME=
DATABASE_USER= DATABASE_USER=
@@ -56,9 +46,3 @@ CAS_USERNAME=username
CAS_EMAIL=email CAS_EMAIL=email
CAS_LASTNAME=lastname CAS_LASTNAME=lastname
CAS_FIRSTNAME=firstname CAS_FIRSTNAME=firstname
###> symfony/swiftmailer-bundle ###
# For Gmail as a transport, use: "gmail://username:password@localhost"
# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
# Delivery is disabled by default via "null://localhost"
MAILER_URL=

View File

@@ -17,6 +17,7 @@
###> symfony/webpack-encore-bundle ### ###> symfony/webpack-encore-bundle ###
/node_modules/ /node_modules/
/public/build/
npm-debug.log npm-debug.log
yarn-error.log yarn-error.log
###< symfony/webpack-encore-bundle ### ###< symfony/webpack-encore-bundle ###

View File

@@ -1,609 +0,0 @@
/* Creates a new Task object. */
function Task(id ,name, description) {
this._name = name;
this._taskid = id;
this._description = description;
this._state = Task.State.STOPPED;
this._timeSpentInPreviousIterations = 0;
this._startDate = 0;
this._endDate = 0;
this._currentIterationStartTime = 0;
this._customTimeSpent = 0;
this._onChange = null;
}
/* Possible task states. */
Task.State = {
STOPPED: "stopped",
RUNNING: "running"
}
Task.prototype = {
/* Returns the task name. */
getName: function() {
return this._name;
},
/* Returns the task description. */
getDescription: function() {
if (this._description == "NaN") {
this._description = ""
}
return this._description;
},
/* Returns the task state. */
getState: function() {
return this._state;
},
/* Is the task stopped? */
isStopped: function() {
return this._state == Task.State.STOPPED;
},
/* Is the task running? */
isRunning: function() {
return this._state == Task.State.RUNNING;
},
/*
* Sets the "onChange" event handler. The "onChange" event is fired when the
* task is started, stopped, or reset.
*/
setOnChange: function(onChange) {
this._onChange = onChange;
},
/*
* Returns the time spent on the task in the current work iteration. Works
* correctly only when the task is running.
*/
_getCurrentIterationTime: function() {
return (new Date).getTime() - this._currentIterationStartTime;
},
/*
* Returns the total time spent on the task. This includes time spent in
* the current work iteration if the task is running.
*/
getTimeSpent: function() {
var result = this._timeSpentInPreviousIterations;
if (this._state == Task.State.RUNNING) {
result += this._getCurrentIterationTime();
}
return result;
},
/* Calls the "onChange" event handler if set. */
_callOnChange: function() {
if (typeof this._onChange == "function") {
this._onChange();
}
},
/* Starts a new task work iteration. */
start: function() {
if (this._state == Task.State.RUNNING) { return };
if (this._startDate == 0) {this._startDate = new Date()}
this._state = Task.State.RUNNING;
this._currentIterationStartTime = (new Date).getTime();
this._callOnChange();
},
/* Stops the current task work iteration. */
stop: function() {
if (this._state == Task.State.STOPPED) { return };
this._state = Task.State.STOPPED;
this._timeSpentInPreviousIterations += this._getCurrentIterationTime();
this._currentIterationStartTime = 0;
this._endDate = new Date();
this._callOnChange();
},
/* Stops the current task work iteration and resets the time data. */
reset: function() {
this.stop();
this._timeSpentInPreviousIterations = 0;
this._callOnChange();
},
save: function(task){
console.log(task)
$.ajax({
type: "POST",
data: {
taskname: task._name,
taskid: task._taskid,
description: task._description,
start: task._startDate,
end: task._endDate,
duration: task._timeSpentInPreviousIterations,
},
url: "{{ path('app_timer_create') }}",
success: function (response) {
response=JSON.parse(response);
if(response.return=="KO") {
$("#dataTable_wrapper").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
}else{
location.reload();
}
}
});
},
/* Serializes the task into a string. */
serialize: function() {
/*
* Originally, I wanted to use "toSource" and "eval" for serialization and
* deserialization, but "toSource" is not supported by WebKit, so I resorted
* to ugly hackery...
*/
return [
encodeURIComponent(this._name),
this._state,
this._timeSpentInPreviousIterations,
this._currentIterationStartTime,
this._startDate,
this._endDate,
this._taskid,
this._description,
].join("&");
},
/* Deserializes the task from a string. */
deserialize: function(serialized) {
var parts = serialized.split("&");
this._name = decodeURIComponent(parts[0]);
this._state = parts[1];
this._timeSpentInPreviousIterations = parseInt(parts[2]);
this._currentIterationStartTime = parseInt(parts[3]);
this._startDate = parseInt(parts[4]);
this._endDate = parseInt(parts[5]);
this._taskid = parseInt(parts[6]);
this._description = parseInt(parts[7]);
}
}
/* ===== Tasks ===== */
/* The Tasks class represents a list of tasks. */
/* Creates a new Tasks object. */
function Tasks() {
this._tasks = [];
this._onAdd = null;
this._onRemove = null;
}
Tasks.prototype = {
/*
* Sets the "onAdd" event handler. The "onAdd" event is fired when a task
* is added to the list.
*/
setOnAdd: function(onAdd) {
this._onAdd = onAdd;
},
/*
* Sets the "onRemove" event handler. The "onRemove" event is fired when a
* task is removed from the list.
*/
setOnRemove: function(onRemove) {
this._onRemove = onRemove;
},
/* Returns the length of the task list. */
length: function() {
return this._tasks.length
},
/*
* Returns index-th task in the list, or "undefined" if the index is out of
* bounds.
*/
get: function(index) {
return this._tasks[index];
},
/*
* Calls the callback function for each task in the list. The function is
* called with three parameters - the task, its index and the task list
* object. This is modeled after "Array.forEach" in JavaScript 1.6.
*/
forEach: function(callback) {
for (var i = 0; i < this._tasks.length; i++) {
callback(this._tasks[i], i, this);
}
},
/* Calls the "onAdd" event handler if set. */
_callOnAdd: function(task) {
if (typeof this._onAdd == "function") {
this._onAdd(task);
}
},
/* Adds a new task to the end of the list. */
add: function(task) {
this._tasks.push(task);
this._callOnAdd(task);
},
/* Calls the "onRemove" event handler if set. */
_callOnRemove: function(index) {
if (typeof this._onRemove == "function") {
this._onRemove(index);
}
},
/*
* Removes index-th task from the list. Does not do anything if the index
* is out of bounds.
*/
remove: function(index) {
this._callOnRemove(index);
this._tasks.splice(index, 1);
},
/* Serializes the list of tasks into a string. */
serialize: function() {
var serializedTasks = [];
this.forEach(function(task) {
serializedTasks.push(task.serialize());
});
return serializedTasks.join("|");
},
/* Deserializes the list of tasks from a string. */
deserialize: function(serialized) {
/*
* Repeatedly use "remove" so the "onRemove" event is triggered. Do the same
* with the "add" method below.
*/
while (this._tasks.length > 0) {
this.remove(0);
}
var serializedTasks = serialized.split("|");
for (var i = 0; i < serializedTasks.length; i++) {
var task = new Task(0 ,"", "");
task.deserialize(serializedTasks[i]);
this.add(task);
}
}
}
/* ===== Extensions ===== */
/*
* Pads this string with another string on the left until the resulting string
* has specified length. If the padding string has more than one character, the
* resulting string may be longer than desired (the padding string is not
* truncated and it is only prepended as a whole). Bad API, I know, but it's
* good enough for me.
*/
String.prototype.pad = function(length, padding) {
var result = this;
while (result.length < length) {
result = padding + result;
}
return result;
}
/* ===== Task List + DOM Storage ===== */
/* The list of tasks. */
var tasks = new Tasks();
/* The last value of the serialized task list string. */
var lastSerializedTasksString;
/*
* The key under which the serialized task list string is stored in the DOM
* Storage.
*/
var TASKS_DOM_STORAGE_KEY = "timerTasks";
/*
* Returns DOM Storage used by the application, or "null" if the browser does
* not support DOM Storage.
*/
function getStorage() {
/*
* HTML 5 says that the persistent storage is available in the
* "window.localStorage" attribute, however Firefox implements older version
* of the proposal, which uses "window.globalStorage" indexed by the domain
* name. We deal with this situation here as gracefully as possible (i.e.
* without concrete browser detection and with forward compatibility).
*
* For more information, see:
*
* http://www.whatwg.org/specs/web-apps/current-work/#storage
* https://developer.mozilla.org/En/DOM/Storage
*/
if (window.localStorage !== undefined) {
return window.localStorage;
} else if (window.globalStorage !== undefined) {
return window.globalStorage[location.hostname];
} else {
return null;
}
}
/*
* Saves the task list into a DOM Storage. Also updates the value of the
* "lastSerializedTasksString" variable.
*/
function saveTasks() {
var serializedTasksString = tasks.serialize();
getStorage()[TASKS_DOM_STORAGE_KEY] = serializedTasksString;
lastSerializedTasksString = serializedTasksString;
}
/*
* Loads the serialized task list string from the DOM Storage. Returns
* "undefined" if the storage does not contain the string (this happens when
* running the application for the first time).
*/
function loadSerializedTasksString() {
var storedValue = getStorage()[TASKS_DOM_STORAGE_KEY];
/*
* The spec says "null" should be returned when the key is not found, but some
* browsers return "undefined" instead. Maybe it was in some earlier version
* of the spec (I didn't bother to check).
*/
if (storedValue !== null && storedValue !== undefined && storedValue.length > 0) {
/*
* The values retrieved from "globalStorage" use one more level of
* indirection.
*/
return (window.localStorage === undefined) ? storedValue.value : storedValue;
} else {
return undefined;
}
}
/*
* Loads the task list from the DOM Storage. Also updates the value of the
* "lastSerializedTasksString" variable.
*/
function loadTasks() {
var serializedTasksString = loadSerializedTasksString();
if (serializedTasksString !== undefined) {
tasks.deserialize(serializedTasksString);
lastSerializedTasksString = serializedTasksString;
}
}
/*
* Was the task list changed outside of the application? Detects the change
* by comparing the current serialized task list string in the DOM Storage
* with a kept old value.
*/
function tasksHaveChangedOutsideApplication() {
var serializedTasksString = loadSerializedTasksString();
if (serializedTasksString != lastSerializedTasksString) {
return true
}
return false;
}
/* ===== View ===== */
/* Some time constants. */
var MILISECONDS_IN_SECOND = 1000;
var MILISECONDS_IN_MINUTE = 60 * MILISECONDS_IN_SECOND;
var MINUTES_IN_HOUR = 60;
/* Formats the time in the H:MM format. */
function formatTime(time) {
var timeInMinutes = time / MILISECONDS_IN_MINUTE;
var hours = Math.floor(timeInMinutes / MINUTES_IN_HOUR);
var minutes = Math.floor(timeInMinutes - hours * MINUTES_IN_HOUR);
return hours + ":" + String(minutes).pad(2, "0");
}
/*
* Computes the URL of the image in the start/stop link according to the task
* state.
*/
function computeStartStopLinkImageUrl(state) {
switch (state) {
case Task.State.STOPPED:
return "fa-play";
case Task.State.RUNNING:
return "fa-stop";
default:
throw "Invalid task state."
}
}
/*
* Builds the HTML element of the row in the task table corresponding to the
* specified task and index.
*/
function buildTaskRow(task, index) {
var result = $("<tr />");
var startStopLink = $(
"<a href='#' class='start-stop-link' title='Start/stop'>"
+ "<i class='fa " + computeStartStopLinkImageUrl(task.getState()) + "'></i>"
);
startStopLink.click(function() {
switch (task.getState()) {
case Task.State.STOPPED:
task.start();
break;
case Task.State.RUNNING:
task.stop();
break;
default:
throw "Invalid task state."
}
saveTasks();
return false;
});
var resetLink = $(
"<a href='#' title='Reset'>"
+ "<i class='fa fa-undo'></i>"
);
resetLink.click(function() {
task.reset();
saveTasks();
return false;
});
var deleteLink = $(
"<a href='#' title='Delete' class='deletetask'>"
+ "<i class='fa fa-trash-alt' class='deletetask'></i>"
);
deleteLink.click(function() {
if (confirm("Do you really want to delete task \"" + task.getName() + "\"?")) {
tasks.remove(index);
saveTasks();
}
return false;
});
var saveLink = $(
"<a href='#' title='Save' class='savetask'>"
+ "<i class='fa fa-download' class='savetask'></i>"
);
saveLink.click(function() {
tasks.remove(index);
saveTasks();
task.save(task);
return false;
});
result
.addClass("state-" + task.getState())
.append($("<td class='task-name' />").text(task.getName()))
.append($("<td class='task-description' />").text(task.getDescription()))
.append($("<td class='task-time' />").text(formatTime(task.getTimeSpent())))
.append($("<td class='task-actions' />")
.append(startStopLink)
.append("&nbsp;&nbsp;")
.append(resetLink)
.append("&nbsp;&nbsp;")
.append(saveLink)
.append("&nbsp;&nbsp;&nbsp;&nbsp;")
.append(deleteLink)
);
return result;
}
/* Finds row with the specified index in the task table. */
function findRowWithIndex(index) {
return $("#task-table").find("tr").slice(1).eq(index);
}
/*
* Updates the row in the task table corresponding to a task according to
* its state.
*/
function updateTaskRow(row, task) {
if (task.isStopped()) {
row.removeClass("state-running");
row.addClass("state-stopped");
} else if (task.isRunning()) {
row.removeClass("state-stopped");
row.addClass("state-running");
}
row.find(".task-time").text(formatTime(task.getTimeSpent()))
row.find(".start-stop-link i").removeClass();
row.find(".start-stop-link i").addClass("fa "+computeStartStopLinkImageUrl(task.getState()));
}
/* ===== Initialization ===== */
/* Initializes event handlers on the task list. */
function initializeTasksEventHandlers() {
tasks.setOnAdd(function(task) {
var row = buildTaskRow(task, tasks.length() - 1);
$("#task-table").append(row);
task.setOnChange(function() {
updateTaskRow(row, task);
});
});
tasks.setOnRemove(function(index) {
findRowWithIndex(index).remove();
if (tasks.length() == 1 ) {
$( "#task-table" ).css({"display":"none"});
}
});
}
/* Initializes GUI event handlers. */
function initializeGuiEventHandlers() {
$( "#addtimer" ).click(function() {
displayTaskAdd();
});
$( "#timer-desc" ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
displayTaskAdd();
}
});
}
function displayTaskAdd() {
$( "#task-table" ).css({"display":"inline"});
var taskName = $("#timer-task option:selected").text();
var taskId = $("#timer-task option:selected").val();
var taskDesc = $("#timer-desc").val();
var task = new Task(taskId, taskName, taskDesc);
tasks.add(task);
saveTasks();
$("#timer-desc").val("");
}
/*
* Initializes a timer used to update task times and detect changes in the
* data stored in the DOM Storage.
*/
function initializeTimer() {
setInterval(function() {
tasks.forEach(function(task, index) {
updateTaskRow(findRowWithIndex(index), task);
});
if (tasksHaveChangedOutsideApplication()) {
loadTasks();
}
}, 10 * MILISECONDS_IN_SECOND);
}
/* Initializes the application. */
$(document).ready(function(){
try {
if (!getStorage()) {
alert("Timer requires a browser with DOM Storage support, such as Firefox 3+ or Safari 4+.");
return;
}
} catch (e) {
alert("Timer does not work with file: URLs in Firefox.");
return;
}
initializeTasksEventHandlers();
loadTasks();
initializeGuiEventHandlers();
initializeTimer();
});

View File

@@ -33,7 +33,6 @@
"symfony/profiler-pack": "^1.0", "symfony/profiler-pack": "^1.0",
"symfony/security-bundle": "4.4.*", "symfony/security-bundle": "4.4.*",
"symfony/serializer-pack": "*", "symfony/serializer-pack": "*",
"symfony/swiftmailer-bundle": "^3.4",
"symfony/translation": "4.4.*", "symfony/translation": "4.4.*",
"symfony/twig-pack": "*", "symfony/twig-pack": "*",
"symfony/validator": "4.4.*", "symfony/validator": "4.4.*",

View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "1be2a2e3a398eb23cd3c3e26bc75c090", "content-hash": "24b27b5f4efd6efcabe5c89e1e1ac51b",
"packages": [ "packages": [
{ {
"name": "doctrine/annotations", "name": "doctrine/annotations",
@@ -2557,68 +2557,6 @@
], ],
"time": "2019-12-27T08:57:19+00:00" "time": "2019-12-27T08:57:19+00:00"
}, },
{
"name": "swiftmailer/swiftmailer",
"version": "v6.2.3",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
"shasum": ""
},
"require": {
"egulias/email-validator": "~2.0",
"php": ">=7.0.0",
"symfony/polyfill-iconv": "^1.0",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0"
},
"require-dev": {
"mockery/mockery": "~0.9.1",
"symfony/phpunit-bridge": "^3.4.19|^4.1.8"
},
"suggest": {
"ext-intl": "Needed to support internationalized email addresses",
"true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.2-dev"
}
},
"autoload": {
"files": [
"lib/swift_required.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Chris Corbyn"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
}
],
"description": "Swiftmailer, free feature-rich PHP mailer",
"homepage": "https://swiftmailer.symfony.com",
"keywords": [
"email",
"mail",
"mailer"
],
"time": "2019-11-12T09:31:26+00:00"
},
{ {
"name": "symfony/apache-pack", "name": "symfony/apache-pack",
"version": "v1.0.1", "version": "v1.0.1",
@@ -5873,71 +5811,6 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2020-01-04T13:00:46+00:00" "time": "2020-01-04T13:00:46+00:00"
}, },
{
"name": "symfony/swiftmailer-bundle",
"version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/swiftmailer-bundle.git",
"reference": "553d2474288349faed873da8ab7c1551a00d26ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/swiftmailer-bundle/zipball/553d2474288349faed873da8ab7c1551a00d26ae",
"reference": "553d2474288349faed873da8ab7c1551a00d26ae",
"shasum": ""
},
"require": {
"php": ">=7.1",
"swiftmailer/swiftmailer": "^6.1.3",
"symfony/config": "^4.3.8|^5.0",
"symfony/dependency-injection": "^4.3.8|^5.0",
"symfony/http-kernel": "^4.3.8|^5.0"
},
"conflict": {
"twig/twig": "<1.41|<2.10"
},
"require-dev": {
"symfony/console": "^4.3.8|^5.0",
"symfony/framework-bundle": "^4.3.8|^5.0",
"symfony/phpunit-bridge": "^4.3.8|^5.0",
"symfony/yaml": "^4.3.8|^5.0"
},
"suggest": {
"psr/log": "Allows logging"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Bundle\\SwiftmailerBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony SwiftmailerBundle",
"homepage": "http://symfony.com",
"time": "2019-11-14T16:18:31+00:00"
},
{ {
"name": "symfony/templating", "name": "symfony/templating",
"version": "v4.4.5", "version": "v4.4.5",

View File

@@ -19,5 +19,4 @@ return [
Tetranz\Select2EntityBundle\TetranzSelect2EntityBundle::class => ['all' => true], Tetranz\Select2EntityBundle\TetranzSelect2EntityBundle::class => ['all' => true],
Oneup\UploaderBundle\OneupUploaderBundle::class => ['all' => true], Oneup\UploaderBundle\OneupUploaderBundle::class => ['all' => true],
Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true], Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true],
Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true],
]; ];

View File

@@ -1,5 +0,0 @@
swiftmailer:
url: '%env(MAILER_URL)%'
spool:
type: file
path: '%kernel.project_dir%/var/spoolmail'

View File

@@ -1,5 +0,0 @@
swiftmailer:
url: '%env(MAILER_URL)%'
spool:
type: file
path: '%kernel.project_dir%/var/spoolmail'

View File

@@ -343,52 +343,6 @@ app_validationholiday_activeholiday:
path: /validator/validateholiday/activeholiday path: /validator/validateholiday/activeholiday
defaults: { _controller: App\Controller\ValidationController:activeholiday } defaults: { _controller: App\Controller\ValidationController:activeholiday }
#== Validationtimer ====================================================================================================
app_validationtimer:
path: /validator/validationtimer
defaults: { _controller: App\Controller\ValidationController:validationtimer }
app_validationtimer_validate:
path: /validator/validatetimer
defaults: { _controller: App\Controller\ValidationController:validatetimer }
app_validationtimer_devalidate:
path: /validator/devalidatetimer
defaults: { _controller: App\Controller\ValidationController:devalidatetimer }
app_validationtimer_activetimer:
path: /validator/validateholiday/activetimer
defaults: { _controller: App\Controller\ValidationController:activetimer }
#== Timer ====================================================================================================
app_timer:
path: /timer
defaults: { _controller: App\Controller\TimerController:list }
app_timer_view:
path: /timer/event
defaults: { _controller: App\Controller\TimerController:view }
app_timer_load:
path: /timer/event/load
defaults: { _controller: App\Controller\TimerController:load }
app_timer_submit:
path: /timer/submit
defaults: { _controller: App\Controller\TimerController:submit }
app_timer_create:
path: /timer/create
defaults: { _controller: App\Controller\TimerController:create }
app_timer_update:
path: /timer/update/{id}
defaults: { _controller: App\Controller\TimerController:update }
app_timer_delete:
path: /timer/delete/{id}
defaults: { _controller: App\Controller\TimerController:delete }
#== Customer ====================================================================================================== #== Customer ======================================================================================================
app_customer_report: app_customer_report:
@@ -397,25 +351,7 @@ app_customer_report:
app_customer_planning: app_customer_planning:
path: /customer/planning/{key} path: /customer/planning/{key}
defaults: { _controller: App\Controller\ReportController:planning, access: 'customer' } defaults: { _controller: App\Controller\ReportController:planning, access: 'customer' }
#== Export ======================================================================================================
app_export_view:
path: /export
defaults: { _controller: App\Controller\ExportController:view }
app_export_penalty_additional:
path: /export/export_penalty_additional
defaults: { _controller: App\Controller\ExportController:export_penalty_additional }
export_project_weekly:
path: /export/export_project_weekly
defaults: { _controller: App\Controller\ExportController:export_project_weekly }
export_full_worked_days:
path: /export/export_full_worked_days
defaults: { _controller: App\Controller\ExportController:export_full_worked_days }
#== API =========================================================================================================== #== API ===========================================================================================================
app_api: app_api:

View File

@@ -9,9 +9,6 @@ parameters:
appName: '%env(resolve:APP_NAME)%' appName: '%env(resolve:APP_NAME)%'
appEnv: '%env(resolve:APP_ENV)%' appEnv: '%env(resolve:APP_ENV)%'
appCron: '%env(resolve:APP_CRON)%' appCron: '%env(resolve:APP_CRON)%'
appMailmethod: '%env(resolve:MAILER_METHOD)%'
appMailnoreply: '%env(resolve:MAILER_NOREPLY)%'
appMailnotif: '%env(resolve:MAILER_DEFAULT_NOTIF)%'
casHost: '%env(resolve:CAS_HOST)%' casHost: '%env(resolve:CAS_HOST)%'
casPort: '%env(resolve:CAS_PORT)%' casPort: '%env(resolve:CAS_PORT)%'
casPath: '%env(resolve:CAS_PATH)%' casPath: '%env(resolve:CAS_PATH)%'
@@ -19,8 +16,6 @@ parameters:
casEmail: '%env(resolve:CAS_EMAIL)%' casEmail: '%env(resolve:CAS_EMAIL)%'
casLastname: '%env(resolve:CAS_LASTNAME)%' casLastname: '%env(resolve:CAS_LASTNAME)%'
casFirstname: '%env(resolve:CAS_FIRSTNAME)%' casFirstname: '%env(resolve:CAS_FIRSTNAME)%'
officeHourStart: '%env(resolve:OFFICE_HOUR_START)%'
officeHourEnd: '%env(resolve:OFFICE_HOUR_END)%'
services: services:
# default configuration for services in *this* file # default configuration for services in *this* file
@@ -64,12 +59,3 @@ services:
tags: tags:
- { name: kernel.event_listener, event: kernel.request, method: onDomainParse } - { name: kernel.event_listener, event: kernel.request, method: onDomainParse }
app.sendmail.transport:
class: Swift_SendmailTransport
public: true
arguments: ['/usr/sbin/sendmail -t']
app.mail.service:
public: true
class: App\Service\mailService
arguments: ["@mailer", "@twig"]

View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
if [ ! -f /var/www/html/schedule/.key ]; then if [ ! -f /var/www/html/schedule/.key ]; then
openssl rand -hex 32 > /var/www/html/schedule/.key cat /dev/urandom | tr -dc '_A-Za-z0-9' | head -c${1:-32} > /var/www/html/schedule/.key
fi fi

View File

@@ -1,87 +0,0 @@
<?php
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
class SendMailCommand extends Command
{
private $container;
private $em;
private $output;
private $filesystem;
private $rootlog;
public function __construct(ContainerInterface $container,EntityManagerInterface $em)
{
parent::__construct();
$this->container = $container;
$this->em = $em;
}
protected function configure()
{
$this
->setName('app:sendMail')
->setDescription('Envoi des mails')
->setHelp('Envoi des mails')
->addArgument('message-limit', InputArgument::OPTIONAL, 'limit message Mail')
->addArgument('env', InputArgument::OPTIONAL, 'env Mail')
->addArgument('cronid', InputArgument::OPTIONAL, 'ID Cron Job')
->addArgument('lastchance', InputArgument::OPTIONAL, 'Lastchance to run the cron')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->output = $output;
$this->filesystem = new Filesystem();
$this->rootlog = $this->container->get('kernel')->getRootDir()."/../var/logs/";
$this->writelnred('');
$this->writelnred('== app:sendMail');
$this->writelnred('==========================================================================================================');
$appMailmethod=$this->container->getParameter("appMailmethod");
$command = $this->getApplication()->find("swiftmailer:spool:send");
$tbparameter["--message-limit"]=100;
$tbparameter["--env"]="prod";
$tbparameter["--time-limit"]=5;
if($appMailmethod=="sendmail") $tbparameter["--transport"]="app.sendmail.transport";
$parameter = new ArrayInput($tbparameter);
try{
$returnCode = $command->run($parameter, $output);
}
catch(\Exception $e) {
$this->writeln("");
$this->writelnred("Impossible d'envoyer des mails");
$this->writeln("");
return 0;
}
$this->writeln("");
return 1;
}
private function writelnred($string) {
$this->output->writeln('<fg=red>'.$string.'</>');
$this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n");
}
private function writeln($string) {
$this->output->writeln($string);
$this->filesystem->appendToFile($this->rootlog.'cron.log', $string."\n");
}
}

View File

@@ -136,15 +136,8 @@ class BreakdayController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -77,6 +77,7 @@ class CropController extends AbstractController
// Cacul de la largeur // Cacul de la largeur
protected function getWidth($image) { protected function getWidth($image) {
dump($image);
$size = getimagesize($image); $size = getimagesize($image);
$width = $size[0]; $width = $size[0];
return $width; return $width;

View File

@@ -146,15 +146,8 @@ class CustomerController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -17,11 +17,6 @@ class EventController extends AbstractController
private $route = "app_event"; private $route = "app_event";
private $render = "Event/"; private $render = "Event/";
private $entity = "App:Event"; private $entity = "App:Event";
private $notificator;
public function __construct(\App\Service\notificationService $notificator) {
$this->notificator = $notificator;
}
public function list(Request $request) public function list(Request $request)
{ {
@@ -45,26 +40,12 @@ class EventController extends AbstractController
// Evenements // Evenements
$iduser=$this->get("session")->get("iduser"); $iduser=$this->get("session")->get("iduser");
$user=$em->getRepository("App:User")->find($iduser);
if($iduser=="all") if($iduser=="all")
$events=$em->getRepository("App:Event")->findAll(); $events=$em->getRepository("App:Event")->findAll();
else { else {
$users= []; $iduser=$this->get("session")->get("iduser");
$fictivuser = $em->getRepository("App:User")->findOneBy([ $user=$em->getRepository("App:User")->find($iduser);
'service' => $user->getService(), $events=$em->getRepository("App:Event")->findBy(["user"=>$user]);
'fictive' => true,
]);
array_push($users,$fictivuser);
$selectedusers = $this->get("session")->get("selectedusers");
if (isset($selectedusers) && sizeof($selectedusers)>1){
foreach($selectedusers as $user) {
array_push($users,$em->getRepository("App:User")->find($user));
}
$events=$em->getRepository("App:Event")->findBy(["user"=>$users]);
}else{
array_push($users,$em->getRepository("App:User")->find($iduser));
$events=$em->getRepository("App:Event")->findBy(["user"=>$users]);
}
} }
foreach($events as $event) { foreach($events as $event) {
@@ -113,7 +94,6 @@ class EventController extends AbstractController
$am = ($request->request->get('am')=="true"); $am = ($request->request->get('am')=="true");
$ap = ($request->request->get('ap')=="true"); $ap = ($request->request->get('ap')=="true");
$astreinte = ($request->request->get('astreinte')=="true"); $astreinte = ($request->request->get('astreinte')=="true");
$externaltrip = ($request->request->get('externaltrip')=="true");
$description = $request->request->get('description'); $description = $request->request->get('description');
$user = $em->getRepository("App:User")->find($iduser); $user = $em->getRepository("App:User")->find($iduser);
@@ -257,7 +237,6 @@ class EventController extends AbstractController
$event->setEnd($dateend); $event->setEnd($dateend);
$event->setDuration($duration); $event->setDuration($duration);
$event->setAllday($allday); $event->setAllday($allday);
$event->setExternalTrip($externaltrip);
$event->setDescription($description); $event->setDescription($description);
$event->setUser($user); $event->setUser($user);
$event->setTask($task); $event->setTask($task);
@@ -266,12 +245,6 @@ class EventController extends AbstractController
$em->persist($event); $em->persist($event);
$em->flush(); $em->flush();
if($task->getNature()->getIsvacation()){
$idevent=$event->getId();
$valid_url = $this->generateUrl('app_validationholiday');
$this->notificator->sendNotifAttenteValid("Congés en attente de validation", $iduser, $idevent, $valid_url);
}
$output=$this->formatEvent($event); $output=$this->formatEvent($event);
} }
@@ -287,10 +260,7 @@ class EventController extends AbstractController
$idevent = str_replace("A","",$request->request->get('idevent')); $idevent = str_replace("A","",$request->request->get('idevent'));
$iduser = $request->request->get('iduser'); $iduser = $request->request->get('iduser');
$idtask = $request->request->get('idtask'); $idtask = $request->request->get('idtask');
$am = ($request->request->get('am')=="true");
$ap = ($request->request->get('ap')=="true");
$fgastreinte = ($request->request->get('fgastreinte')=="true"); $fgastreinte = ($request->request->get('fgastreinte')=="true");
$externaltrip = ($request->request->get('externaltrip')=="true");
$description = $request->request->get('description'); $description = $request->request->get('description');
$user = $em->getRepository("App:User")->find($iduser); $user = $em->getRepository("App:User")->find($iduser);
@@ -346,82 +316,17 @@ class EventController extends AbstractController
return new Response(json_encode($output)); return new Response(json_encode($output));
} }
$datestart=$event->getStart();
$dateend =$event->getEnd();
$duration=$dateend->diff($datestart)->d;
if($am&&$ap) {
if ($duration >= 1) {
$dateend->SetTime(0,0,-1);
}
$datestart->SetTime(0,0,0);
$dateend->add(new \DateInterval('P1D'));
$dateend->SetTime(0,0,0);
$duration=$dateend->diff($datestart)->d;
$allday=true;
}
else {
$duration=$dateend->diff($datestart)->d;
if ($duration == 1) {
$dateend->SetTime(0,0,-1);
}
$duration=0.5;
$allday=false;
if($am) {
$datestart->SetTime(9,0,0);
$dateend->SetTime(12,0,0);
}
else {
$datestart->SetTime(13,0,0);
$dateend->SetTime(17,0,0);
}
}
// On regarde si une tache ne commence pas pendant une autre intervention ou qui se termine pendant une autre intervention ou qui a une intervention compris dans ses dates
$events = $em->createQueryBuilder('event')
->select('event')
->from('App:Event','event')
->Where('event.user=:user AND event.start<=:start AND event.end >:start')
->orWhere('event.user=:user AND event.start<:end AND event.end >=:end')
->orWhere('event.user=:user AND event.start>:start AND event.end <:end')
->setParameter('user',$iduser)
->setParameter('start',$datestart)
->setParameter('end',$dateend)
->getQuery()->getResult();
if($events) {
$tbevent=[];
foreach($events as $ev) {
if ($event->getId() != $ev->getId()) {
$tmp=[
"id" => $ev->getId(),
"task" => $ev->getTask()->getName(),
"start" => $ev->getStart(),
"end" => $ev->getEnd(),
];
array_push($tbevent,$tmp);
}
}
if (sizeof($tbevent)>0) {
$output=["return"=>"KO","error"=>"Cet intervant a déjà une tache à cette date","start"=>$datestart,"end"=>$dateend,"events"=>$tbevent];
return new Response(json_encode($output));
}
}
// Modification de l'évenement // Modification de l'évenement
$event->setStart($datestart);
$event->setEnd($dateend);
$event->setDescription($description); $event->setDescription($description);
$event->setDuration($duration);
$event->setAllday($allday);
$event->setExternalTrip($externaltrip);
$event->setUser($user); $event->setUser($user);
$event->setTask($task); $event->setTask($task);
$em->persist($event); $em->persist($event);
$em->flush(); $em->flush();
$output=$this->formatEvent($event); $output=$this->formatEvent($event);
} }
return new Response(json_encode($output)); return new Response(json_encode($output));
} }
@@ -495,16 +400,12 @@ class EventController extends AbstractController
"borderColor" => $event->getTask()->getColor(), "borderColor" => $event->getTask()->getColor(),
"textColor" => "#ffffff", "textColor" => "#ffffff",
"allDay" => $event->getAllday(), "allDay" => $event->getAllday(),
"holiday" => $event->getTask()->getNature()->getIsvacation(),
"externaltrip" => ($event instanceof Penalty?false:$event->getExternalTrip()),
"editable" => $editable, "editable" => $editable,
"fictivuser" => $event->getUser()->getFictive(),
"durationEditable" => false, "durationEditable" => false,
"extendedProps" => [ "extendedProps" => [
"fulldescription" => ($event instanceof Penalty?"ASTREINTE\n":"").strtoupper($event->getTask()->getDisplayname())."\n\n".$event->getDescription(), "fulldescription" => ($event instanceof Penalty?"ASTREINTE\n":"").strtoupper($event->getTask()->getDisplayname())."\n\n".$event->getDescription(),
"description" => $event->getDescription(), "description" => $event->getDescription(),
"userid" => $event->getUser()->getId(), "userid" => $event->getUser()->getId(),
"username" => $event->getUser()->getUsername(),
"taskid" => $event->getTask()->getId(), "taskid" => $event->getTask()->getId(),
"avatar" => "/".$this->getParameter("appAlias")."/uploads/avatar/".$event->getUser()->getAvatar(), "avatar" => "/".$this->getParameter("appAlias")."/uploads/avatar/".$event->getUser()->getAvatar(),
"estimate" => $event->getTask()->getDuration($event->getEnd())." / ".$event->getTask()->getQuantity(), "estimate" => $event->getTask()->getDuration($event->getEnd())." / ".$event->getTask()->getQuantity(),
@@ -528,15 +429,12 @@ class EventController extends AbstractController
"borderColor" => "#cdcdcd", "borderColor" => "#cdcdcd",
"textColor" => "#ffffff", "textColor" => "#ffffff",
"allDay" => true, "allDay" => true,
"externaltrip" => false,
"holiday" => false,
"editable" => false, "editable" => false,
"durationEditable" => false, "durationEditable" => false,
"extendedProps" => [ "extendedProps" => [
"fulldescription" => "Jour Férié", "fulldescription" => "Jour Férié",
"description" => "Jour Férié", "description" => "Jour Férié",
"userid" => null, "userid" => null,
"username" => "",
"taskid" => null, "taskid" => null,
"avatar" => "/".$this->getParameter("appAlias")."/uploads/avatar/".$this->getUser()->getAvatar(), "avatar" => "/".$this->getParameter("appAlias")."/uploads/avatar/".$this->getUser()->getAvatar(),
"estimate" => "", "estimate" => "",

View File

@@ -1,435 +0,0 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManagerInterface;
class ExportController extends AbstractController
{
private $data = "export";
private $route = "app_exportèview";
private $render = "Export/";
private $entity = "App:Export";
public function view(Request $request)
{
$em = $this->getDoctrine()->getManager();
$iduser = $this->get("session")->get("iduser");
$user = $em->getRepository("App:User")->find($iduser);
return $this->render($this->render.'list.html.twig',[
"useheader" => true,
"usesidebar" => true,
"user" => $user,
]);
}
public function export_full_worked_days(Request $request,$access=null): Response
{
$em = $this->getDoctrine()->getManager();
$nbmonth=$this->get("session")->get("nbmonth");
$iduser=$this->get("session")->get("iduser");
if($iduser=="all") {
$users=$em->getRepository("App:User")->findAll();
}
else {
$users=$em->getRepository("App:User")->findBy(["id"=>$iduser]);
}
$tbevents=[];
foreach($users as $user) {
if(in_array("ROLE_USER",$user->getRoles())) {
// Filtre par Service
if($this->get('session')->get('idservice')!="all") {
if($user->getService()->getId()!=$this->get('session')->get('idservice'))
continue;
}
$tmp=[
"id" => $user->getId(),
"user" => $user,
"events" => [],
];
// On formate le tableau de jour
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->modify('previous monday');
$start->setTime(0,0,0);
$end = new \Datetime('first day of this month');
$end->add(new \DateInterval('P1M'));
$end->modify('next monday');
$end->setTime(23,59,0);
while($start<$end) {
$idday=$start->format("Ymd");
$idmonth=$start->format("Ym");
$tmp["events"][$idday] = [
"date"=>clone $start,
"allday"=>false,
"descriptionday"=>"",
"am"=>false,
"descriptionam"=>"",
"ap"=>false,
"descriptionap"=>"",
"astreinte"=>false,
"descriptionastreinte"=>"",
];
$start->add(new \DateInterval('P1D'));
}
// On formate le tableau des event
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->modify('previous monday');
$start->setTime(0,0,0);
$end = new \Datetime('first day of this month');
$end->add(new \DateInterval('P1M'));
$end->modify('next monday');
$end->setTime(23,59,0);
$events = $em
->createQueryBuilder('event')
->select('event')
->from('App:Event','event')
->Where('event.user=:user AND event.start>=:start AND event.end <:end')
->setParameter('user',$user->getId())
->setParameter('start',$start)
->setParameter('end',$end)
->getQuery()->getResult();
foreach($events as $event) {
$idproject=$event->getTask()->getProject()->getId();
// Filtre par project
if($this->get('session')->get('idproject')!="all") {
if($idproject!=$this->get('session')->get('idproject'))
continue;
}
$isvac= $event->getTask()->getNature()->getIsvacation();
if($isvac) {continue;}
$st=clone $event->getStart();
while($st<$event->getEnd()) {
$idday=$st->format("Ymd");
if($event->getAllday()) {
$tmp["events"][$idday]["allday"]=true;
$tmp["events"][$idday]["descriptionday"]=strtoupper($event->getTask()->getDisplayname());
}
else {
// Matin ou après-midi ?
$time=$event->getStart()->format("H");
if($time==9) {
$tmp["events"][$idday]["am"]=true;
if(isset($tmp["events"][$idday]["ap"]) && $tmp["events"][$idday]["ap"]==true){$tmp["events"][$idday]["allday"]=true;}
$tmp["events"][$idday]["descriptionam"]=strtoupper($event->getTask()->getDisplayname());
}
else {
$tmp["events"][$idday]["ap"]=true;
if(isset($tmp["events"][$idday]["am"]) && $tmp["events"][$idday]["am"] ==true){$tmp["events"][$idday]["allday"]=true;}
$tmp["events"][$idday]["descriptionap"]=strtoupper($event->getTask()->getDisplayname());
}
}
$st->add(new \DateInterval('P1D'));
}
}
// On formate le tableau des astreintes
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->modify('previous monday');
$start->setTime(0,0,0);
$end = new \Datetime('first day of this month');
$end->add(new \DateInterval('P1M'));
$end->modify('next monday');
$end->setTime(23,59,0);
$penaltys = $em
->createQueryBuilder('penalty')
->select('penalty')
->from('App:Penalty','penalty')
->Where('penalty.user=:user AND penalty.start>=:start AND penalty.end <:end')
->setParameter('user',$user->getId())
->setParameter('start',$start)
->setParameter('end',$end)
->getQuery()->getResult();
foreach($penaltys as $penalty) {
$idproject=$penalty->getTask()->getProject()->getId();
// Filtre par project
if($this->get('session')->get('idproject')!="all") {
if($idproject!=$this->get('session')->get('idproject'))
continue;
}
$st=clone $penalty->getStart();
while($st<$penalty->getEnd()) {
$idday=$st->format("Ymd");
if($penalty->getAllday()) {
$tmp["events"][$idday]["astreinte"]=true;
$tmp["events"][$idday]["descriptionastreinte"]=strtoupper($penalty->getTask()->getDisplayname());
}
$st->add(new \DateInterval('P1D'));
}
}
array_push($tbevents,$tmp);
}
}
$csv = $this->renderView('Export/export_full_worked_days.csv.twig', ["users" => $tbevents]);
$response = new Response($csv);
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="export_full_worked_days.csv"');
return $response;
}
public function export_penalty_additional(Request $request,$access=null): Response
{
$em = $this->getDoctrine()->getManager();
$iduser = $this->get("session")->get("iduser");
$timers = $em->getRepository("App:Timer")->findBy(["user"=>$iduser]);
$tbtimers = [];
foreach ($timers as $timer) {
$isactive = $timer->getActivePenalty();
$isadditional = $timer->getAdditionalHour();
if ($isactive || $isadditional) {
$tbtimer["id"] = $timer->getId();
$tbtimer["taskname"] = $timer->getTask()->getDisplayname();
$tbtimer["user"] = $timer->getUser()->getUsername();
$tbtimer["start"] = $timer->getStart()->format("Y-m-d H:i");
$tbtimer["end"] = $timer->getEnd()->format("Y-m-d H:i");
$tbtimer["duration"] = $timer->getDuration();
$tbtimer["activepenalty"] = $timer->getActivePenalty();
$tbtimer["additionalhour"] = $timer->getAdditionalHour();
$tbtimer["description"] = $timer->getDescription();
array_push($tbtimers, $tbtimer);
}
}
$csv = $this->renderView('Export/export_penalty_additional.csv.twig', ["timers" => $tbtimers]);
$response = new Response($csv);
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="export_penalty_additional.csv"');
return $response;
}
public function export_project_weekly(Request $request,$access=null): Response {
$nbmonth=$this->get("session")->get("nbmonth");
$em = $this->getDoctrine()->getManager();
$projects=$em->getRepository("App:Project")->findAll();
//Construction du tableau des projets
$tbprojects=[];
foreach($projects as $project) {
// Filtre par Customer
if($access=="customer") {
if($project->getCustomer()->getKeypass()!=$key)
continue;
}
// Filtre par Service
if($this->get('session')->get('idservice')!="all") {
if($project->getService()->getId()!=$this->get('session')->get('idservice'))
continue;
}
// Filtre par project
if($this->get('session')->get('idproject')!="all") {
if($project->getId()!=$this->get('session')->get('idproject'))
continue;
}
// Ne prendre que les projets actif/inactif
if($this->get('session')->get('activeproject')!=$project->getActive())
continue;
$tbproject= [];
$tbproject["projectname"] = $project->getDisplayname();
$tbproject["name"] = $project->getname();
$tbproject["customer"] = $project->getCustomer()->getName();
// Somme event validé par semaine
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->modify('previous monday');
$start->setTime(0,0,0);
$endmonth = new \Datetime('first day of this month');
$endmonth->add(new \DateInterval('P1M'));
$endmonth->modify('next monday');
$endmonth->setTime(23,59,0);
$eventsbyweek = $em
->createQueryBuilder('event')
->select('event')
->from('App:Task','task')
->from('App:Event','event')
->Where('task.project=:project')
->andWhere('event.task=task')
->andWhere('event.end >=:start')
->andWhere('event.end <:end')
->andWhere('event.validate=:validate')
->setParameter('project',$project)
->setParameter('validate',true)
->setParameter('start',$start)
->setParameter('end',$endmonth)
->orderBy('event.start')
->getQuery()->getResult();
// foreach($eventsbyweek as $event) {
// if(!isset($tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")])){
// $tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")] = [
// "weeknumber" => $event->getStart()->format("W"),
// "cumul" => 0,
// ];
// }
// $tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["cumul"] = $tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["cumul"]+$event->getDuration();
// }
// foreach($eventsbyweek as $event) {
// if(!isset($tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"])){
// $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")] = [
// "weeknumber" => $event->getStart()->format("W"),
// "users" => [],
// ];
// }
// if(!isset($tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()])){
// $tbuser= [
// "id"=>$event->getUser()->getId(),
// "displayname"=>$event->getUser()->getDisplayname(),
// "cumul"=>0
// ];
// $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()] = $tbuser;
// }
// $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()]["cumul"] = $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()]["cumul"]+$event->getDuration();
// }
foreach($eventsbyweek as $event) {
if(!isset($tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"])){
$tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")] = [
"weeknumber" => $event->getStart()->format("W"),
"tasks" => [],
];
}
if(!isset($tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()])){
$tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()] = [
"taskname" => $event->getTask()->getName(),
"users" => [],
];
}
if(!isset($tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()])){
$tbuser= [
"id"=>$event->getUser()->getId(),
"displayname"=>$event->getUser()->getDisplayname(),
"cumul"=>0
];
$tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()] = $tbuser;
}
$tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()]["cumul"] = $tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()]["cumul"]+$event->getDuration();
}
// Somme astreintes validé par semaine
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->modify('previous monday');
$start->setTime(0,0,0);
$endmonth = new \Datetime('first day of this month');
$endmonth->add(new \DateInterval('P1M'));
$endmonth->modify('next monday');
$endmonth->setTime(23,59,0);
$penaltybyweek = $em
->createQueryBuilder('penalty')
->select('penalty')
->from('App:Task','task')
->from('App:Penalty','penalty')
->Where('task.project=:project')
->andWhere('penalty.task=task')
->andWhere('penalty.end >=:start')
->andWhere('penalty.end <:end')
->andWhere('penalty.validate=:validate')
->setParameter('project',$project)
->setParameter('validate',true)
->setParameter('start',$start)
->setParameter('end',$endmonth)
->orderBy('penalty.start')
->getQuery()->getResult();
// foreach($penaltybyweek as $penalty) {
// if(!isset($tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")])){
// $tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")] = [
// "weeknumber" => $penalty->getStart()->format("W"),
// "cumul" => 0,
// ];
// }
// $tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["cumul"] = $tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["cumul"]+$penalty->getDuration();
// }
// foreach($penaltybyweek as $penalty) {
// if(!isset($tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"])){
// $tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")] = [
// "weeknumber" => $penalty->getStart()->format("W"),
// "users" => [],
// ];
// }
// if(!isset($tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()])){
// $tbuser= [
// "id"=>$penalty->getUser()->getId(),
// "displayname"=>$penalty->getUser()->getDisplayname(),
// "cumul"=>0
// ];
// $tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()] = $tbuser;
// }
// $tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()]["cumul"] = $tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()]["cumul"]+$penalty->getDuration();
// }
foreach($penaltybyweek as $penalty) {
if(!isset($tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["tasks"])){
$tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")] = [
"weeknumber" => $penalty->getStart()->format("W"),
"tasks" => [],
];
}
if(!isset($tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["tasks"][$penalty->getTask()->getId()])){
$tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["tasks"][$penalty->getTask()->getId()] = [
"taskname" => $penalty->getTask()->getName(),
"users" => [],
];
}
if(!isset($tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["tasks"][$penalty->getTask()->getId()]["users"][$penalty->getUser()->getId()])){
$tbuser= [
"id"=>$penalty->getUser()->getId(),
"displayname"=>$penalty->getUser()->getDisplayname(),
"cumul"=>0
];
$tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["tasks"][$penalty->getTask()->getId()]["users"][$penalty->getUser()->getId()] = $tbuser;
}
$tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["tasks"][$penalty->getTask()->getId()]["users"][$penalty->getUser()->getId()]["cumul"] = $tbproject["weeks_by_task_by_user"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["tasks"][$penalty->getTask()->getId()]["users"][$penalty->getUser()->getId()]["cumul"]+$penalty->getDuration();
}
$tbprojects[$project->getId()]=$tbproject;
}
$csv = $this->renderView('Export/export_project_weekly.csv.twig', ["projects" => $tbprojects]);
$response = new Response($csv);
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="export_project_weekly.csv"');
return $response;
}
}

View File

@@ -36,9 +36,7 @@ class HomeController extends AbstractController
public function selectuser(Request $request) public function selectuser(Request $request)
{ {
$iduser = $request->request->get('iduser'); $iduser = $request->request->get('iduser');
$selectedusers = $request->request->get('selectedusers');
$this->get('session')->set('iduser',$iduser); $this->get('session')->set('iduser',$iduser);
$this->get('session')->set('selectedusers',$selectedusers);
$output=["return"=>"OK"]; $output=["return"=>"OK"];
return new Response(json_encode($output)); return new Response(json_encode($output));
} }

View File

@@ -146,15 +146,8 @@ class JobController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -129,15 +129,8 @@ class NatureController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -146,15 +146,8 @@ class OfferController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -150,16 +150,8 @@ class ProjectController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
$this->refreshsession(); $this->refreshsession();
// Retour à la liste // Retour à la liste

View File

@@ -6,7 +6,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse; use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
class ReportController extends AbstractController class ReportController extends AbstractController
{ {
@@ -16,6 +15,7 @@ class ReportController extends AbstractController
public function synthese(Request $request) public function synthese(Request $request)
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$nbmonth=$this->get("session")->get("nbmonth"); $nbmonth=$this->get("session")->get("nbmonth");
$iduser=$this->get("session")->get("iduser"); $iduser=$this->get("session")->get("iduser");
@@ -102,7 +102,7 @@ class ReportController extends AbstractController
$tmp["events"][$idday]["allday"]=true; $tmp["events"][$idday]["allday"]=true;
$tmp["events"][$idday]["colorday"]=$event->getTask()->getColor(); $tmp["events"][$idday]["colorday"]=$event->getTask()->getColor();
$tmp["events"][$idday]["descriptionday"]=strtoupper($event->getTask()->getDisplayname())."\n\n".$event->getDescription(); $tmp["events"][$idday]["descriptionday"]=strtoupper($event->getTask()->getDisplayname())."\n\n".$event->getDescription();
} }
else { else {
// Matin ou après-midi ? // Matin ou après-midi ?
$time=$event->getStart()->format("H"); $time=$event->getStart()->format("H");
@@ -119,9 +119,8 @@ class ReportController extends AbstractController
} }
$st->add(new \DateInterval('P1D')); $st->add(new \DateInterval('P1D'));
} }
} }
// On formate le tableau des astreintes // On formate le tableau des astreintes
$start=new \Datetime('first day of this month'); $start=new \Datetime('first day of this month');
@@ -158,7 +157,7 @@ class ReportController extends AbstractController
} }
$st->add(new \DateInterval('P1D')); $st->add(new \DateInterval('P1D'));
} }
} }
// On formate le tableau des jours fériés // On formate le tableau des jours fériés
@@ -185,7 +184,7 @@ class ReportController extends AbstractController
$tmp["events"][$idday]["descriptionday"]="Jour Férié"; $tmp["events"][$idday]["descriptionday"]="Jour Férié";
$st->add(new \DateInterval('P1D')); $st->add(new \DateInterval('P1D'));
} }
} }
array_push($tbevents,$tmp); array_push($tbevents,$tmp);
@@ -203,10 +202,9 @@ class ReportController extends AbstractController
return new PdfResponse( return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render), $this->knpSnappy->getOutputFromHtml($render),
'synthese.pdf' 'synthese.pdf'
); );
} }
else { else {
return $this->render('Report/synthese.html.twig',[ return $this->render('Report/synthese.html.twig',[
"useheader" => true, "useheader" => true,
"usesidebar" => ($this->getUser()), "usesidebar" => ($this->getUser()),
@@ -248,7 +246,7 @@ class ReportController extends AbstractController
if($project->getId()!=$this->get('session')->get('idproject')) if($project->getId()!=$this->get('session')->get('idproject'))
continue; continue;
} }
// Ne prendre que les projets actif/inactif // Ne prendre que les projets actif/inactif
if($this->get('session')->get('activeproject')!=$project->getActive()) if($this->get('session')->get('activeproject')!=$project->getActive())
continue; continue;
@@ -352,7 +350,7 @@ class ReportController extends AbstractController
$end=new \Datetime('first day of this month'); $end=new \Datetime('first day of this month');
$end->add(new \DateInterval('P'.$nbmonth.'M')); $end->add(new \DateInterval('P'.$nbmonth.'M'));
$end->sub(new \DateInterval('P1D')); $end->sub(new \DateInterval('P1D'));
foreach($users as $user) { foreach($users as $user) {
$tbevents = $this->getEventuser($user,$start,$end,false); $tbevents = $this->getEventuser($user,$start,$end,false);
@@ -370,7 +368,7 @@ class ReportController extends AbstractController
} }
} }
} }
// Cumule // Cumule
foreach($tbprojects as $project) { foreach($tbprojects as $project) {
foreach($project["months"] as $month) { foreach($project["months"] as $month) {
@@ -389,7 +387,7 @@ class ReportController extends AbstractController
$totmonth+=$day["duration"]; $totmonth+=$day["duration"];
$totmontha+=$day["astreinte"]; $totmontha+=$day["astreinte"];
} }
if($totuser==0&&$totusera==0) { if($totuser==0&&$totusera==0) {
unset($tbprojects[$project["id"]]["months"][$month["monthid"]]["users"][$user["id"]]); unset($tbprojects[$project["id"]]["months"][$month["monthid"]]["users"][$user["id"]]);
} else { } else {
@@ -400,7 +398,7 @@ class ReportController extends AbstractController
if(!$haveuser) if(!$haveuser)
unset($tbprojects[$project["id"]]["months"][$month["monthid"]]); unset($tbprojects[$project["id"]]["months"][$month["monthid"]]);
else { else {
$tbprojects[$project["id"]]["months"][$month["monthid"]]["total"]=$totmonth; $tbprojects[$project["id"]]["months"][$month["monthid"]]["total"]=$totmonth;
$tbprojects[$project["id"]]["months"][$month["monthid"]]["totala"]=$totmontha; $tbprojects[$project["id"]]["months"][$month["monthid"]]["totala"]=$totmontha;
} }
@@ -420,9 +418,9 @@ class ReportController extends AbstractController
return new PdfResponse( return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render,["orientation"=>"Landscape"]), $this->knpSnappy->getOutputFromHtml($render,["orientation"=>"Landscape"]),
'planning.pdf' 'planning.pdf'
); );
} }
else { else {
return $this->render('Report/planning.html.twig',[ return $this->render('Report/planning.html.twig',[
"useheader" => true, "useheader" => true,
"usesidebar" => ($this->getUser()), "usesidebar" => ($this->getUser()),
@@ -430,7 +428,7 @@ class ReportController extends AbstractController
"access" => $access, "access" => $access,
"key" => $key "key" => $key
]); ]);
} }
} }
public function report($key=null,$access=null,Request $request) { public function report($key=null,$access=null,Request $request) {
@@ -449,7 +447,7 @@ class ReportController extends AbstractController
} }
$projects=$em->getRepository("App:Project")->findAll(); $projects=$em->getRepository("App:Project")->findAll();
//Construction du tableau des projets //Construction du tableau des projets
$tbprojects=[]; $tbprojects=[];
foreach($projects as $project) { foreach($projects as $project) {
@@ -470,7 +468,7 @@ class ReportController extends AbstractController
if($project->getId()!=$this->get('session')->get('idproject')) if($project->getId()!=$this->get('session')->get('idproject'))
continue; continue;
} }
// Ne prendre que les projets actif/inactif // Ne prendre que les projets actif/inactif
if($this->get('session')->get('activeproject')!=$project->getActive()) if($this->get('session')->get('activeproject')!=$project->getActive())
continue; continue;
@@ -515,13 +513,11 @@ class ReportController extends AbstractController
"beforeastreinte"=>[], "beforeastreinte"=>[],
"months"=>[], "months"=>[],
"offers"=>[], "offers"=>[],
"weeks"=>[],
]; ];
// Somme event validé avant la date // Somme event validé avant la date
$end=new \Datetime('first day of this month'); $end=new \Datetime('first day of this month');
$end->sub(new \DateInterval('P'.$nbmonth.'M')); $end->sub(new \DateInterval('P'.$nbmonth.'M'));
$end->setTime(23,59,0);
$events = $em $events = $em
->createQueryBuilder('event') ->createQueryBuilder('event')
->select('event') ->select('event')
@@ -537,20 +533,19 @@ class ReportController extends AbstractController
->orderBy('event.start') ->orderBy('event.start')
->getQuery()->getResult(); ->getQuery()->getResult();
foreach($events as $event) { foreach($events as $event) {
if(!isset($tbproject["before"][$event->getStart()->format("Y")][$event->getStart()->format("Ym")])) { if(!isset($tbproject["before"][$event->getStart()->format("Ym")])) {
$tbproject["before"][$event->getStart()->format("Y")][$event->getStart()->format("Ym")] = [ $tbproject["before"][$event->getStart()->format("Ym")] = [
"idmonth" => $event->getStart()->format("Ym"), "idmonth" => $event->getStart()->format("Ym"),
"monthlabel"=>$event->getStart()->format("m/Y"), "monthlabel"=>$event->getStart()->format("m/Y"),
"duration" => 0, "duration" => 0,
]; ];
} }
$tbproject["before"][$event->getStart()->format("Y")][$event->getStart()->format("Ym")]["duration"]=$tbproject["before"][$event->getStart()->format("Y")][$event->getStart()->format("Ym")]["duration"]+$event->getDuration(); $tbproject["before"][$event->getStart()->format("Ym")]["duration"]=$tbproject["before"][$event->getStart()->format("Ym")]["duration"]+$event->getDuration();
} }
// Somme astreinte validé avant la date // Somme astreinte validé avant la date
$end=new \Datetime('first day of this month'); $end=new \Datetime('first day of this month');
$end->sub(new \DateInterval('P'.$nbmonth.'M')); $end->sub(new \DateInterval('P'.$nbmonth.'M'));
$end->setTime(23,59,0);
$penaltys = $em $penaltys = $em
->createQueryBuilder('penalty') ->createQueryBuilder('penalty')
->select('penalty') ->select('penalty')
@@ -566,150 +561,17 @@ class ReportController extends AbstractController
->orderBy('penalty.start') ->orderBy('penalty.start')
->getQuery()->getResult(); ->getQuery()->getResult();
foreach($penaltys as $penalty) { foreach($penaltys as $penalty) {
if(!isset($tbproject["beforeastreinte"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("Ym")])) { if(!isset($tbproject["beforeastreinte"][$penalty->getStart()->format("Ym")])) {
$tbproject["beforeastreinte"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("Ym")] = [ $tbproject["beforeastreinte"][$penalty->getStart()->format("Ym")] = [
"idmonth" => $penalty->getStart()->format("Ym"), "idmonth" => $penalty->getStart()->format("Ym"),
"monthlabel"=>$penalty->getStart()->format("m/Y"), "monthlabel"=>$penalty->getStart()->format("m/Y"),
"duration" => 0, "duration" => 0,
]; ];
} }
$tbproject["beforeastreinte"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("Ym")]["duration"]=$tbproject["beforeastreinte"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("Ym")]["duration"]+$penalty->getDuration(); $tbproject["beforeastreinte"][$penalty->getStart()->format("Ym")]["duration"]=$tbproject["beforeastreinte"][$penalty->getStart()->format("Ym")]["duration"]+$penalty->getDuration();
} }
// Somme event validé par semaine
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->modify('previous monday');
$start->setTime(0,0,0);
$endmonth = new \Datetime('first day of this month');
$endmonth->add(new \DateInterval('P1M'));
$endmonth->modify('next monday');
$end->setTime(23,59,0);
$eventsbyweek = $em
->createQueryBuilder('event')
->select('event')
->from('App:Task','task')
->from('App:Event','event')
->Where('task.project=:project')
->andWhere('event.task=task')
->andWhere('event.end >=:start')
->andWhere('event.end <:end')
->andWhere('event.validate=:validate')
->setParameter('project',$project)
->setParameter('validate',true)
->setParameter('start',$start)
->setParameter('end',$endmonth)
->orderBy('event.start')
->getQuery()->getResult();
foreach($eventsbyweek as $event) {
if(!isset($tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")])){
$tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")] = [
"weeknumber" => $event->getStart()->format("W"),
"cumul" => 0,
];
}
$tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["cumul"] = $tbproject["weeks"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["cumul"]+$event->getDuration();
}
// foreach($eventsbyweek as $event) {
// if(!isset($tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"])){
// $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")] = [
// "weeknumber" => $event->getStart()->format("W"),
// "users" => [],
// ];
// }
// if(!isset($tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()])){
// $tbuser= [
// "id"=>$event->getUser()->getId(),
// "displayname"=>$event->getUser()->getDisplayname(),
// "cumul"=>0
// ];
// $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()] = $tbuser;
// }
// $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()]["cumul"] = $tbproject["weeks_by_name"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["users"][$event->getUser()->getId()]["cumul"]+$event->getDuration(); // Recap des propositions
// }
// foreach($eventsbyweek as $event) {
// if(!isset($tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"])){
// $tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")] = [
// "weeknumber" => $event->getStart()->format("W"),
// "tasks" => [],
// ];
// }
// if(!isset($tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()])){
// $tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()] = [
// "taskname" => $event->getTask()->getName(),
// "users" => [],
// ];
// }
// if(!isset($tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()])){
// $tbuser= [
// "id"=>$event->getUser()->getId(),
// "displayname"=>$event->getUser()->getDisplayname(),
// "cumul"=>0
// ];
// $tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()] = $tbuser;
// }
// $tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()]["cumul"] = $tbproject["weeks_by_task_by_user"][$event->getStart()->format("Y")][$event->getStart()->format("W")]["tasks"][$event->getTask()->getId()]["users"][$event->getUser()->getId()]["cumul"]+$event->getDuration();
// }
// Somme astreintes validé par semaine
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->modify('previous monday');
$start->setTime(0,0,0);
$endmonth = new \Datetime('first day of this month');
$endmonth->add(new \DateInterval('P1M'));
$endmonth->modify('next monday');
$end->setTime(23,59,0);
$penaltybyweek = $em
->createQueryBuilder('penalty')
->select('penalty')
->from('App:Task','task')
->from('App:Penalty','penalty')
->Where('task.project=:project')
->andWhere('penalty.task=task')
->andWhere('penalty.end >=:start')
->andWhere('penalty.end <:end')
->andWhere('penalty.validate=:validate')
->setParameter('project',$project)
->setParameter('validate',true)
->setParameter('start',$start)
->setParameter('end',$endmonth)
->orderBy('penalty.start')
->getQuery()->getResult();
foreach($penaltybyweek as $penalty) {
if(!isset($tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")])){
$tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")] = [
"weeknumber" => $penalty->getStart()->format("W"),
"cumul" => 0,
];
}
$tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["cumul"] = $tbproject["weeks"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["cumul"]+$penalty->getDuration();
}
foreach($penaltybyweek as $penaltybyweek) {
if(!isset($tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"])){
$tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")] = [
"weeknumber" => $penalty->getStart()->format("W"),
"users" => [],
];
}
if(!isset($tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()])){
$tbuser= [
"id"=>$penalty->getUser()->getId(),
"displayname"=>$penalty->getUser()->getDisplayname(),
"cumul"=>0
];
$tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()] = $tbuser;
}
$tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()]["cumul"] = $tbproject["weeks_by_name"][$penalty->getStart()->format("Y")][$penalty->getStart()->format("W")]["users"][$penalty->getUser()->getId()]["cumul"]+$penalty->getDuration();
}
// Recap des Commandes
$offers=$em->getRepository("App:Offer")->findBy(["project"=>$project->getId()]); $offers=$em->getRepository("App:Offer")->findBy(["project"=>$project->getId()]);
foreach($offers as $offer) { foreach($offers as $offer) {
$tbproject["offers"][$offer->getId()] = [ $tbproject["offers"][$offer->getId()] = [
@@ -717,16 +579,14 @@ class ReportController extends AbstractController
"ref"=>$offer->getRef(), "ref"=>$offer->getRef(),
"quantity"=>$offer->getQuantity(), "quantity"=>$offer->getQuantity(),
]; ];
} }
// Formater les mois // Formater les mois
$start=new \Datetime('first day of this month'); $start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M')); $start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->setTime(0,0,0);
$end=new \Datetime('first day of this month'); $end=new \Datetime('first day of this month');
$end->add(new \DateInterval('P'.$nbmonth.'M')); $end->add(new \DateInterval('P'.$nbmonth.'M'));
$end->sub(new \DateInterval('P1D')); $end->sub(new \DateInterval('P1D'));
$end->setTime(23,59,0);
while($start<$end) { while($start<$end) {
$tbproject["months"][$start->format("Ym")]=[ $tbproject["months"][$start->format("Ym")]=[
"monthid"=> $start->format("Ym"), "monthid"=> $start->format("Ym"),
@@ -774,7 +634,7 @@ class ReportController extends AbstractController
]; ];
$tbproject["months"][$start->format("Ym")]["tasks"][$event["id"]]=$tbtask; $tbproject["months"][$start->format("Ym")]["tasks"][$event["id"]]=$tbtask;
} }
$start->add(new \DateInterval('P1M')); $start->add(new \DateInterval('P1M'));
} }
@@ -810,15 +670,14 @@ class ReportController extends AbstractController
} }
$tbprojects[$project->getId()]=$tbproject; $tbprojects[$project->getId()]=$tbproject;
} }
// Formater les utilisateurs // Formater les utilisateurs
$start=new \Datetime('first day of this month'); $start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M')); $start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->setTime(0,0,0);
$end=new \Datetime('first day of this month'); $end=new \Datetime('first day of this month');
$end->add(new \DateInterval('P'.$nbmonth.'M')); $end->add(new \DateInterval('P'.$nbmonth.'M'));
$end->sub(new \DateInterval('P1D')); $end->sub(new \DateInterval('P1D'));
$end->setTime(23,59,0);
foreach($users as $user) { foreach($users as $user) {
$tbevents = $this->getEventuser($user,$start,$end,true); $tbevents = $this->getEventuser($user,$start,$end,true);
@@ -836,6 +695,7 @@ class ReportController extends AbstractController
} }
} }
} }
// Cumule // Cumule
foreach($tbprojects as $project) { foreach($tbprojects as $project) {
foreach($project["months"] as $month) { foreach($project["months"] as $month) {
@@ -854,7 +714,7 @@ class ReportController extends AbstractController
$totmonth+=$day["duration"]; $totmonth+=$day["duration"];
$totmontha+=$day["astreinte"]; $totmontha+=$day["astreinte"];
} }
if($totuser==0&&$totusera==0) { if($totuser==0&&$totusera==0) {
unset($tbprojects[$project["id"]]["months"][$month["monthid"]]["users"][$user["id"]]); unset($tbprojects[$project["id"]]["months"][$month["monthid"]]["users"][$user["id"]]);
} else { } else {
@@ -865,7 +725,7 @@ class ReportController extends AbstractController
if(!$haveuser) if(!$haveuser)
unset($tbprojects[$project["id"]]["months"][$month["monthid"]]); unset($tbprojects[$project["id"]]["months"][$month["monthid"]]);
else { else {
$tbprojects[$project["id"]]["months"][$month["monthid"]]["total"]=$totmonth; $tbprojects[$project["id"]]["months"][$month["monthid"]]["total"]=$totmonth;
$tbprojects[$project["id"]]["months"][$month["monthid"]]["totala"]=$totmontha; $tbprojects[$project["id"]]["months"][$month["monthid"]]["totala"]=$totmontha;
} }
@@ -885,9 +745,9 @@ class ReportController extends AbstractController
return new PdfResponse( return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render,["orientation"=>"Landscape"]), $this->knpSnappy->getOutputFromHtml($render,["orientation"=>"Landscape"]),
'report.pdf' 'report.pdf'
); );
} }
else { else {
return $this->render('Report/report.html.twig',[ return $this->render('Report/report.html.twig',[
"useheader" => true, "useheader" => true,
"usesidebar" => ($this->getUser()), "usesidebar" => ($this->getUser()),
@@ -895,12 +755,13 @@ class ReportController extends AbstractController
"access" => $access, "access" => $access,
"key" => $key "key" => $key
]); ]);
} }
} }
private function getEventuser($user,$start,$end,$onlyvalidate) { private function getEventuser($user,$start,$end,$onlyvalidate) {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$tbevents=[]; $tbevents=[];
// Récupération de event // Récupération de event
$qb = $em $qb = $em
->createQueryBuilder('event') ->createQueryBuilder('event')
@@ -912,7 +773,7 @@ class ReportController extends AbstractController
->setParameter('end',$end); ->setParameter('end',$end);
if($onlyvalidate) if($onlyvalidate)
$qb->andWhere('event.validate=:validate')->setParameter('validate',true); $qb->andWhere('event.validate=:validate')->setParameter('validate',true);
$events=$qb->getQuery()->getResult(); $events=$qb->getQuery()->getResult();
foreach($events as $event) { foreach($events as $event) {
$project=$event->getTask()->getProject(); $project=$event->getTask()->getProject();
@@ -931,14 +792,14 @@ class ReportController extends AbstractController
if($idproject!=$this->get('session')->get('idproject')) if($idproject!=$this->get('session')->get('idproject'))
continue; continue;
} }
// Ne prendre que les projets actif/inactif // Ne prendre que les projets actif/inactif
if($this->get('session')->get('activeproject')!=$activeproject) if($this->get('session')->get('activeproject')!=$activeproject)
continue; continue;
if(!isset($tbevents[$idproject])) if(!isset($tbevents[$idproject]))
$tbevents[$idproject] = []; $tbevents[$idproject] = [];
$st=clone $event->getStart(); $st=clone $event->getStart();
while($st<$event->getEnd()) { while($st<$event->getEnd()) {
$idday=$st->format("Ymd"); $idday=$st->format("Ymd");
@@ -959,7 +820,7 @@ class ReportController extends AbstractController
$st->add(new \DateInterval('P1D')); $st->add(new \DateInterval('P1D'));
} }
} }
@@ -974,7 +835,7 @@ class ReportController extends AbstractController
->setParameter('end',$end); ->setParameter('end',$end);
if($onlyvalidate) if($onlyvalidate)
$qb->andWhere('penalty.validate=:validate')->setParameter('validate',true); $qb->andWhere('penalty.validate=:validate')->setParameter('validate',true);
$penaltys=$qb->getQuery()->getResult(); $penaltys=$qb->getQuery()->getResult();
foreach($penaltys as $penalty) { foreach($penaltys as $penalty) {
$project=$penalty->getTask()->getProject(); $project=$penalty->getTask()->getProject();
@@ -993,14 +854,14 @@ class ReportController extends AbstractController
if($idproject!=$this->get('session')->get('idproject')) if($idproject!=$this->get('session')->get('idproject'))
continue; continue;
} }
// Ne prendre que les projets actif/inactif // Ne prendre que les projets actif/inactif
if($this->get('session')->get('activeproject')!=$activeproject) if($this->get('session')->get('activeproject')!=$activeproject)
continue; continue;
if(!isset($tbevents[$idproject])) if(!isset($tbevents[$idproject]))
$tbevents[$idproject] = []; $tbevents[$idproject] = [];
$st=clone $penalty->getStart(); $st=clone $penalty->getStart();
while($st<$penalty->getEnd()) { while($st<$penalty->getEnd()) {
$idday=$st->format("Ymd"); $idday=$st->format("Ymd");
@@ -1021,7 +882,7 @@ class ReportController extends AbstractController
$st->add(new \DateInterval('P1D')); $st->add(new \DateInterval('P1D'));
} }
} }
return $tbevents; return $tbevents;
@@ -1030,7 +891,7 @@ class ReportController extends AbstractController
public function holiday(Request $request) public function holiday(Request $request)
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$iduser=$this->getUser(); $iduser=$this->getUser();
$users=$em->getRepository("App:User")->findBy(["id"=>$iduser]); $users=$em->getRepository("App:User")->findBy(["id"=>$iduser]);
@@ -1079,13 +940,13 @@ class ReportController extends AbstractController
"useheader" => true, "useheader" => true,
"usesidebar" => ($this->getUser()), "usesidebar" => ($this->getUser()),
"users" => $tbevents, "users" => $tbevents,
"fgprint" => $request->query->get('fgprint'), "fgprint" => $request->query->get('fgprint'),
]); ]);
return new PdfResponse( return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render), $this->knpSnappy->getOutputFromHtml($render),
'conges.pdf' 'conges.pdf'
); );
} }
else { else {
return $this->render('Report/holiday.html.twig',[ return $this->render('Report/holiday.html.twig',[
@@ -1093,15 +954,15 @@ class ReportController extends AbstractController
"usesidebar" => ($this->getUser()), "usesidebar" => ($this->getUser()),
"users" => $tbevents "users" => $tbevents
]); ]);
} }
} }
public function activeholiday() { public function activeholiday() {
$this->get('session')->set('activeholiday',!$this->get('session')->get('activeholiday')); $this->get('session')->set('activeholiday',!$this->get('session')->get('activeholiday'));
return $this->redirectToRoute("app_holiday"); return $this->redirectToRoute("app_holiday");
} }
private function frmDay($daynumber) { private function frmDay($daynumber) {
switch($daynumber) { switch($daynumber) {
@@ -1127,4 +988,3 @@ class ReportController extends AbstractController
} }
} }
} }

View File

@@ -97,7 +97,7 @@ class SecurityController extends AbstractController
$user->setPassword("CASPWD-".$username); $user->setPassword("CASPWD-".$username);
$user->setSalt("CASPWD-".$username); $user->setSalt("CASPWD-".$username);
$user->setRole("ROLE_USER"); $user->setRoles(["ROLE_USER"]);
$em->persist($user); $em->persist($user);
$em->flush(); $em->flush();
@@ -132,14 +132,26 @@ class SecurityController extends AbstractController
public function logout() { public function logout() {
$auth_mode=$this->getParameter("appAuth");
switch($auth_mode) {
case "MYSQL":
return $this->logoutMYSQL();
break;
case "CAS":
return $this->logoutCAS();
break;
}
}
public function logoutMYSQL() {
$this->get('security.token_storage')->setToken(null); $this->get('security.token_storage')->setToken(null);
$this->get('session')->invalidate(); $this->get('session')->invalidate();
return $this->redirect($this->generateUrl("cnous_portal_homepage")); return $this->redirect($this->generateUrl("app_home"));
} }
public function logoutcas() { public function logoutcas() {
// Init Client CAS // Init Client CAS
\phpCAS::setDebug('/var/www/html/schedule/var/log/cas.log'); \phpCAS::setDebug('/var/www/html/schedule/var/log/cas.log');
@@ -150,5 +162,7 @@ class SecurityController extends AbstractController
// Logout // Logout
$url=$this->generateUrl('app_home', array(), UrlGeneratorInterface::ABSOLUTE_URL); $url=$this->generateUrl('app_home', array(), UrlGeneratorInterface::ABSOLUTE_URL);
\phpCAS::logout(array("service"=>$url)); \phpCAS::logout(array("service"=>$url));
return true;
} }
} }

View File

@@ -9,7 +9,6 @@ use Symfony\Component\Form\FormError;
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse; use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
use App\Entity\Service as Entity; use App\Entity\Service as Entity;
use App\Entity\User as Fictiv;
use App\Form\ServiceType as Form; use App\Form\ServiceType as Form;
class ServiceController extends AbstractController class ServiceController extends AbstractController
@@ -70,16 +69,6 @@ class ServiceController extends AbstractController
$em->persist($data); $em->persist($data);
$em->flush(); $em->flush();
$fictivuser = new Fictiv();
$fictivuser->setUsername($data->getName());
$fictivuser->setPassword(bin2hex(openssl_random_pseudo_bytes(4)));
$fictivuser->setLastname("Service");
$fictivuser->setFirstname($data->getName());
$fictivuser->setEmail($data->getName());
$fictivuser->setService($data->getId());
$fictivuser->setFictive(true);
$em->persist($fictivuser);
$em->flush();
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);
} }
@@ -157,21 +146,8 @@ class ServiceController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$fictivuser = $em->getRepository("App:User")->findOneBy([ $em->flush();
'service' => $data->getService(),
'fictive' => true,
]);
$em->remove($fictivuser);
$em->remove($data);
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -146,15 +146,8 @@ class TaskController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste // Retour à la liste
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -1,284 +0,0 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Timer as Entity;
use App\Form\TimerType as Form;
class TimerController extends AbstractController
{
private $data = "timer";
private $route = "app_timer";
private $render = "Timer/";
private $entity = "App:Timer";
public function list(Request $request)
{
$em = $this->getDoctrine()->getManager();
$iduser = $this->get("session")->get("iduser");
$user = $em->getRepository("App:User")->find($iduser);
$tasks = $em->getRepository("App:Task")->findAll();
$timers = $em->getRepository("App:Timer")->findBy(["user"=>$iduser]);
return $this->render($this->render.'list.html.twig',[
"useheader" => true,
"usesidebar" => true,
"user" => $user,
"tasks" => $tasks,
"timers" => $timers,
]);
}
public function view(Request $request)
{
$em = $this->getDoctrine()->getManager();
$iduser = $this->get("session")->get("iduser");
$user = $em->getRepository("App:User")->find($iduser);
$tasks = $em->getRepository("App:Task")->findAll();
$timers = $em->getRepository("App:Timer")->findBy(["user"=>$iduser]);
return $this->render($this->render.'list.cal.html.twig',[
"useheader" => true,
"usesidebar" => true,
"user" => $user,
"tasks" => $tasks,
"timers" => $timers,
]);
}
public function load(Request $request)
{
$em = $this->getDoctrine()->getManager();
$tbtimers=[];
// Evenements
$iduser=$this->get("session")->get("iduser");
if($iduser=="all")
$timers=$em->getRepository("App:Timer")->findAll();
else {
$iduser=$this->get("session")->get("iduser");
$user=$em->getRepository("App:User")->find($iduser);
$timers=$em->getRepository("App:Timer")->findBy(["user"=>$user]);
}
foreach($timers as $timer) {
$tmp=$this->formatTimer($timer);
array_push($tbtimers,$tmp);
}
// Retour
return new Response(json_encode($tbtimers));
}
public function create(Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$iduser = $this->get("session")->get("iduser");
$user = $em->getRepository("App:User")->find($iduser);
$taskid = $request->request->get('taskid');
$description = $request->request->get('description');
$task = $em->getRepository("App:Task")->find($taskid);
$start = \DateTime::createFromFormat('D M d Y H:i:s e+',$request->request->get('start'));
$end = \DateTime::createFromFormat('D M d Y H:i:s e+',$request->request->get('end'));
$duration = new \DateTime(date("H:i:s", ($request->request->get('duration')/1000)));
$duration->sub(new \DateInterval('PT1H'));
$activepenalty = $request->request->get('activepenalty');
$additionalhour= $request->request->get('additionalhour');
$officeworkstart = clone $start;
$officeworkend = clone $officeworkstart;
$officeworkstart->SetTime(9,0,0);
$officeworkend->SetTime(17,30,0);
if ($start < $officeworkstart || $end > $officeworkend) {
$timer->setAdditionalHour(true);
}else{
$timer->setAdditionalHour($additionalhour);
}
$timer = new Entity();
$timer->setUser($user);
$timer->setTask($task);
$timer->setStart($start);
$timer->setEnd($end);
$timer->setDuration($duration);
$timer->setDescription($description);
$timer->setActivePenalty($activepenalty);
$em->persist($timer);
$em->flush();
$output=["return"=>"OK"];
return new Response(json_encode($output));
}
public function submit(Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data = new Entity();
$iduser = $this->get("session")->get("iduser");
$user = $em->getRepository("App:User")->find($iduser);
// Création du formulaire
$form = $this->createForm(Form::class,$data,array("mode"=>"submit"));
// Récupération des data du formulaire
$form->handleRequest($request);
// Sur erreur
$this->getErrorForm(null,$form,$request,$data,"submit");
// Sur validation
if ($form->get('submit')->isClicked() && $form->isValid()) {
$data = $form->getData();
$data->setUser($user);
$start = $data->getStart();
$end = $data->getEnd();
$additionalhour = $data->getAdditionalHour();
$officeworkstart = clone $start;
$officeworkend = clone $officeworkstart;
$uStart = explode(":",$this->getParameter('officeHourStart'));
$uEnd = explode(":",$this->getParameter('officeHourEnd'));
$officeworkstart->SetTime(intval($uStart[0]),intval($uStart[1]),0);
$officeworkend->SetTime(intval($uEnd[0]),intval($uEnd[1]),0);
if ($start < $officeworkstart || $end > $officeworkend) {
$data->setAdditionalHour(true);
}else{
$data->setAdditionalHour($additionalhour);
}
$em->persist($data);
$em->flush();
// Retour à la liste
return $this->redirectToRoute($this->route);
}
// Affichage du formulaire
return $this->render($this->render.'edit.html.twig', [
'useheader' => true,
'usesidebar' => true,
$this->data => $data,
'mode' => 'submit',
'form' => $form->createView()
]);
}
public function update($id,Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data=$em->getRepository($this->entity)->find($id);
// Création du formulaire
$form = $this->createForm(Form::class,$data,array("mode"=>"update"));
// Récupération des data du formulaire
$form->handleRequest($request);
// Sur erreur
$this->getErrorForm(null,$form,$request,$data,"update");
// Sur validation
if ($form->get('submit')->isClicked() && $form->isValid()) {
$data = $form->getData();
$em->persist($data);
$em->flush();
// Retour à la liste
return $this->redirectToRoute($this->route);
}
return $this->render($this->render.'edit.html.twig', [
'useheader' => true,
'usesidebar' => true,
$this->data => $data,
'mode' => 'update',
'form' => $form->createView()
]);
}
public function delete($id, Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data=$em->getRepository($this->entity)->find($id);
// Controle avant suppression
$error=false;
if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else {
try {
$em->remove($data);
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
// Retour à la liste
return $this->redirectToRoute($this->route);
}
}
protected function getErrorForm($id,$form,$request,$data,$mode) {
if ($form->get('submit')->isClicked()&&$mode=="delete") {
}
if ($form->get('submit')->isClicked() && $mode=="submit") {
}
if ($form->get('submit')->isClicked() && !$form->isValid()) {
$this->get('session')->getFlashBag()->clear();
$errors = $form->getErrors();
foreach( $errors as $error ) {
$request->getSession()->getFlashBag()->add("error", $error->getMessage());
}
}
}
public function formatTimer($timer) {
$tmp= [
"id"=> $timer->getId(),
"title" => $timer->getTask()->getDisplayname(),
"start" => $timer->getStart()->format("Y-m-d H:i"),
"end" => $timer->getEnd()->format("Y-m-d H:i"),
"backgroundColor" => $timer->getTask()->getColor(),
"borderColor" => $timer->getTask()->getColor(),
"textColor" => "#ffffff",
"allDay" => false,
"editable" => true,
"durationEditable" => false,
"extendedProps" => [
"fulldescription" => $timer->getTask()->getDisplayname()."\n\n".$timer->getDescription(),
"description" => $timer->getDescription(),
"userid" => $timer->getUser()->getId(),
"username" => $timer->getUser()->getUsername(),
"taskid" => $timer->getTask()->getId(),
"avatar" => "/".$this->getParameter("appAlias")."/uploads/avatar/".$timer->getUser()->getAvatar(),
"estimate" => $timer->getDuration()->format("H:i"),
"locked" => false,
"editable" => true,
"astreinte" => false
]
];
return $tmp;
}
}

View File

@@ -202,16 +202,8 @@ class UserController extends AbstractController
if($error) if($error)
return $this->redirectToRoute($this->route."_update",["id"=>$id]); return $this->redirectToRoute($this->route."_update",["id"=>$id]);
else { else {
try { $em->remove($data);
$em->remove($data); $em->flush();
$em->flush();
}
catch(\Doctrine\DBAL\DBALException $e) {
// Création du formulaire
$this->get('session')->getFlashBag()->add('error', 'Impossible de supprimer cet enregistrement');
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
}
$this->refreshsession(); $this->refreshsession();
// Retour à la liste // Retour à la liste

View File

@@ -10,11 +10,7 @@ use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
class ValidationController extends AbstractController class ValidationController extends AbstractController
{ {
private $knpSnappy; private $knpSnappy;
private $notificator; public function __construct(\Knp\Snappy\Pdf $knpSnappy) { $this->knpSnappy = $knpSnappy; }
public function __construct(\Knp\Snappy\Pdf $knpSnappy, \App\Service\notificationService $notificator) {
$this->knpSnappy = $knpSnappy;
$this->notificator = $notificator;
}
public function validation(Request $request) public function validation(Request $request)
{ {
@@ -514,9 +510,6 @@ class ValidationController extends AbstractController
$event->setValidateholiday(true); $event->setValidateholiday(true);
$em->persist($event); $em->persist($event);
$em->flush(); $em->flush();
$iduser=$this->get("session")->get("iduser");
$idevent=$event->getId();
$this->notificator->sendNotifValid("Congé validé", $iduser, $event);
} }
$output=[]; $output=[];
@@ -548,128 +541,6 @@ class ValidationController extends AbstractController
$this->get('session')->set('activeholiday',!$this->get('session')->get('activeholiday')); $this->get('session')->set('activeholiday',!$this->get('session')->get('activeholiday'));
return $this->redirectToRoute("app_validationholiday"); return $this->redirectToRoute("app_validationholiday");
} }
public function validationtimer(Request $request)
{
$em = $this->getDoctrine()->getManager();
$iduser=$this->get("session")->get("iduser");
if($iduser=="all") {
$users=$em->getRepository("App:User")->findAll();
}
else {
$users=$em->getRepository("App:User")->findBy(["id"=>$iduser]);
}
$tbtimers=[];
foreach($users as $user) {
if(in_array("ROLE_USER",$user->getRoles())) {
// Filtre par Service
if($this->get('session')->get('idservice')!="all") {
if($user->getService()->getId()!=$this->get('session')->get('idservice'))
continue;
}
$tmp=[
"id" => $user->getId(),
"user" => $user,
"timers" => [],
"timerstodevalidate" => [],
];
// Timers à valider ou à dévalider
$timers = $em
->createQueryBuilder('timer')
->select('timer')
->from('App:Timer','timer')
->from('App:Task','task')
->Where('timer.user=:user')
->andWhere('timer.validate=:validate')
->andWhere('task=timer.task')
->setParameter('user',$user->getId())
->setParameter('validate',!($this->get("session")->get("activetimer")))
->getQuery()->getResult();
foreach($timers as $timer) {
$tbtimer = [
"id"=>$timer->getId(),
"taskname"=>$timer->getTask()->getDisplayname(),
"user"=>$timer->getUser()->getUsername(),
"start"=>$timer->getStart()->format("Y-m-d H:i"),
"end"=>$timer->getEnd()->format("Y-m-d H:i"),
"duration"=>$timer->getDuration(),
"activepenalty"=>$timer->getActivePenalty(),
"additionalhour"=>$timer->getAdditionalHour(),
"description"=>$timer->getDescription(),
"validate"=>$timer->getValidate(),
];
array_push($tmp["timers"],$tbtimer);
}
array_push($tbtimers,$tmp);
}
}
if($request->query->get('fgprint')) {
$render = $this->renderView('Validation/validationtimer.html.twig',[
"useheader" => true,
"usesidebar" => ($this->getUser()),
"users" => $tbtimers,
"fgprint" => $request->query->get('fgprint'),
]);
return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render),
'validationhoraires.pdf'
);
}
else {
return $this->render('Validation/validationtimer.html.twig',[
"useheader" => true,
"usesidebar" => ($this->getUser()),
"users" => $tbtimers
]);
}
}
public function validatetimer(Request $request){
$em = $this->getDoctrine()->getManager();
// Récupération des variables envoyées en post
$id = $request->request->get('id');
$timer=$em->getRepository("App:Timer")->find($id);
if($timer) {
$timer->setValidate(true);
$em->persist($timer);
$em->flush();
$iduser=$this->get("session")->get("iduser");
$idtimer=$timer->getId();
}
$output=[];
return new Response(json_encode($output));
}
public function devalidatetimer(Request $request){
$em = $this->getDoctrine()->getManager();
// Récupération des variables envoyées en post
$id = $request->request->get('id');
$timer=$em->getRepository("App:Timer")->find($id);
if($timer) {
$timer->setValidate(false);
$em->persist($timer);
$em->flush();
}
$output=[];
return new Response(json_encode($output));
}
public function activetimer() {
$this->get('session')->set('activetimer',!$this->get('session')->get('activetimer'));
return $this->redirectToRoute("app_validationtimer");
}
} }

View File

@@ -50,12 +50,6 @@ class Event
*/ */
private $allday; private $allday;
/**
* @ORM\Column(name="externaltrip", type="boolean")
*
*/
private $externaltrip;
/** /**
* @ORM\Column(name="validate", type="boolean") * @ORM\Column(name="validate", type="boolean")
* *
@@ -102,24 +96,24 @@ class Event
public function getStart(): ?\DateTimeInterface public function getStart(): ?\DateTimeInterface
{ {
return clone $this->start; return $this->start;
} }
public function setStart(\DateTimeInterface $start): self public function setStart(\DateTimeInterface $start): self
{ {
$this->start = clone $start; $this->start = $start;
return $this; return $this;
} }
public function getEnd(): ?\DateTimeInterface public function getEnd(): ?\DateTimeInterface
{ {
return clone $this->end; return $this->end;
} }
public function setEnd(\DateTimeInterface $end): self public function setEnd(\DateTimeInterface $end): self
{ {
$this->end = clone $end; $this->end = $end;
return $this; return $this;
} }
@@ -135,17 +129,6 @@ class Event
return $this; return $this;
} }
public function getExternalTrip(): ?bool
{
return $this->externaltrip;
}
public function setExternalTrip(bool $externaltrip): self
{
$this->externaltrip = $externaltrip;
return $this;
}
public function getValidate(): ?bool public function getValidate(): ?bool
{ {

View File

@@ -61,17 +61,12 @@ class Task
*/ */
private $events; private $events;
/**
* @ORM\OneToMany(targetEntity="Timer", mappedBy="task", cascade={"persist"}, orphanRemoval=false)
*/
private $timers;
/** /**
* @ORM\OneToMany(targetEntity="Penalty", mappedBy="task", cascade={"persist"}, orphanRemoval=false) * @ORM\OneToMany(targetEntity="Penalty", mappedBy="task", cascade={"persist"}, orphanRemoval=false)
*/ */
private $penaltys; private $penaltys;
/** /**
* Calculate Displayname * Calculate Displayname
*/ */
public function getDisplayname(): ?string public function getDisplayname(): ?string
@@ -79,7 +74,7 @@ class Task
return $this->project->getCustomer()->getName()."-".$this->project->getName()."-".$this->name; return $this->project->getCustomer()->getName()."-".$this->project->getName()."-".$this->name;
} }
/** /**
* Calculate Duration * Calculate Duration
*/ */
public function getDuration($end): ?string public function getDuration($end): ?string
@@ -95,7 +90,6 @@ class Task
public function __construct() public function __construct()
{ {
$this->events = new ArrayCollection(); $this->events = new ArrayCollection();
$this->timers = new ArrayCollection();
$this->penaltys = new ArrayCollection(); $this->penaltys = new ArrayCollection();
} }
@@ -197,24 +191,6 @@ class Task
return $this; return $this;
} }
/**
* @return Collection|Timer[]
*/
public function getTimers(): Collection
{
return $this->tasks;
}
public function addTimer(Timer $timer): self
{
if (!$this->timers->contains($timer)) {
$this->timers[] = $timer;
$timer->setTask($this);
}
return $this;
}
public function removeEvent(Event $event): self public function removeEvent(Event $event): self
{ {
if ($this->events->contains($event)) { if ($this->events->contains($event)) {
@@ -259,17 +235,4 @@ class Task
return $this; return $this;
} }
public function removeTimer(Timer $timer): self
{
if ($this->timers->contains($timer)) {
$this->timers->removeElement($timer);
// set the owning side to null (unless already changed)
if ($timer->getTask() === $this) {
$timer->setTask(null);
}
}
return $this;
}
} }

View File

@@ -1,197 +0,0 @@
<?php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Timer
*
* @ORM\Table(name="timer")
* @ORM\Entity(repositoryClass="App\Repository\TimerRepository")
*/
class Timer
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(name="start", type="datetime")
*
*/
private $start;
/**
* @ORM\Column(name="end", type="datetime")
*
*/
private $end;
/**
* @ORM\Column(name="duration", type="datetime")
*
*/
private $duration;
/**
* @ORM\Column(type="text", nullable=true)
*/
private $description;
/**
* @ORM\ManyToOne(targetEntity="User")
*/
private $user;
/**
* @ORM\ManyToOne(targetEntity="Task", inversedBy="timers"))
*/
private $task;
/**
* @ORM\Column(name="activepenalty", type="boolean")
*
*/
private $activepenalty;
/**
* @ORM\Column(name="additionalhour", type="boolean")
*
*/
private $additionalhour;
/**
* @ORM\Column(name="validate", type="boolean")
*
*/
private $validate;
public function __construct()
{
$this->start = new \DateTime();
$this->end = new \DateTime();
$this->duration = new \DateTime();
$this->validate = false;
}
public function getId(): ?int
{
return $this->id;
}
public function getStart(): ?\DateTimeInterface
{
return $this->start;
}
public function setStart(\DateTimeInterface $start): self
{
$this->start = $start;
return $this;
}
public function getEnd(): ?\DateTimeInterface
{
return $this->end;
}
public function setEnd(\DateTimeInterface $end): self
{
$this->end = $end;
return $this;
}
public function getDuration(): ?\DateTimeInterface
{
return $this->duration;
}
public function setDuration(\DateTimeInterface $duration): self
{
$this->duration = $duration;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
public function getTask(): ?Task
{
return $this->task;
}
public function setTask(?Task $task): self
{
$this->task = $task;
return $this;
}
public function getActivePenalty(): ?bool
{
return $this->activepenalty;
}
public function setActivePenalty(bool $activepenalty): self
{
$this->activepenalty = $activepenalty;
return $this;
}
public function getAdditionalHour(): ?bool
{
return $this->additionalhour;
}
public function setAdditionalHour(bool $additionalhour): self
{
$this->additionalhour = $additionalhour;
return $this;
}
public function getValidate(): ?bool
{
return $this->validate;
}
public function setValidate(bool $validate): self
{
$this->validate = $validate;
return $this;
}
}

View File

@@ -11,7 +11,7 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/** /**
* User * User
* *
* @ORM\Entity(repositoryClass="App\Repository\UserRepository") * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
* @ORM\Table(name="user",indexes={@ORM\Index(name="username", columns={"username"})}) * @ORM\Table(name="user",indexes={@ORM\Index(name="username", columns={"username"})})
* @UniqueEntity("username", message="Ce nom d'utilisateur existe dèja") * @UniqueEntity("username", message="Ce nom d'utilisateur existe dèja")
@@ -84,7 +84,7 @@ class User implements UserInterface, \Serializable
* @ORM\ManyToOne(targetEntity="Service", inversedBy="users") * @ORM\ManyToOne(targetEntity="Service", inversedBy="users")
* @ORM\JoinColumn(nullable=true) * @ORM\JoinColumn(nullable=true)
*/ */
private $service; private $service;
/** /**
* @ORM\OneToMany(targetEntity="Event", mappedBy="user", cascade={"persist"}, orphanRemoval=false) * @ORM\OneToMany(targetEntity="Event", mappedBy="user", cascade={"persist"}, orphanRemoval=false)
@@ -104,16 +104,11 @@ class User implements UserInterface, \Serializable
* ) * )
*/ */
protected $jobs; protected $jobs;
/** /**
* @ORM\OneToMany(targetEntity="Userproject", mappedBy="user", cascade={"persist"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="Userproject", mappedBy="user", cascade={"persist"}, orphanRemoval=true)
*/ */
private $userprojects; private $userprojects;
/**
* @ORM\Column(name="fictive", type="boolean")
*
*/
private $fictive;
public function __construct() public function __construct()
{ {
@@ -122,7 +117,6 @@ class User implements UserInterface, \Serializable
$this->penaltys = new ArrayCollection(); $this->penaltys = new ArrayCollection();
$this->jobs = new ArrayCollection(); $this->jobs = new ArrayCollection();
$this->userprojects = new ArrayCollection(); $this->userprojects = new ArrayCollection();
$this->fictive = false;
} }
public function getUsername(): ?string public function getUsername(): ?string
@@ -412,19 +406,7 @@ class User implements UserInterface, \Serializable
} }
return $this; return $this;
} }
public function getFictive(): ?bool
{
return $this->fictive;
}
public function setFictive(bool $fictive): self
{
$this->fictive = $fictive;
return $this;
}
} }

View File

@@ -1,110 +0,0 @@
<?php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\ChoiceList\ChoiceList;
use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class TimerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('submit',
SubmitType::class, [
"label" => "Valider",
"attr" => ["class" => "btn btn-success no-print"],
]
);
$builder->add('task',
EntityType::class, [
"label" => "Tâche",
"class" => "App:Task",
"choice_label" => function ($task) {
return $task->getDisplayname();},
"disabled" => false,
"required" => true,
"multiple" => false,
"placeholder" => "Selectionner une Tâche",
]
);
$builder->add('description',
TextType::class, [
"label" => "Description",
"required" => false
]
);
$builder->add("activepenalty",
ChoiceType::class,[
"label" => "Astreinte active",
"choices" => ["Non"=>false, "Oui"=>true]
]
);
$builder->add("additionalhour",
ChoiceType::class,[
"label" => "Heures supplémentaires",
"choices" => ["Non"=>false, "Oui"=>true]
]
);
$builder->add('start',
DateTimeType::class, [
"label" =>"Début",
"date_widget" => "single_text",
"time_widget" => "single_text",
"format" => "yyyy-MM-dd HH:mm",
]
);
$builder->add('end',
DateTimeType::class, [
"label" =>"Fin",
"date_widget" => "single_text",
"time_widget" => "single_text",
"format" => "yyyy-MM-dd HH:mm",
]
);
$builder->add('duration',
TimeType::class, [
"label" =>"Durée",
"widget" => "single_text",
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Timer',
'mode' => 'string',
));
}
}

View File

@@ -1,98 +0,0 @@
<?php
namespace App\Service;
use Doctrine\ORM\EntityManagerInterface;
class notificationService
{
private $em;
protected $mailer;
protected $twig;
public function __construct(EntityManagerInterface $em, \Swift_Mailer $mailer, \Twig\Environment $twig)
{
$this->mailer = $mailer;
$this->twig = $twig;
$this->em = $em;
}
public function sendNotifAttenteValid($subject, $iduser, $idevent, $valid_url)
{
$template = $this->twig->load('Notif/attentevalidation.html.twig');
$user=$this->em->getRepository("App:User")->find($iduser);
$event=$this->em->getRepository("App:Event")->find($idevent);
$users=$this->em->getRepository("App:User")->findAll();
$tbemails=[];
foreach($users as $usr) {
if(in_array("ROLE_VALIDATOR",$usr->getRoles())) {
array_push($tbemails,$usr->getEmail());
}
// else{
// if(in_array("ROLE_MASTER",$usr->getRoles())) {
// if ($usr->getService() == $user->getService() ){
// $tmp=[
// "id"=>$usr->getId(),
// "email"=>$usr->getEmail()
// ];
// }
// array_push($tbemails,$tmp);
// }
// }
}
$parameters=[
'date' => new \DateTime(),
'username' => $user->getUsername(),
'start' => $event->getStart(),
'end' => $event->getEnd(),
'duration' => $event->getDuration(),
'valid_link' => $valid_url,
];
$bodyHtml = $template->renderBlock('body', $parameters);
$message = (new \Swift_Message())
->setFrom('schedule@cadoles.com')
->setSubject($user->getUsername() . " = " . $subject)
//TODO envoyer à tt les users master associé au service de l'utilisateur et l'ensemble des user validator
->setTo($tbemails)
->setBody($bodyHtml, 'text/html');
$response = $this->mailer->send($message);
return $response;
}
public function sendNotifValid($subject, $iduser, $idevent)
{
$template = $this->twig->load('Notif/validation.html.twig');
$user=$this->em->getRepository("App:User")->find($iduser);
$event=$this->em->getRepository("App:Event")->find($idevent);
$users=$this->em->getRepository("App:User")->findAll();
$tbemails=[];
foreach($users as $usr) {
if(in_array("ROLE_VALIDATOR",$usr->getRoles())) {
array_push($tbemails,$usr->getEmail());
}
}
$parameters=[
'date' => new \DateTime(),
'username' => $user->getUsername(),
'start' => $event->getStart(),
'end' => $event->getEnd(),
'duration' => $event->getDuration(),
];
$bodyHtml = $template->renderBlock('body', $parameters);
$message = (new \Swift_Message())
->setFrom('schedule@cadoles.com')
->setSubject($user->getUsername() . " = " . $subject)
->setTo($this->container->getParameter('appMailnotif'))
->setCc($tbemails)
->setBody($bodyHtml, 'text/html');
$response = $this->mailer->send($message);
return $response;
}
}

View File

@@ -69,7 +69,6 @@ class sessionListener {
$session->set('activeproject',true); $session->set('activeproject',true);
$session->set('activeoffer',true); $session->set('activeoffer',true);
$session->set('activeholiday',true); $session->set('activeholiday',true);
$session->set('activetimer',true);
$session->set('nbmonth',3); $session->set('nbmonth',3);
if($curentuser!="anon.") { if($curentuser!="anon.") {
@@ -120,10 +119,7 @@ class sessionListener {
]; ];
array_push($tbservices,$tmp); array_push($tbservices,$tmp);
} }
$session->set('services',$tbservices); $session->set('services',$tbservices);
$selectedusers=[];
$session->set('selectedusers',$selectedusers);
} }
} }
} }

View File

@@ -21,31 +21,23 @@
.fc-title { .fc-title {
font-weight: bolder; font-weight: bolder;
font-size: 12px; font-size: 14px;
} }
.eventAvatar { .eventAvatar {
width: 20px; width: 40px;
margin: 0px 5px 0px 0px; margin: 0px 5px 0px 0px;
float: left; float: left;
} }
.eventInfo{ .eventInfo{
margin: -5px 5px 0px 0px; margin: -18px 5px 0px 0px;
clear: both;
}
.eventUser{
clear: both; clear: both;
} }
.eventEstimate { .eventEstimate {
margin: -3px 10px; margin: -3px 10px;
} }
.fictive{
height:10px!important;
background-color:#cdcdcd;
}
{% endblock %} {% endblock %}
{% block body %} {% block body %}
@@ -113,12 +105,6 @@
<label class="custom-control-label" for="astreinte">Astreinte</label> <label class="custom-control-label" for="astreinte">Astreinte</label>
</div> </div>
</div> </div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="externaltrip">
<label class="custom-control-label" for="externaltrip">Déplacement externe</label>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="description" class="control-label"> <label for="description" class="control-label">
@@ -167,6 +153,7 @@
{% endif %} {% endif %}
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label required" for="taskupdate"> <label class="control-label required" for="taskupdate">
Project<span class="mandatory">*</span> Project<span class="mandatory">*</span>
@@ -178,25 +165,7 @@
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="amupdate">
<label class="custom-control-label" for="amupdate">Evènement sur la matinée</label>
</div>
</div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="apupdate">
<label class="custom-control-label" for="apupdate">Evènement sur l'après-midi</label>
</div>
</div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="externaltripupdate">
<label class="custom-control-label" for="externaltripupdate">Déplacement externe</label>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="description" class="control-label"> <label for="description" class="control-label">
Description Description
@@ -219,7 +188,6 @@
{% block localjavascript %} {% block localjavascript %}
$(document).ready(function() { $(document).ready(function() {
$("#modalsubmit #user").select2({ $("#modalsubmit #user").select2({
theme: 'bootstrap4', theme: 'bootstrap4',
@@ -247,50 +215,30 @@ $(document).ready(function() {
// Rendu d'un évenement // Rendu d'un évenement
function eventRender(info) { function eventRender(info) {
console.log(info.event.extendedProps);
// Récupération des divers élements du rendu event // Récupération des divers élements du rendu event
var content=$(info.el).children('.fc-content'); var content=$(info.el).children('.fc-content');
var title=$(content).children('.fc-title'); var title=$(content).children('.fc-title');
if(!info.event.extendedProps.fictivuser){
// Ajouter l'avatar
content.prepend("<img src="+info.event.extendedProps.avatar+" class='eventAvatar'>");
content.append("<span class='eventUser float-left small'>"+info.event.extendedProps.username+"</span>");
var eventInfo=$(content).children('.eventUser');
// Ajout container // Ajouter l'avatar
content.append("<span class='eventInfo float-right'></span>"); content.prepend("<img src="+info.event.extendedProps.avatar+" class='eventAvatar'>");
var eventInfo=$(content).children('.eventInfo');
// Ajouter le verrou si event non editable // Ajout container
if(info.event.extendedProps.locked) { content.append("<span class='eventInfo float-right'></span>");
eventInfo.append("<i class='fa fa-lock float-right'></i>"); var eventInfo=$(content).children('.eventInfo');
}
if(info.event.extendedProps.externaltrip) {
eventInfo.append("<i class='fas fa-bed float-right'></i>");
}
if(info.event.extendedProps.holiday) {
eventInfo.append("<i class='fas fa-umbrella-beach float-right'></i>");
}
// Ajout estimation
eventInfo.append("<span class='eventEstimate float-right small'>"+info.event.extendedProps.estimate+"</span>");
}else{ // Ajouter le verrou si event non editable
$(content).addClass('fictive'); if(info.event.extendedProps.locked) {
$(content).children('.fc-title').remove(); eventInfo.append("<i class='fa fa-lock float-right'></i>");
} }
// Ajout estimation
eventInfo.append("<span class='eventEstimate float-right'>"+info.event.extendedProps.estimate+"</span>");
// Description // Description
content.attr("data-placement","top");
content.attr("data-html",true);
content.attr("data-toggle","tooltip");
content.attr("title",info.event.extendedProps.fulldescription); content.attr("title",info.event.extendedProps.fulldescription);
content.tooltip()
} }
// Formulaire Création d'un événement // Formulaire Création d'un évelement
var allDay; var allDay;
function eventSelect(selectionInfo) { function eventSelect(selectionInfo) {
var start=moment(selectionInfo.start); var start=moment(selectionInfo.start);
@@ -336,73 +284,32 @@ function eventSelect(selectionInfo) {
$('#modalsubmit #end').val(end.format("YYYY-MM-DD")); $('#modalsubmit #end').val(end.format("YYYY-MM-DD"));
$('#modalsubmit #description').val(""); $('#modalsubmit #description').val("");
$('#modalsubmit #externaltrip').prop("checked",false);
$("#modalsubmit .alert").remove(); $("#modalsubmit .alert").remove();
// Formulaire de création d'un évènement // Formulaire de création d'un évènement
$('#modalsubmit').modal(); $('#modalsubmit').modal();
} }
// Formulaire Modification d'un événement // Formulaire Modification d'un évelement
function eventClick(info) { function eventClick(info) {
if(info.event.extendedProps.editable) { if(info.event.extendedProps.editable) {
console.log(info.event); console.log(info.event.id);
var id=info.event.id; var id=info.event.id;
var description=info.event.extendedProps.description; var description=info.event.extendedProps.description;
var userid=info.event.extendedProps.userid; var userid=info.event.extendedProps.userid;
var taskid=info.event.extendedProps.taskid; var taskid=info.event.extendedProps.taskid;
var fgastreinte=info.event.extendedProps.astreinte; var fgastreinte=info.event.extendedProps.astreinte;
var eventallday = info.event.allDay;
var eventstart = info.event.start;
var eventend = info.event.end;
var externaltrip = info.event.extendedProps.externaltrip;
var holiday = info.event.extendedProps.holiday;
$('#userupdate').val(userid).trigger("change"); $('#userupdate').val(userid).trigger("change");
$('#taskupdate').val(taskid).trigger("change"); $('#taskupdate').val(taskid).trigger("change");
$('#modalupdate #idevent').val(id); $('#modalupdate #idevent').val(id);
$('#modalupdate #fgastreinte').val(fgastreinte); $('#modalupdate #fgastreinte').val(fgastreinte);
$('#modalupdate #description').val(description); $('#modalupdate #description').val(description);
if (holiday) {
$('#modalupdate #externaltripupdate').prop("checked",false);
$('#modalupdate #externaltripupdate').prop("disabled",true);
}else{
$('#modalupdate #externaltripupdate').prop("disabled",false);
$('#modalupdate #externaltripupdate').prop("checked",externaltrip);
}
$("#modalupdate .alert").remove();
eDayStart=eventstart.toString().split(" ")[2]
eDayEnd=eventend.toString().split(" ")[2]
if ((eDayEnd - eDayStart) >1) {
$('#modalupdate #amupdate').prop("checked",true);
$('#modalupdate #apupdate').prop("checked",true);
$('#modalupdate #amupdate').prop("disabled",true);
$('#modalupdate #apupdate').prop("disabled",true);
}else{
$('#modalupdate #amupdate').prop("disabled",false);
$('#modalupdate #apupdate').prop("disabled",false);
if (!eventallday){
eStart = eventstart.toString().split(" ")[4].split(":")[0]
//eEnd = eventend.toString().split(" ")[4].split(":")[0]
//AM $("#modalupdate .alert").remove();
if (eStart == 09){
$('#modalupdate #amupdate').prop("checked",true);
$('#modalupdate #apupdate').prop("checked",false);
}
//AP
if (eStart == 13){
$('#modalupdate #amupdate').prop("checked",false);
$('#modalupdate #apupdate').prop("checked",true);
}
}else{
$('#modalupdate #amupdate').prop("checked",true);
$('#modalupdate #apupdate').prop("checked",true);
}
}
// Formulaire de création d'un évènement // Formulaire de création d'un évènement
$('#modalupdate').modal(); $('#modalupdate').modal();
} }
@@ -436,7 +343,6 @@ function eventSubmit() {
am: $("#modalsubmit #amsubmit").prop("checked"), am: $("#modalsubmit #amsubmit").prop("checked"),
ap: $("#modalsubmit #apsubmit").prop("checked"), ap: $("#modalsubmit #apsubmit").prop("checked"),
astreinte: $("#modalsubmit #astreinte").prop("checked"), astreinte: $("#modalsubmit #astreinte").prop("checked"),
externaltrip: $("#modalsubmit #externaltrip").prop("checked"),
description: $("#modalsubmit #description").val() description: $("#modalsubmit #description").val()
}, },
url: "{{ path('app_event_submit') }}", url: "{{ path('app_event_submit') }}",
@@ -465,10 +371,7 @@ function eventUpdate() {
idevent: $("#modalupdate #idevent").val(), idevent: $("#modalupdate #idevent").val(),
iduser: $("#userupdate").val(), iduser: $("#userupdate").val(),
idtask: $("#taskupdate").val(), idtask: $("#taskupdate").val(),
am: $("#modalupdate #amupdate").prop("checked"),
ap: $("#modalupdate #apupdate").prop("checked"),
fgastreinte: $("#modalupdate #fgastreinte").val(), fgastreinte: $("#modalupdate #fgastreinte").val(),
externaltrip: $("#modalupdate #externaltripupdate").prop("checked"),
description: $("#modalupdate #description").val() description: $("#modalupdate #description").val()
}, },
url: "{{ path('app_event_update') }}", url: "{{ path('app_event_update') }}",
@@ -516,6 +419,7 @@ function eventDelete() {
// On change astreinte // On change astreinte
$("#astreinte").change(function() { $("#astreinte").change(function() {
console.log(allDay)
if(this.checked) { if(this.checked) {
$("#amsubmit").prop("disabled",true); $("#amsubmit").prop("disabled",true);
$("#apsubmit").prop("disabled",true); $("#apsubmit").prop("disabled",true);

View File

@@ -1,8 +0,0 @@
{% block body %}
Utilisateur;Jour;Journée entière;Astreinte;AM;AP;Taches;AM;Tache AM;AP;Tache AP;Astreinte;Description Astreintes
{% for user in users %}
{% for day, event in user.events %}
{{ user.user.displayname }};{{day}};{{event.allday}};{{event.astreinte}};{{event.am}};{{event.ap}};{{event.descriptionday|trim}} {{event.descriptionam|trim}} {{event.descriptionap|trim}} {{event.descriptionastreinte|trim}}
{% endfor %}
{% endfor %}
{% endblock %}

View File

@@ -1,6 +0,0 @@
{% block body %}
Tâche;Astr.Act;H.Supp;Utilisateur;Début;Fin;Durée;Description;
{% for timer in timers %}
{{timer.taskname}};{{timer.activepenalty}};{{timer.additionalhour}};{{timer.user}};{{timer.start|date("d/m/Y H:i")}};{{timer.end|date("d/m/Y H:i")}};{{timer.duration|date("H:i")}};{{timer.description}};
{% endfor %}
{% endblock %}

View File

@@ -1,16 +0,0 @@
{% block body %}
Client;Projet;Tâche;Utilisateur;Année;Semaine;Cumul;
{% for project in projects %}
{% if project.weeks_by_task_by_user is defined %}
{% for year,weeks in project.weeks_by_task_by_user %}
{% for week in weeks %}
{% for task in week.tasks%}
{% for user in task.users%}
{{project.customer}};{{project.name}};{{task.taskname}};{{user.displayname}};{{year}};S{{week.weeknumber}};{{user.cumul|replace({".": ","})}};
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endif %}
{% endfor %}
{% endblock %}

View File

@@ -1,36 +0,0 @@
{% extends "base.html.twig" %}
{% block body %}
<h1 class="page-header">
EXPORTS DE DONNEES
</h1>
<div class="card">
<div class="card-header">
<a href="{{ path('export_project_weekly') }}" class="btn btn-success">Export des Projets par semaine par participant</a>
</div>
<div class="card-body">
<p>Exporter le cumul des points éffectués sur un/des projets, par tâche par utilisateur.</p>
<p>Filtres utiles : Nombres de mois, Projet, Service</p>
</div>
</div>
<p></p>
<div class="card">
<div class="card-header">
<a class="btn btn-success" href={{ path('app_export_penalty_additional') }}>Export des astreintes actives et heures supplémentaires</a>
</div>
<div class="card-body">
<p>Exporter la liste des astreintes actives réalisés, ainsi que les saisies en heure supplémentaires.</p>
<p>Filtres utiles : Intervenant (hors "Tout le monde")</p>
</div>
</div>
<p></p>
<div class="card">
<div class="card-header">
<a class="btn btn-success" href={{ path('export_full_worked_days') }}>Export des jours pleins travaillés</a>
</div>
<div class="card-body">
<p>Exporter la liste des jours travaillés pleinement éligibles aux tickets restaurants</p>
<p>Filtres utiles : Nombre de mois, Intervenant</p>
</div>
</div>
<p></p>
{% endblock %}

View File

@@ -1,25 +0,0 @@
{% block body %}
{% autoescape %}
<h2>Date de la demande : {{ date|date("d/m/Y H:i") }} </h2>
<p>
<b>Utilisateur =</b> {{ username }}
</p>
<p>
<b>Début =</b> {{ start|date("d/m/Y H:i") }}
</p>
<p>
<b>Fin =</b> {{ end|date("d/m/Y H:i") }}
</p>
<p>
<b>Durée =</b> {{ duration }}
</p>
<p>
<b>Type =</b> Congé
</p>
<p>
<b>Lien pour valider =</b> {{ valid_link }}
</p>
{% endautoescape %}
{% endblock %}

View File

@@ -1,23 +0,0 @@
{% block body %}
{% autoescape %}
<h2>VALIDATION</h2>
<p>
<b>Utilisateur =</b> {{ username }}
</p>
<p>
<b>Début =</b> {{ start|date("d/m/Y H:i") }}
</p>
<p>
<b>Fin =</b> {{ end|date("d/m/Y H:i") }}
</p>
<p>
<b>Durée =</b> {{ duration }}
</p>
<p>
<b>Type =</b> Congé
</p>
{% endautoescape %}
{% endblock %}

View File

@@ -18,7 +18,7 @@
{% block body %} {% block body %}
<h1 class="page-header"> <h1 class="page-header">
COMMANDES PROPOSITIONS
</h1> </h1>
<a class="btn btn-success" href={{ path('app_offer_submit') }}>Ajouter</a> <a class="btn btn-success" href={{ path('app_offer_submit') }}>Ajouter</a>

View File

@@ -12,7 +12,7 @@
thead { thead {
display: table-header-group; display: table-header-group;
} }
tr { page-break-inside: avoid; } tr { page-break-inside: avoid; }
{%endif%} {%endif%}
{% endblock %} {% endblock %}
@@ -69,12 +69,7 @@
<tr> <tr>
<td class="no-print"> <td class="no-print">
<a href="{{path("app_project_update",{id:project.id})}}"><i class="fa fa-file"></i></a> <a href="{{path("app_project_update",{id:project.id})}}"><i class="fa fa-file"></i></a>
<a href="{{path("app_project_users",{id:project.id})}}" <a href="{{path("app_project_users",{id:project.id})}}"><i class="fa fa-users"></i></a>
data-toggle="tooltip"
data-placement="right"
data-html="true"
title="{% for user in project.userprojects %}<b>{{user.user.username}}:</b> {{user.job.name}} <br />{% endfor %}"
><i class="fa fa-users"></i></a>
</td> </td>
<td>{{project.customer.name}}</td> <td>{{project.customer.name}}</td>
@@ -94,7 +89,7 @@
{% for task in project.tasks %} {% for task in project.tasks %}
{% set tottask=tottask+task.quantity %} {% set tottask=tottask+task.quantity %}
{% set totvalidate=totvalidate+task.validate %}
{% set totplanified=totplanified+task.validate %} {% set totplanified=totplanified+task.validate %}
{% for event in task.events %} {% for event in task.events %}
{% set totplanified=totplanified+event.duration %} {% set totplanified=totplanified+event.duration %}
@@ -135,9 +130,6 @@
{% endblock %} {% endblock %}
{% block localjavascript %} {% block localjavascript %}
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
$(document).ready(function() { $(document).ready(function() {
{% if not fgprint is defined or not fgprint %} {% if not fgprint is defined or not fgprint %}
$('.table').DataTable({ $('.table').DataTable({

View File

@@ -93,6 +93,7 @@
{% block body %} {% block body %}
{% if fgprint is defined and fgprint %}<h1>Planning</h1>{%endif%} {% if fgprint is defined and fgprint %}<h1>Planning</h1>{%endif%}
{% if access=="customer" and not app.user %} {% if access=="customer" and not app.user %}
<div class="no-print" style="margin-top:10px;"> <div class="no-print" style="margin-top:10px;">
<style> .select2-container { display:inline-block} </style> <style> .select2-container { display:inline-block} </style>
@@ -124,9 +125,40 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<h3>RAPPORT</h3> <h4>RAPPORT</h4>
<div class="small"> <div class="small">
{% if project.hors!=0 %}
consommé avant = {{ project.hors }}<br>
{% endif %}
{% set bycolonne = max(10,((project.before|length)/3)|round) %}
{% set compteur = 0 %}
<div class="row">
<div class="col-md-4">
{% for month in project.before %}
{% set compteur = compteur + 1 %}
{% if compteur > bycolonne %}
</div>
<div class="col-md-4">
{% set compteur = 1 %}
{% endif %}
consommé le {{ month.monthlabel }} = {{ month.duration }}<br>
{% endfor %}
</div>
</div>
</div>
{% if not project.beforeastreinte is empty %}
<h4>ASTREINTE</h4>
{% set compteur = 0 %}
<div class="small">
{% for month in project.beforeastreinte %}
consommé le {{ month.monthlabel }} = {{ month.duration }}<br>
{% endfor %}
</div>
{% endif %}
<div class="new-page">&nbsp;</div> <div class="new-page">&nbsp;</div>
{% for month in project.months %} {% for month in project.months %}
@@ -189,37 +221,10 @@
</table> </table>
{% endif %} {% endif %}
<div class="new-page">&nbsp;</div>
{% endfor %} {% endfor %}
<h4>CUMUL HEBDOMADAIRE</h4>
<table>
{% for year, weeks in project.weeks %}
<thead>
<th class="text-center day">
{{ year}}
</th>
{% for week in weeks %}
<th class="text-center">
S{{ week.weeknumber}}
</th>
{% endfor %}
</thead>
<tr class="text-center">
<td class="text-center">
</td>
{% for week in weeks %}
<td class="text-center">
{{ week.cumul}}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<div class="new-page">&nbsp;</div>
{% if not project.offers is empty %} {% if not project.offers is empty %}
<h4>COMMANDES</h4> <h4>COMMANDES</h4>
{% set count=(project.offers|length)-8 %} {% set count=(project.offers|length)-8 %}
@@ -329,64 +334,7 @@
<div class="new-page">&nbsp;</div> <div class="new-page">&nbsp;</div>
{% endif %} {% endif %}
<h4>CONSOMMATION PASSEE</h4>
{% if project.hors!=0 %}
Consommation précédente totale = {{ project.hors }}<br>
{% endif %}
<table>
{% for year in project.before %}
<thead>
<th class="text-center day">
Date
</th>
{% for month in year %}
<th class="text-center">
{{ month.monthlabel }}
</th>
{% endfor %}
</thead>
<tr class="text-center">
<td class="text-center">
Consommé
</td>
{% for month in year %}
<td class="text-center">
{{ month.duration }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% if not project.beforeastreinte is empty %}
<h4>ASTREINTES PASSEES</h4>
<table>
{% for year in project.beforeastreinte %}
<thead>
<th class="text-center day">
Date
</th>
{% for month in year %}
<th class="text-center">
{{ month.monthlabel }}
</th>
{% endfor %}
</thead>
<tr class=" text-center">
<td class="text-center">
Consommé
</td>
{% for month in year %}
<td class="text-center">
{{ month.duration }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% endif %}
</div> </div>
</div> </div>
{% endif %} {% endif %}

View File

@@ -66,7 +66,6 @@
<div class="card-body"> <div class="card-body">
<table> <table>
<thead> <thead>
<th>S</th>
<th>L</th> <th>L</th>
<th>M</th> <th>M</th>
<th>M</th> <th>M</th>
@@ -79,8 +78,8 @@
{% for event in user.events %} {% for event in user.events %}
{% if nbday==1 %} {% if nbday==1 %}
<tr> <tr>
<td class="date" style="vertical-align:middle">{{event.date|date("W")}}</td>
{% endif %} {% endif %}
<td> <td>
<div class="date">{{ event.date | date("d/m") }}</div> <div class="date">{{ event.date | date("d/m") }}</div>
{% if event.allday %} {% if event.allday %}

View File

@@ -1,112 +0,0 @@
{% extends "base.html.twig" %}
{% block localstyle %}
td {
padding:5px !important;
}
{% endblock %}
{% block body %}
{{ form_start(form) }}
<h1 class="page-header">
{% if mode=="update" %}
Modification TIMER
{% elseif mode=="submit" %}
Création TIMER
{% endif %}
</h1>
{{ form_widget(form.submit) }}
<a class="btn btn-secondary" href={{ path('app_timer') }}>Annuler</a>
{% if mode=="update" %}
<a href="{{ path('app_timer_delete',{'id':timer.id}) }}"
class="btn btn-danger float-right"
data-method="delete"
data-confirm="Êtes-vous sûr de vouloir supprimer cet entregistrement ?">
Supprimer
</a>
{% endif %}
<br><br>
{% if app.session.flashbag.has('error') %}
<div class='alert alert-danger' style='margin: 5px 0px'>
<strong>Erreur</strong><br>
{% for flashMessage in app.session.flashbag.get('error') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
{% if app.session.flashbag.has('notice') %}
<div class='alert alert-info' style='margin: 5px 0px'>
<strong>Information</strong><br>
{% for flashMessage in app.session.flashbag.get('notice') %}
{{ flashMessage }}<br>
{% endfor %}
</div>
{% endif %}
<div class="card">
<div class="card-header">
<i class="fa fa-pencil-alt fa-fw"></i> Informations
</div>
<div class="card-body">
{{ form_row(form.task) }}
{{ form_row(form.description) }}
{{ form_row(form.activepenalty) }}
{{ form_row(form.additionalhour) }}
{{ form_row(form.start) }}
{{ form_row(form.end) }}
{{ form_row(form.duration) }}
</div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block localjavascript %}
$("#timer_task").addClass("select2entity");
/*
* Pads this string with another string on the left until the resulting string
* has specified length. If the padding string has more than one character, the
* resulting string may be longer than desired (the padding string is not
* truncated and it is only prepended as a whole). Bad API, I know, but it's
* good enough for me.
*/
String.prototype.pad = function(length, padding) {
var result = this;
while (result.length < length) {
result = padding + result;
}
return result;
}
/* Some time constants. */
var MILISECONDS_IN_SECOND = 1000;
var MILISECONDS_IN_MINUTE = 60 * MILISECONDS_IN_SECOND;
var MINUTES_IN_HOUR = 60;
/* Formats the time in the H:MM format. */
function formatTime(time) {
var timeInMinutes = time / MILISECONDS_IN_MINUTE;
var hours = Math.floor(timeInMinutes / MINUTES_IN_HOUR);
var minutes = Math.floor(timeInMinutes - hours * MINUTES_IN_HOUR);
return String(hours).pad(2, "0") + ":" + String(minutes).pad(2, "0");
}
$("#timer_start_time,#timer_end_time").on('input',function(){
console.log($("#timer_start_date").val() +"T"+$("#timer_start_time").val()+":00Z")
console.log($("#timer_end_date").val()+"T"+$("#timer_end_time").val()+":00Z")
var start = Date.parse($("#timer_start_date").val() +"T"+$("#timer_start_time").val()+":00Z");
var end = Date.parse($("#timer_end_date").val()+"T"+$("#timer_end_time").val()+":00Z");
var diff = end - start;
$("#timer_duration").val(formatTime(diff))
})
{% endblock %}

View File

@@ -1,186 +0,0 @@
{% extends "base.html.twig" %}
{% block head_style %}
{{ encore_entry_link_tags('app') }}
{{ encore_entry_link_tags('fullcalendar') }}
{% endblock head_style %}
{% block localstyle %}
.fc-header-toolbar h2 {
text-transform: uppercase;
}
.fc-day-grid-event {
padding:0px;
border-radius:0px;
border: none;
}
.fc-content {
height: 40px;
}
.fc-title {
font-weight: bolder;
font-size: 12px;
}
.eventAvatar {
width: 20px;
margin: 0px 5px 0px 0px;
float: left;
}
.eventInfo{
margin: -5px 5px 0px 0px;
clear: both;
}
.eventUser{
clear: both;
}
.eventEstimate {
margin: -3px 10px;
}
{% endblock %}
{% block body %}
<div id="fullcalendar" style="width:100%; margin-top:10px;"></div>
{{ encore_entry_script_tags('fullcalendar') }}
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$("#modalsubmit #user").select2({
theme: 'bootstrap4',
language: "fr"
});
$("#modalsubmit #task").select2({
placeholder: "Selectionnez un projet",
allowClear: true,
theme: 'bootstrap4',
language: "fr"
});
$("#modalupdate #user").select2({
theme: 'bootstrap4',
language: "fr"
});
$("#modalupdate #task").select2({
placeholder: "Selectionnez un projet",
theme: 'bootstrap4',
language: "fr"
});
});
// Rendu d'un évenement
function eventRender(info) {
console.log(info.event.extendedProps);
// Récupération des divers élements du rendu event
var content=$(info.el).children('.fc-content');
var title=$(content).children('.fc-title');
// Ajouter l'avatar
content.prepend("<img src="+info.event.extendedProps.avatar+" class='eventAvatar'>");
content.append("<span class='eventUser float-left small'>"+info.event.extendedProps.username+"</span>");
var eventInfo=$(content).children('.eventUser');
// Ajout container
content.append("<span class='eventInfo float-right'></span>");
var eventInfo=$(content).children('.eventInfo');
// Ajouter le verrou si event non editable
if(info.event.extendedProps.locked) {
eventInfo.append("<i class='fa fa-lock float-right'></i>");
}
// Ajout estimation
eventInfo.append("<span class='eventEstimate float-right small'>"+info.event.extendedProps.estimate+"</span>");
// Description
content.attr("title",info.event.extendedProps.fulldescription);
}
// Formulaire Création d'un évelement
var allDay;
function eventSelect(selectionInfo) {
var start=moment(selectionInfo.start);
var end=moment(selectionInfo.end);
var end=end.subtract(1, 'd');
allDay=(start.format("DD/MM/YYYY") != end.format("DD/MM/YYYY"));
// Controle
if(start.month()!=end.month()) {
alert("Une tâche ne peut être sur deux mois différents");
return false;
}
if(start.week()!=end.week()) {
alert("Une tâche ne peut être sur deux semaines différentes");
return false;
}
// Valeur par défaut
{% if (is_granted('ROLE_ADMIN') or is_granted('ROLE_VALIDATOR') or is_granted('ROLE_MASTER')) and app.session.get('iduser')!="all" %}
$('#usersubmit').val({{app.session.get('iduser')}}).trigger("change");
{% else %}
$('#usersubmit').val({{app.user.id}}).trigger("change");
{% endif %}
// Si jour de fin un samedi ou un dimanche : on est forcement en astreinte
if(moment(end).day()==0||moment(end).day()==6) {
$("#modalsubmit #astreinte").prop("checked",true);
$("#modalsubmit #astreinte").attr("disabled",true);
allDay=true;
}
else {
$("#modalsubmit #astreinte").prop('checked', false);
$("#modalsubmit #astreinte").attr('disabled', false);
}
$('#modalsubmit #amsubmit').prop("checked",true);
$('#modalsubmit #apsubmit').prop("checked",true);
$('#modalsubmit #amsubmit').attr("disabled",allDay);
$('#modalsubmit #apsubmit').attr("disabled",allDay);
$('#modalsubmit #start').val(start.format("YYYY-MM-DD"));
$('#modalsubmit #end').val(end.format("YYYY-MM-DD"));
$('#modalsubmit #description').val("");
$("#modalsubmit .alert").remove();
// Formulaire de création d'un évènement
$('#modalsubmit').modal();
}
// On change astreinte
$("#astreinte").change(function() {
console.log(allDay)
if(this.checked) {
$("#amsubmit").prop("disabled",true);
$("#apsubmit").prop("disabled",true);
$('#modalsubmit #amsubmit').prop("checked",true);
$('#modalsubmit #apsubmit').prop("checked",true);
}
else {
$("#amsubmit").prop("disabled",allDay);
$("#apsubmit").prop("disabled",allDay);
$('#modalsubmit #amsubmit').prop("checked",true);
$('#modalsubmit #apsubmit').prop("checked",true);
}
});
{% endblock %}

View File

@@ -1,703 +0,0 @@
{% extends "base.html.twig" %}
{% block localstyle %}
#timer-task {
width:300px;
}
#timer-desc {
width:300px;
}
{% endblock %}
{% block body %}
<h1 class="page-header">
SUIVI HORAIRE
</h1>
<div id="timer" class="card">
<div class="card-header">
<a class="btn btn-success" style="float:right" href={{ path('app_timer_submit') }}>Créer un Timer</a>
Lancer un Timer :
<select class="select2entity" id="timer-task" name="timer-task">
<option> Tâche </option>
{% for task in tasks %}
<option value="{{task.id}}">{{task.displayname}}</option>
{% endfor %}
</select>
<input id="timer-desc" name="timer-desc" placeholder="Description" />
<a href='#' title='Add' id='addtimer'>
<i class='fas fa-plus-circle'></i>
</a>
</div>
</div>
<div>
<table id="task-table" class="table table-striped table-hover" >
</table>
</div>
<a class="btn btn-success" href={{ path('app_timer_view') }}>Voir le calendrier</a>
<p></p>
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
<thead>
<tr>
<th width="70px" class="no-sort">Tâche</th>
<th width="150px" class="no-sort">Description</th>
<th width="150px">Début</th>
<th width="100px">Fin</th>
<th width="100px">Durée</th>
<th width="100px" class="text-center no-string">Actions</th>
</tr>
</thead>
<tbody>
{%for timer in timers %}
<tr>
<td>{{ timer.task.displayname }}</td>
<td>
<span class="font-weight-bold">
{{ timer.activepenalty ? "<i class='fa fa-exclamation' style='color:red;opacity: 0.33;'></i> Astreinte active" : "" }}
</span>
<span class="font-weight-bold">
{{ timer.additionalhour ? "<i class='fa fa-exclamation-triangle' style='color:red;opacity: 0.33;'></i> Heures supplémentaires" : "" }}
</span>
<p>{{ timer.description }}</p>
</td>
<td>{{ timer.start|date("d/m/Y H:i") }}</td>
<td>{{ timer.end|date("d/m/Y H:i") }}</td>
<td>{{ timer.duration|date("H:i") }}</td>
<td>
<a href="{{path("app_timer_update",{id:timer.id})}}">
<i class="fa fa-file"></i>
</a>
&nbsp;&nbsp;
<a href="{{ path('app_timer_delete',{'id':timer.id}) }}"
data-method="delete"
data-confirm="Êtes-vous sûr de vouloir supprimer cet entregistrement ?">
<i class="fa fa-trash-alt"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block localjavascript %}
/* Creates a new Task object. */
function Task(id ,name, description) {
this._name = name;
this._taskid = id;
this._description = description;
this._state = Task.State.STOPPED;
this._timeSpentInPreviousIterations = 0;
this._startDate = 0;
this._endDate = 0;
this._currentIterationStartTime = 0;
this._customTimeSpent = 0;
this._onChange = null;
}
/* Possible task states. */
Task.State = {
STOPPED: "stopped",
RUNNING: "running"
}
Task.prototype = {
/* Returns the task name. */
getName: function() {
return this._name;
},
/* Returns the task description. */
getDescription: function() {
if (this._description == "NaN") {
this._description = ""
}
return this._description;
},
/* Returns the task state. */
getState: function() {
return this._state;
},
/* Is the task stopped? */
isStopped: function() {
return this._state == Task.State.STOPPED;
},
/* Is the task running? */
isRunning: function() {
return this._state == Task.State.RUNNING;
},
/*
* Sets the "onChange" event handler. The "onChange" event is fired when the
* task is started, stopped, or reset.
*/
setOnChange: function(onChange) {
this._onChange = onChange;
},
/*
* Returns the time spent on the task in the current work iteration. Works
* correctly only when the task is running.
*/
_getCurrentIterationTime: function() {
return (new Date).getTime() - this._currentIterationStartTime;
},
/*
* Returns the total time spent on the task. This includes time spent in
* the current work iteration if the task is running.
*/
getTimeSpent: function() {
var result = this._timeSpentInPreviousIterations;
if (this._state == Task.State.RUNNING) {
result += this._getCurrentIterationTime();
}
return result;
},
/* Calls the "onChange" event handler if set. */
_callOnChange: function() {
if (typeof this._onChange == "function") {
this._onChange();
}
},
/* Starts a new task work iteration. */
start: function() {
if (this._state == Task.State.RUNNING) { return };
if (this._startDate == 0) {this._startDate = new Date()}
this._state = Task.State.RUNNING;
this._currentIterationStartTime = (new Date).getTime();
this._callOnChange();
},
/* Stops the current task work iteration. */
stop: function() {
if (this._state == Task.State.STOPPED) { return };
this._state = Task.State.STOPPED;
this._timeSpentInPreviousIterations += this._getCurrentIterationTime();
this._currentIterationStartTime = 0;
this._endDate = new Date();
this._callOnChange();
},
/* Stops the current task work iteration and resets the time data. */
reset: function() {
this.stop();
this._timeSpentInPreviousIterations = 0;
this._callOnChange();
},
save: function(task){
console.log(task)
$.ajax({
type: "POST",
data: {
taskname: task._name,
taskid: task._taskid,
description: task._description,
start: task._startDate,
end: task._endDate,
duration: task._timeSpentInPreviousIterations,
},
url: "{{ path('app_timer_create') }}",
success: function (response) {
response=JSON.parse(response);
if(response.return=="KO") {
$("#dataTable_wrapper").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
}else{
location.reload();
}
}
});
},
/* Serializes the task into a string. */
serialize: function() {
/*
* Originally, I wanted to use "toSource" and "eval" for serialization and
* deserialization, but "toSource" is not supported by WebKit, so I resorted
* to ugly hackery...
*/
return [
encodeURIComponent(this._name),
this._state,
this._timeSpentInPreviousIterations,
this._currentIterationStartTime,
this._startDate,
this._endDate,
this._taskid,
this._description,
].join("&");
},
/* Deserializes the task from a string. */
deserialize: function(serialized) {
var parts = serialized.split("&");
this._name = decodeURIComponent(parts[0]);
this._state = parts[1];
this._timeSpentInPreviousIterations = parseInt(parts[2]);
this._currentIterationStartTime = parseInt(parts[3]);
this._startDate = parseInt(parts[4]);
this._endDate = parseInt(parts[5]);
this._taskid = parseInt(parts[6]);
this._description = parseInt(parts[7]);
}
}
/* ===== Tasks ===== */
/* The Tasks class represents a list of tasks. */
/* Creates a new Tasks object. */
function Tasks() {
this._tasks = [];
this._onAdd = null;
this._onRemove = null;
}
Tasks.prototype = {
/*
* Sets the "onAdd" event handler. The "onAdd" event is fired when a task
* is added to the list.
*/
setOnAdd: function(onAdd) {
this._onAdd = onAdd;
},
/*
* Sets the "onRemove" event handler. The "onRemove" event is fired when a
* task is removed from the list.
*/
setOnRemove: function(onRemove) {
this._onRemove = onRemove;
},
/* Returns the length of the task list. */
length: function() {
return this._tasks.length
},
/*
* Returns index-th task in the list, or "undefined" if the index is out of
* bounds.
*/
get: function(index) {
return this._tasks[index];
},
/*
* Calls the callback function for each task in the list. The function is
* called with three parameters - the task, its index and the task list
* object. This is modeled after "Array.forEach" in JavaScript 1.6.
*/
forEach: function(callback) {
for (var i = 0; i < this._tasks.length; i++) {
callback(this._tasks[i], i, this);
}
},
/* Calls the "onAdd" event handler if set. */
_callOnAdd: function(task) {
if (typeof this._onAdd == "function") {
this._onAdd(task);
}
},
/* Adds a new task to the end of the list. */
add: function(task) {
this._tasks.push(task);
this._callOnAdd(task);
},
/* Calls the "onRemove" event handler if set. */
_callOnRemove: function(index) {
if (typeof this._onRemove == "function") {
this._onRemove(index);
}
},
/*
* Removes index-th task from the list. Does not do anything if the index
* is out of bounds.
*/
remove: function(index) {
this._callOnRemove(index);
this._tasks.splice(index, 1);
},
/* Serializes the list of tasks into a string. */
serialize: function() {
var serializedTasks = [];
this.forEach(function(task) {
serializedTasks.push(task.serialize());
});
return serializedTasks.join("|");
},
/* Deserializes the list of tasks from a string. */
deserialize: function(serialized) {
/*
* Repeatedly use "remove" so the "onRemove" event is triggered. Do the same
* with the "add" method below.
*/
while (this._tasks.length > 0) {
this.remove(0);
}
var serializedTasks = serialized.split("|");
for (var i = 0; i < serializedTasks.length; i++) {
var task = new Task(0 ,"", "");
task.deserialize(serializedTasks[i]);
this.add(task);
}
}
}
/* ===== Extensions ===== */
/*
* Pads this string with another string on the left until the resulting string
* has specified length. If the padding string has more than one character, the
* resulting string may be longer than desired (the padding string is not
* truncated and it is only prepended as a whole). Bad API, I know, but it's
* good enough for me.
*/
String.prototype.pad = function(length, padding) {
var result = this;
while (result.length < length) {
result = padding + result;
}
return result;
}
/* ===== Task List + DOM Storage ===== */
/* The list of tasks. */
var tasks = new Tasks();
/* The last value of the serialized task list string. */
var lastSerializedTasksString;
/*
* The key under which the serialized task list string is stored in the DOM
* Storage.
*/
var TASKS_DOM_STORAGE_KEY = "timerTasks";
/*
* Returns DOM Storage used by the application, or "null" if the browser does
* not support DOM Storage.
*/
function getStorage() {
/*
* HTML 5 says that the persistent storage is available in the
* "window.localStorage" attribute, however Firefox implements older version
* of the proposal, which uses "window.globalStorage" indexed by the domain
* name. We deal with this situation here as gracefully as possible (i.e.
* without concrete browser detection and with forward compatibility).
*
* For more information, see:
*
* http://www.whatwg.org/specs/web-apps/current-work/#storage
* https://developer.mozilla.org/En/DOM/Storage
*/
if (window.localStorage !== undefined) {
return window.localStorage;
} else if (window.globalStorage !== undefined) {
return window.globalStorage[location.hostname];
} else {
return null;
}
}
/*
* Saves the task list into a DOM Storage. Also updates the value of the
* "lastSerializedTasksString" variable.
*/
function saveTasks() {
var serializedTasksString = tasks.serialize();
getStorage()[TASKS_DOM_STORAGE_KEY] = serializedTasksString;
lastSerializedTasksString = serializedTasksString;
}
/*
* Loads the serialized task list string from the DOM Storage. Returns
* "undefined" if the storage does not contain the string (this happens when
* running the application for the first time).
*/
function loadSerializedTasksString() {
var storedValue = getStorage()[TASKS_DOM_STORAGE_KEY];
/*
* The spec says "null" should be returned when the key is not found, but some
* browsers return "undefined" instead. Maybe it was in some earlier version
* of the spec (I didn't bother to check).
*/
if (storedValue !== null && storedValue !== undefined && storedValue.length > 0) {
/*
* The values retrieved from "globalStorage" use one more level of
* indirection.
*/
return (window.localStorage === undefined) ? storedValue.value : storedValue;
} else {
return undefined;
}
}
/*
* Loads the task list from the DOM Storage. Also updates the value of the
* "lastSerializedTasksString" variable.
*/
function loadTasks() {
var serializedTasksString = loadSerializedTasksString();
if (serializedTasksString !== undefined) {
tasks.deserialize(serializedTasksString);
lastSerializedTasksString = serializedTasksString;
}
}
/*
* Was the task list changed outside of the application? Detects the change
* by comparing the current serialized task list string in the DOM Storage
* with a kept old value.
*/
function tasksHaveChangedOutsideApplication() {
var serializedTasksString = loadSerializedTasksString();
if (serializedTasksString != lastSerializedTasksString) {
return true
}
return false;
}
/* ===== View ===== */
/* Some time constants. */
var MILISECONDS_IN_SECOND = 1000;
var MILISECONDS_IN_MINUTE = 60 * MILISECONDS_IN_SECOND;
var MINUTES_IN_HOUR = 60;
/* Formats the time in the H:MM format. */
function formatTime(time) {
var timeInMinutes = time / MILISECONDS_IN_MINUTE;
var hours = Math.floor(timeInMinutes / MINUTES_IN_HOUR);
var minutes = Math.floor(timeInMinutes - hours * MINUTES_IN_HOUR);
return hours + ":" + String(minutes).pad(2, "0");
}
/*
* Computes the URL of the image in the start/stop link according to the task
* state.
*/
function computeStartStopLinkImageUrl(state) {
switch (state) {
case Task.State.STOPPED:
return "fa-play";
case Task.State.RUNNING:
return "fa-stop";
default:
throw "Invalid task state."
}
}
/*
* Builds the HTML element of the row in the task table corresponding to the
* specified task and index.
*/
function buildTaskRow(task, index) {
var result = $("<tr />");
var startStopLink = $(
"<a href='#' class='start-stop-link' title='Start/stop'>"
+ "<i class='fa " + computeStartStopLinkImageUrl(task.getState()) + "'></i>"
);
startStopLink.click(function() {
switch (task.getState()) {
case Task.State.STOPPED:
task.start();
break;
case Task.State.RUNNING:
task.stop();
break;
default:
throw "Invalid task state."
}
saveTasks();
return false;
});
var resetLink = $(
"<a href='#' title='Reset'>"
+ "<i class='fa fa-undo'></i>"
);
resetLink.click(function() {
task.reset();
saveTasks();
return false;
});
var deleteLink = $(
"<a href='#' title='Delete' class='deletetask'>"
+ "<i class='fa fa-trash-alt' class='deletetask'></i>"
);
deleteLink.click(function() {
if (confirm("Do you really want to delete task \"" + task.getName() + "\"?")) {
tasks.remove(index);
saveTasks();
}
return false;
});
var saveLink = $(
"<a href='#' title='Save' class='savetask'>"
+ "<i class='fa fa-download' class='savetask'></i>"
);
saveLink.click(function() {
tasks.remove(index);
saveTasks();
task.save(task);
return false;
});
result
.addClass("state-" + task.getState())
.append($("<td class='task-name' />").text(task.getName()))
.append($("<td class='task-description' />").text(task.getDescription()))
.append($("<td class='task-time' />").text(formatTime(task.getTimeSpent())))
.append($("<td class='task-actions' />")
.append(startStopLink)
.append("&nbsp;&nbsp;")
.append(resetLink)
.append("&nbsp;&nbsp;")
.append(saveLink)
.append("&nbsp;&nbsp;&nbsp;&nbsp;")
.append(deleteLink)
);
return result;
}
/* Finds row with the specified index in the task table. */
function findRowWithIndex(index) {
return $("#task-table").find("tr").slice(1).eq(index);
}
/*
* Updates the row in the task table corresponding to a task according to
* its state.
*/
function updateTaskRow(row, task) {
if (task.isStopped()) {
row.removeClass("state-running");
row.addClass("state-stopped");
} else if (task.isRunning()) {
row.removeClass("state-stopped");
row.addClass("state-running");
}
row.find(".task-time").text(formatTime(task.getTimeSpent()))
row.find(".start-stop-link i").removeClass();
row.find(".start-stop-link i").addClass("fa "+computeStartStopLinkImageUrl(task.getState()));
}
/* ===== Initialization ===== */
/* Initializes event handlers on the task list. */
function initializeTasksEventHandlers() {
tasks.setOnAdd(function(task) {
var row = buildTaskRow(task, tasks.length() - 1);
$("#task-table").append(row);
task.setOnChange(function() {
updateTaskRow(row, task);
});
});
tasks.setOnRemove(function(index) {
findRowWithIndex(index).remove();
if (tasks.length() == 1 ) {
$( "#task-table" ).css({"display":"none"});
}
});
}
/* Initializes GUI event handlers. */
function initializeGuiEventHandlers() {
$( "#addtimer" ).click(function() {
displayTaskAdd();
});
$( "#timer-desc" ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
displayTaskAdd();
}
});
}
function displayTaskAdd() {
$( "#task-table" ).css({"display":"inline"});
var taskName = $("#timer-task option:selected").text();
var taskId = $("#timer-task option:selected").val();
var taskDesc = $("#timer-desc").val();
var task = new Task(taskId, taskName, taskDesc);
tasks.add(task);
saveTasks();
$("#timer-desc").val("");
}
/*
* Initializes a timer used to update task times and detect changes in the
* data stored in the DOM Storage.
*/
function initializeTimer() {
setInterval(function() {
tasks.forEach(function(task, index) {
updateTaskRow(findRowWithIndex(index), task);
});
if (tasksHaveChangedOutsideApplication()) {
loadTasks();
}
}, 10 * MILISECONDS_IN_SECOND);
}
/* Initializes the application. */
$(document).ready(function(){
try {
if (!getStorage()) {
alert("Timer requires a browser with DOM Storage support, such as Firefox 3+ or Safari 4+.");
return;
}
} catch (e) {
alert("Timer does not work with file: URLs in Firefox.");
return;
}
initializeTasksEventHandlers();
loadTasks();
initializeGuiEventHandlers();
initializeTimer();
});
{% endblock %}

View File

@@ -94,33 +94,7 @@
{{ form_row(form.roles) }} {{ form_row(form.roles) }}
{%endif%} {%endif%}
</div> </div>
</div> </div>
<p></p>
<div class="card">
<div class="card-header">
<i class="fas fa-list-ul"></i> Affectations
</div>
<div class="card-body">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th>Projet</th>
<th>Rôle</th>
</tr>
</thead>
<tbody>
{% for userproject in user.userprojects %}
<tr>
<td>{{userproject.project.displayname}}</td>
<td>{{userproject.job.name}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
{{ form_end(form) }} {{ form_end(form) }}

View File

@@ -68,7 +68,6 @@
<table> <table>
<thead> <thead>
<th class="no-print"></th> <th class="no-print"></th>
<th>S</th>
<th>L</th> <th>L</th>
<th>M</th> <th>M</th>
<th>M</th> <th>M</th>
@@ -90,7 +89,6 @@
{% set btnvalidate=true %} {% set btnvalidate=true %}
{%endif%} {%endif%}
</td> </td>
<td class="date" style="vertical-align:middle">{{event.date|date("W")}}</td>
{% endif %} {% endif %}
<td> <td>

View File

@@ -1,163 +0,0 @@
{% extends "base.html.twig" %}
{% block localstyle %}
{% if fgprint is defined and fgprint %}
table { font-size:10px;}
th,td {
border: 1px solid #37474F;
}
thead {
display: table-header-group;
}
tr { page-break-inside: avoid; }
.homecard {width: 100% }
{%endif%}
{% endblock %}
{% block body %}
<h1 class="page-header">
VALIDATION HORAIRES
</h1>
<div class="custom-control custom-switch float-right">
<input type="checkbox" class="custom-control-input" id="switchactive" {% if app.session.get('activetimer') %} checked {% endif %}>
<label class="custom-control-label" for="switchactive">Horaires à Valider</label>
</div>
<div style="height:30px;">
</div>
<div class="card homecard">
<div class="card-header">
{% if not app.session.get('activetimer') %}
Horaires à Dévalider
{% else %}
Horaires à Valider
{% endif %}
</div>
<div class="card-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
<thead>
<th class="no-print"></th>
<th width="150px">Utilisateur</th>
<th>Tâche</th>
<th>Description</th>
<th>Début</th>
<th>Fin</th>
<th>Durée</th>
</thead>
{% for user in users %}
{% for timer in user.timers %}
<tr id="row-{{timer.id}}">
<td class="no-print" style="vertical-align:middle">
{% if timer.validate %}
<i class="fa fa-thumbs-down validate-{{user.user.id}}" onClick="devalidate({{timer.id}})" style="cursor:pointer; color:red;"></i>
{% else %}
<i class="fa fa-thumbs-up validate-{{user.user.id}}" onClick="validate({{timer.id}})" style="cursor:pointer; color:green;"></i>
{% endif %}
</td>
<td>
{{ user.user.displayname }}
</td>
<td>
{{ timer.taskname }}
</td>
<td>
<span class="font-weight-bold">
{{ timer.activepenalty ? "<i class='fa fa-exclamation' style='color:red;opacity: 0.33;'></i> Astreinte active" : "" }}
</span>
<span class="font-weight-bold">
{{ timer.additionalhour ? "<i class='fa fa-exclamation-triangle' style='color:red;opacity: 0.33;'></i> Heures supplémentaires" : "" }}
</span>
<p>{{ timer.description }}</p>
</td>
<td>
{{ timer.start|date("d/m/Y H:i") }}
</td>
<td>
{{ timer.end|date("d/m/Y H:i") }}
</td>
<td>
{{ timer.duration|date("H:i") }}
</td>
</tr>
{% endfor %}
{% endfor %}
</table>
</div>
</div>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
{% if not fgprint is defined or not fgprint %}
$('.table ').DataTable({
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
responsive: true,
iDisplayLength: 100,
order: [[ 1, "asc" ]]
});
{%else%}
$('#dataTables').removeClass("table table-striped table-bordered table-hover small dataTable no-footer");
{% endif %}
});
function myprint() {
href=document.location.href;
document.location.href=href+"?fgprint=true";
}
function validate(id) {
$.ajax({
type: "POST",
data: {
id: id,
},
url: "{{ path('app_validationtimer_validate') }}",
success: function (response) {
response=JSON.parse(response);
if(response.return=="KO") {
alert(response.error);
}
else {
$("#row-"+id).remove();
}
}
});
}
function devalidate(id) {
$.ajax({
type: "POST",
data: {
id: id,
},
url: "{{ path('app_validationtimer_devalidate') }}",
success: function (response) {
response=JSON.parse(response);
if(response.return=="KO") {
alert(response.error);
}
else {
$("#row-"+id).remove();
}
}
});
}
$('#switchactive').change(function() {
window.location="{{ path('app_validationtimer_activetimer' )}}";
});
{% endblock %}

View File

@@ -256,7 +256,7 @@
{% set contentsidebar="contentsidebar" %} {% set contentsidebar="contentsidebar" %}
<div id="sidebar" class="collapse"> <div id="sidebar" class="collapse">
<ul style="padding-bottom:70px" class="nav"> <ul class="nav">
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_VALIDATOR') or is_granted('ROLE_MASTER') or is_granted('ROLE_USER') %} {% if is_granted('ROLE_ADMIN') or is_granted('ROLE_VALIDATOR') or is_granted('ROLE_MASTER') or is_granted('ROLE_USER') %}
<p></p> <p></p>
<li> <li>
@@ -284,20 +284,12 @@
</label> </label>
</a> </a>
<div class="select-control"> <div class="select-control">
<select class="form-control select2entity" id="sideuser" name="sideuser" multiple> <select class="form-control select2entity" id="sideuser" name="sideuser">
<option value="all" {%if app.session.get('iduser')=="all" %}selected{% endif %}>Tout le monde</option> <option value="all" selected>Tout le monde</option>
{% for user in app.session.get('users') %} {% for user in app.session.get('users') %}
{% set selected="" %} {% set selected="" %}
{% if app.session.get('selectedusers')|length > 1 %} {%if user.id==app.session.get('iduser') %}
{% for suser in app.session.get('selectedusers') %} {% set selected="selected" %}
{%if user.id == suser %}
{% set selected="selected" %}
{% endif %}
{% endfor %}
{% else %}
{%if user.id==app.session.get('iduser') %}
{% set selected="selected" %}
{% endif %}
{% endif %} {% endif %}
<option value="{{user.id}}" {{selected}}>{{user.displayname}}</option> <option value="{{user.id}}" {{selected}}>{{user.displayname}}</option>
{% endfor %} {% endfor %}
@@ -367,21 +359,9 @@
</a> </a>
</li> </li>
<li> <li class="last">
<a href="{{path("app_timer")}}">
<i class="fa fa-stopwatch"></i>Suivi Horaire
</a>
</li>
<li>
<a href="{{path("app_holiday")}}"> <a href="{{path("app_holiday")}}">
<i class="fa fa-umbrella-beach"></i>Mes Congés <i class="fa fa-cocktail"></i>Mes Congés
</a>
</li>
<li class="last">
<a href="{{path("app_export_view")}}">
<i class="fa fa-file-download"></i>Exports
</a> </a>
</li> </li>
@@ -392,21 +372,15 @@
<li> <li>
<a href="{{path("app_validation")}}"> <a href="{{path("app_validation")}}">
<i class="fa fa-user-check"></i>Validation Calendrier <i class="fa fa-user"></i>Validation
</a>
</li>
<li>
<a href="{{path("app_validationholiday")}}">
<i class="fa fa-user-tag"></i>Validation Congés
</a> </a>
</li> </li>
<li class="last"> <li class="last">
<a href="{{path("app_validationtimer")}}"> <a href="{{path("app_validationholiday")}}">
<i class="fa fa-user-clock"></i>Validation Horaires <i class="fa fa-suitcase"></i>Validation Congés
</a> </a>
</li> </li>
{% endif %} {% endif %}
@@ -427,7 +401,7 @@
<li> <li>
<a href="{{path("app_offer")}}"> <a href="{{path("app_offer")}}">
<i class="fa fa-euro-sign"></i>Commandes <i class="fa fa-euro-sign"></i>Propositions
</a> </a>
</li> </li>
@@ -520,13 +494,10 @@
$('#sideuser').on('select2:select', function (e) { $('#sideuser').on('select2:select', function (e) {
var data = e.params.data; var data = e.params.data;
var selectedusers = $('#sideuser').val();
console.log(selectedusers)
$.ajax({ $.ajax({
type: "POST", type: "POST",
data: { data: {
iduser: data.id, iduser: data.id,
selectedusers: selectedusers,
}, },
url: "{{ path('app_home_selectuser') }}", url: "{{ path('app_home_selectuser') }}",
success: function (response) { success: function (response) {

View File

@@ -4,12 +4,6 @@ APP_SECRET=%%pwdreader("","/var/www/html/schedule/.key")
APP_AUTH=CAS APP_AUTH=CAS
# MAIL sendmail / smtp
MAILER_METHOD=sendmail
MAILER_URL=
MAILER_NOREPLY=noreply@noreply.fr
MAILER_DEFAULT_NOTIF=%%getVar('schedule_email_global_notif', '')
# Bdd = Redefine local # Bdd = Redefine local
DATABASE_NAME=schedule DATABASE_NAME=schedule
DATABASE_USER=schedule DATABASE_USER=schedule