Compare commits

...

31 Commits

Author SHA1 Message Date
00a55a9e67 Merge branch 'master' into dist/eole/2.7.2/master 2021-03-08 10:26:07 +01:00
7ebdf9ba53 Correction Problème au niveau des astreintes #65 2021-03-08 10:23:23 +01:00
349f5c26e7 Merge branch 'master' into dist/eole/2.7.2/master 2021-03-05 14:29:21 +01:00
01f56289b4 update route app_event_load parameter 2021-03-05 14:19:57 +01:00
18d993f307 Merge branch 'master' into dist/eole/2.7.2/master 2021-03-05 10:24:51 +01:00
94fa9d1f0b switch task inactives ref #61 2021-03-04 10:17:13 +01:00
5343d61401 correction mise en page rapport pdf ref #58 2021-03-04 09:26:18 +01:00
6bd189271f correction fermeture div dans rapport ref #57 2021-03-04 09:18:17 +01:00
f8b4d0446d Merge branch 'master' into dist/eole/2.7.2/master 2021-03-03 16:16:59 +01:00
ce10df9293 Correction affichage calendrier sélectionné ref #60 2021-03-03 16:10:48 +01:00
b14fc3d0e1 Merge branch 'master' into dist/eole/2.7.2/master 2021-03-03 14:55:03 +01:00
164da2ee48 correction on planing 2021-03-03 14:51:22 +01:00
1fec858f01 suppression trace de debug 2021-02-04 17:05:39 +01:00
697c7a8f1c Merge branch 'dist/eole/2.7.2/master' of https://forge.cadoles.com/Cadoles/schedule into dist/eole/2.7.2/master 2021-02-04 16:17:23 +01:00
24ecd6c87e Merge branch 'master' into dist/eole/2.7.2/master 2021-02-04 16:17:18 +01:00
6acf427696 correctif sur autosubmit des users 2021-02-04 16:13:35 +01:00
b17024cccd Merge branch 'master' into dist/eole/2.7.2/master 2021-01-28 12:15:43 +01:00
cdb2537d3f update migration script 2020-12-17 11:04:01 +01:00
2ba143e5a2 Ajout notion de tâche active, et affichage uniquement des taches active lors de la création d'événements #55 2020-12-17 10:53:52 +01:00
5037b0945e ajout export jours facturés #56 2020-12-16 16:40:15 +01:00
a0b87b907f Merge branch 'master' into dist/eole/2.7.2/master 2020-11-13 10:20:38 +01:00
c31d14bff4 mise à niveau des fichiers d'environnement 2020-11-13 10:20:05 +01:00
dfa5a993ce Merge branch 'master' into dist/eole/2.7.2/master 2020-11-13 09:30:06 +01:00
91536ed930 update dico description 2020-11-06 15:25:29 +01:00
10cb25730b Merge branch 'api_dolibarr' of Cadoles/schedule into master 2020-11-03 09:55:46 +01:00
937ec6f4ca Merge branch 'master' into dist/eole/2.7.2/master 2020-09-29 08:58:50 +02:00
7e988ff7a9 Merge branch 'master' into dist/eole/2.7.0/master 2020-09-23 09:15:06 +02:00
c66962097d Merge branch 'master' into dist/eole/2.7.0/master 2020-09-22 14:32:26 +02:00
db11d66ae0 Merge branch 'master' into dist/eole/2.7.0/master 2020-05-13 14:06:01 +02:00
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
33 changed files with 386 additions and 150 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

@@ -34,8 +34,8 @@
<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='string' name='schedule_email_global_notif' description='URL de connexion au serveur smtp'/> <variable type='string' name='schedule_email_url' description='URL de connexion au serveur smtp'/>
<variable type='string' name='schedule_email_url' description='Email pour envoie de notifications'/> <variable type='string' name='schedule_email_global_notif' description='Email pour envoie de notifications'/>
<variable type='string' name="schedule_office_hour_start" description="Heure de début d'une journée"> <variable type='string' name="schedule_office_hour_start" description="Heure de début d'une journée">
<value>09:00</value> <value>09:00</value>
</variable> </variable>

View File

@@ -57,15 +57,10 @@ 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=
## Sentry DSN ## Sentry DSN
SENTRY_DSN= SENTRY_DSN=
# Dolibar
DOLIBARR_ACTIVE=false DOLIBARR_ACTIVE=false
DOLIBARR_API_KEY= DOLIBARR_API_KEY=
DOLIBARR_URI= DOLIBARR_URI=

View File

@@ -9,6 +9,8 @@ import interactionPlugin from '@fullcalendar/interaction';
import dayGridPlugin from '@fullcalendar/daygrid'; import dayGridPlugin from '@fullcalendar/daygrid';
var calendar; var calendar;
var e = document.getElementById("sideuser");
var iduser = e.value;
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('fullcalendar'); var calendarEl = document.getElementById('fullcalendar');
calendar = new Calendar(calendarEl, { calendar = new Calendar(calendarEl, {
@@ -16,7 +18,7 @@ document.addEventListener('DOMContentLoaded', function() {
locale: frLocale, locale: frLocale,
weekNumbers: true, weekNumbers: true,
selectable: true, selectable: true,
events: 'event/load', events: 'event/load/'+iduser,
eventLimit:8, eventLimit:8,
eventDrop: function(info) { eventDrop: function(info) {
info.revert(); info.revert();

View File

@@ -262,13 +262,17 @@ app_task_activeproject:
path: /master/task/activeproject path: /master/task/activeproject
defaults: { _controller: App\Controller\TaskController:activeproject } defaults: { _controller: App\Controller\TaskController:activeproject }
app_task_activetask:
path: /master/task/activetask
defaults: { _controller: App\Controller\TaskController:activetask }
#== Event ==================================================================================================== #== Event ====================================================================================================
app_event: app_event:
path: /user/event path: /user/event
defaults: { _controller: App\Controller\EventController:list } defaults: { _controller: App\Controller\EventController:list }
app_event_load: app_event_load:
path: /user/event/load path: /user/event/load/{iduser}
defaults: { _controller: App\Controller\EventController:load } defaults: { _controller: App\Controller\EventController:load }
app_event_submit: app_event_submit:
@@ -399,6 +403,10 @@ app_timer_delete:
#== Customer ====================================================================================================== #== Customer ======================================================================================================
app_customer_home:
path: /customer
defaults: { _controller: App\Controller\HomeController:customer }
app_customer_report: app_customer_report:
path: /customer/report/{key} path: /customer/report/{key}
defaults: { _controller: App\Controller\ReportController:report, access: 'customer' } defaults: { _controller: App\Controller\ReportController:report, access: 'customer' }
@@ -428,6 +436,10 @@ export_offers:
path: /export/export_offers path: /export/export_offers
defaults: { _controller: App\Controller\ExportController:export_offers } defaults: { _controller: App\Controller\ExportController:export_offers }
export_month_charged_days:
path: /export/export_month_charged_days
defaults: { _controller: App\Controller\ExportController:export_month_charged_days }
#== Export ====================================================================================================== #== Export ======================================================================================================
app_stat_view: app_stat_view:

View File

@@ -36,6 +36,8 @@ __webpack_require__(/*! @fullcalendar/daygrid/main.css */ "./node_modules/@fullc
var calendar; var calendar;
var e = document.getElementById("sideuser");
var iduser = e.value;
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
var calendarEl = document.getElementById('fullcalendar'); var calendarEl = document.getElementById('fullcalendar');
calendar = new _fullcalendar_core__WEBPACK_IMPORTED_MODULE_3__["Calendar"](calendarEl, { calendar = new _fullcalendar_core__WEBPACK_IMPORTED_MODULE_3__["Calendar"](calendarEl, {
@@ -43,7 +45,7 @@ document.addEventListener('DOMContentLoaded', function () {
locale: _fullcalendar_core_locales_fr_js__WEBPACK_IMPORTED_MODULE_4___default.a, locale: _fullcalendar_core_locales_fr_js__WEBPACK_IMPORTED_MODULE_4___default.a,
weekNumbers: true, weekNumbers: true,
selectable: true, selectable: true,
events: 'event/load', events: 'event/load/'+iduser,
eventLimit: 8, eventLimit: 8,
eventDrop: function eventDrop(info) { eventDrop: function eventDrop(info) {
info.revert(); info.revert();

View File

@@ -20,10 +20,7 @@ APP_SECRET=52c1cb88ee822cd2643abe29e16a68a6
###< symfony/framework-bundle ### ###< symfony/framework-bundle ###
###> symfony/mailer ### ###> symfony/mailer ###
MAILER_METHOD=sendmail # MAILER_DSN=smtp://localhost
MAILER_URL=
MAILER_NOREPLY=noreply@noreply.fr
MAILER_DEFAULT_NOTIF=
###< symfony/mailer ### ###< symfony/mailer ###
###< doctrine/doctrine-bundle ### ###< doctrine/doctrine-bundle ###
@@ -35,6 +32,16 @@ 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=
@@ -45,14 +52,15 @@ DATABASE_HOST=
CAS_HOST= CAS_HOST=
CAS_PORT= CAS_PORT=
CAS_PATH= CAS_PATH=
CAS_USERNAME=username
OFFICE_HOUR_START=09:00 CAS_EMAIL=email
OFFICE_HOUR_END=17:30 CAS_LASTNAME=lastname
CAS_FIRSTNAME=firstname
## Sentry DSN ## Sentry DSN
SENTRY_DSN= SENTRY_DSN=
## Dolibarr # Dolibar
DOLIBARR_ACTIVE=false DOLIBARR_ACTIVE=false
DOLIBARR_API_KEY= DOLIBARR_API_KEY=
DOLIBARR_URI= DOLIBARR_URI=

View File

@@ -174,10 +174,10 @@ while($row=$queryold->fetch()) {
$nature=$row["task_nature"]; $nature=$row["task_nature"];
if($row["task_id"]<=-70) $nature=-200; if($row["task_id"]<=-70) $nature=-200;
if($row["task_id"]==-85 || $row["task_id"]==-70) $nature=-190; if($row["task_id"]==-85 || $row["task_id"]==-70) $nature=-190;
$q="INSERT IGNORE INTO task (id, name, color, quantity, validate, project_id, nature_id ) VALUES (?,?,?,?,?,?,?)"; $q="INSERT IGNORE INTO task (id, name, color, quantity, validate, project_id, nature_id, active) VALUES (?,?,?,?,?,?,?,?)";
$quantity=($row["task_quantity"]==0?null:$row["task_quantity"]); $quantity=($row["task_quantity"]==0?null:$row["task_quantity"]);
$query=$bddnew->prepare($q); $query=$bddnew->prepare($q);
$query->execute([$row["task_id"],$row["task_name"],"#".$row["task_color"],$quantity,$row["task_validate"],$row["task_project"],$nature ]); $query->execute([$row["task_id"],$row["task_name"],"#".$row["task_color"],$quantity,$row["task_validate"],$row["task_project"],$nature, 1]);
} }
writeligne(""); writeligne("");

View File

@@ -38,13 +38,13 @@ class EventController extends AbstractController
]); ]);
} }
public function load(Request $request) public function load($iduser, Request $request)
{ {
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
$tbevents=[]; $tbevents=[];
$start = $request->query->get('start'); $start = $request->query->get('start');
$end = $request->query->get('end'); $end = $request->query->get('end');
$iduser=$this->get("session")->get("iduser"); //$iduser=$this->get("session")->get("iduser");
// Evenements // Evenements
if($iduser=="all") { if($iduser=="all") {
$events=$em->getRepository("App:Event")->findAll(); $events=$em->getRepository("App:Event")->findAll();
@@ -492,7 +492,8 @@ class EventController extends AbstractController
} }
public function formatEvent($event) { public function formatEvent($event) {
$editable=(!($event->getValidate())&&!($event->getValidateholiday())); $event instanceof Penalty ? $editable=(!($event->getValidate())) : ($editable=(!($event->getValidate())&&!($event->getValidateholiday())));
// Si l'utilisateur en cours est différent de celui de l'event = seul MASTER - ADMIN peuvent modifier // Si l'utilisateur en cours est différent de celui de l'event = seul MASTER - ADMIN peuvent modifier
if($event->getUser()!=$this->getUser()) { if($event->getUser()!=$this->getUser()) {
@@ -522,7 +523,7 @@ class EventController extends AbstractController
"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()->getNature()->getIsvacation() ? $event->getTask()->getDuration($event->getEnd())." / ".$event->getTask()->getQuantity(): "", "estimate" => !$event->getTask()->getNature()->getIsvacation() ? $event->getTask()->getDuration($event->getEnd())." / ".$event->getTask()->getQuantity(): "",
"locked" => $event->getValidate()||$event->getValidateholiday(), "locked" => ($event instanceof Penalty?$event->getValidate():$event->getValidate()||$event->getValidateholiday()),
"editable" => $editable, "editable" => $editable,
"astreinte" => ($event instanceof Penalty) "astreinte" => ($event instanceof Penalty)
] ]

View File

@@ -473,5 +473,58 @@ class ExportController extends AbstractController
return $response; return $response;
} }
public function export_month_charged_days(Request $request,$access=null): Response {
$em = $this->getDoctrine()->getManager();
$nbmonth=$this->get("session")->get("nbmonth");
$tbevents=[];
// On formate le tableau des event
$start=new \Datetime('first day of this month');
$start->sub(new \DateInterval('P'.$nbmonth.'M'));
$start->setTime(0,0,0);
$end = new \Datetime('first day of this month');
$end->add(new \DateInterval('P1M'));
$end->setTime(23,59,0);
$events = $em
->createQueryBuilder('event')
->select('event')
->from('App:Event','event')
->Where('event.start>=:start AND event.end <:end')
->setParameter('start',$start)
->setParameter('end',$end)
->getQuery()->getResult();
foreach($events as $event) {
if (!isset($tbevents[$event->getStart()->format("m")])) {
$tbevents[$event->getStart()->format("m")]["f"]=0;
$tbevents[$event->getStart()->format("m")]["nf"]=0;
}
if ($event->getTask()->getNature()->getName() == "Prestation") {
if (!isset($tbevents[$event->getStart()->format("m")])){
$tbevents[$event->getStart()->format("m")]['f'] = $event->getDuration();
}else{
$tbevents[$event->getStart()->format("m")]['f'] += $event->getDuration();
}
}
if ($event->getTask()->getNature()->getName() != "Prestation") {
if (!isset($tbevents[$event->getStart()->format("m")])){
$tbevents[$event->getStart()->format("m")]['nf'] = $event->getDuration();
}else{
$tbevents[$event->getStart()->format("m")]['nf'] += $event->getDuration();
}
}
}
$csv = $this->renderView('Export/export_month_charged_days.csv.twig', ["events" => $tbevents]);
$response = new Response($csv);
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="export_month_charged_days.csv"');
return $response;
}
} }

View File

@@ -25,6 +25,14 @@ class HomeController extends AbstractController
*/ */
} }
public function customer()
{
return $this->render('Home/customer.html.twig',[
"useheader" => true,
"usesidebar" => false,
]);
}
public function selectmonth(Request $request) public function selectmonth(Request $request)
{ {
$nbmonth = $request->request->get('nbmonth'); $nbmonth = $request->request->get('nbmonth');

View File

@@ -255,9 +255,11 @@ class ReportController extends AbstractController
// Ne pas prendre les projects sans event dans la durée // Ne pas prendre les projects sans event dans la durée
$start=new \Datetime('first day of this month'); $start=new \Datetime('first day of this month');
$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);
$events = $em $events = $em
->createQueryBuilder('event') ->createQueryBuilder('event')
->select('event') ->select('event')
@@ -291,9 +293,11 @@ class ReportController extends AbstractController
// Formater les mois // Formater les mois
$start=new \Datetime('first day of this month'); $start=new \Datetime('first day of this month');
$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"),
@@ -323,7 +327,7 @@ class ReportController extends AbstractController
->from('App:Event','event') ->from('App:Event','event')
->Where('task.project=:project') ->Where('task.project=:project')
->andWhere('event.task=task') ->andWhere('event.task=task')
->andWhere('event.end >=:start') ->andWhere('event.start >=:start')
->andWhere('event.end <:end') ->andWhere('event.end <:end')
->setParameter('project',$project) ->setParameter('project',$project)
->setParameter('start',$start) ->setParameter('start',$start)
@@ -343,10 +347,11 @@ class ReportController extends AbstractController
// Formater les jours // Formater les jours
$start=new \Datetime('first day of this month'); $start=new \Datetime('first day of this month');
$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) {
$tbday=[ $tbday=[
"date"=>clone $start, "date"=>clone $start,
@@ -375,9 +380,11 @@ class ReportController extends AbstractController
// Formater les utilisateurs // Formater les utilisateurs
$start=new \Datetime('first day of this month'); $start=new \Datetime('first day of this month');
$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,false); $tbevents = $this->getEventuser($user,$start,$end,false);

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_VISITOR"]);
$em->persist($user); $em->persist($user);
$em->flush(); $em->flush();
@@ -125,8 +125,13 @@ class SecurityController extends AbstractController
// Redirection // Redirection
if($redirect) if($redirect)
return $this->redirect($redirect); return $this->redirect($redirect);
else else {
return $this->redirect($this->generateUrl('app_home')); $roles=$user->getRoles();
if(!in_array("ROLE_VISITOR",$roles))
return $this->redirect($this->generateUrl('app_home'));
else
return $this->redirect($this->generateUrl('app_customer_home'));
}
} }

View File

@@ -55,6 +55,7 @@ class TaskController extends AbstractController
$data = new Entity(); $data = new Entity();
$defaultnature = $em->getRepository("App:Nature")->findOneBy(['name' => 'Prestation']); $defaultnature = $em->getRepository("App:Nature")->findOneBy(['name' => 'Prestation']);
$data->setNature($defaultnature); $data->setNature($defaultnature);
$data->setActive(true);
// Création du formulaire // Création du formulaire
$form = $this->createForm(Form::class,$data,array("mode"=>"submit")); $form = $this->createForm(Form::class,$data,array("mode"=>"submit"));
@@ -167,6 +168,11 @@ class TaskController extends AbstractController
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);
} }
public function activetask() {
$this->get('session')->set('activetask',!$this->get('session')->get('activetask'));
return $this->redirectToRoute($this->route);
}
public function activeoffer() { public function activeoffer() {
$this->get('session')->set('activeoffer',!$this->get('session')->get('activeoffer')); $this->get('session')->set('activeoffer',!$this->get('session')->get('activeoffer'));
return $this->redirectToRoute($this->route); return $this->redirectToRoute($this->route);

View File

@@ -70,7 +70,11 @@ class Task
* @ORM\OneToMany(targetEntity="Penalty", mappedBy="task", cascade={"persist"}, orphanRemoval=false) * @ORM\OneToMany(targetEntity="Penalty", mappedBy="task", cascade={"persist"}, orphanRemoval=false)
*/ */
private $penaltys; private $penaltys;
/**
* @ORM\Column(name="active", type="boolean")
*
*/
private $active;
/** /**
* Calculate Displayname * Calculate Displayname
*/ */
@@ -228,6 +232,19 @@ class Task
return $this; return $this;
} }
public function getActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
/** /**
* @return Collection|Penalty[] * @return Collection|Penalty[]
*/ */

View File

@@ -57,6 +57,13 @@ class TaskType extends AbstractType
] ]
); );
$builder->add("active",
ChoiceType::class,[
"label" => "Actif",
"choices" => ["Non"=>false, "Oui"=>true]
]
);
$builder->add('color', $builder->add('color',
TextType::class, [ TextType::class, [
"label" => "Couleur", "label" => "Couleur",

View File

@@ -67,6 +67,7 @@ class sessionListener {
// Initialisation de la session // Initialisation de la session
if($regen) { if($regen) {
$session->set('activeproject',true); $session->set('activeproject',true);
$session->set('activetask',true);
$session->set('activeoffer',true); $session->set('activeoffer',true);
$session->set('activeholiday',true); $session->set('activeholiday',true);
$session->set('activetimer',true); $session->set('activetimer',true);

View File

@@ -99,7 +99,9 @@
{% for project in projects|sort((a, b) => a.displayname <=> b.displayname) %} {% for project in projects|sort((a, b) => a.displayname <=> b.displayname) %}
<optgroup label="{{project.displayname}}"> <optgroup label="{{project.displayname}}">
{% for task in project.tasks|sort((a, b) => a.displayname <=> b.displayname) %} {% for task in project.tasks|sort((a, b) => a.displayname <=> b.displayname) %}
{% if task.active %}
<option value="{{task.id}}">{{task.displayname}}</option> <option value="{{task.id}}">{{task.displayname}}</option>
{% endif %}
{% endfor %} {% endfor %}
</optgroup> </optgroup>
{% endfor %} {% endfor %}

View File

@@ -0,0 +1,6 @@
{% block body %}
Mois;Jours_facturés;Jour_non_facturés
{% for month, event in events %}
{{month}};{{event.f}};{{event.nf}}
{% endfor %}
{% endblock %}

View File

@@ -43,4 +43,14 @@ EXPORTS DE DONNEES
</div> </div>
</div> </div>
<p></p> <p></p>
<div class="card">
<div class="card-header">
<a class="btn btn-success" href={{ path('export_month_charged_days') }}>Export des jours facturés/non-facturés</a>
</div>
<div class="card-body">
<p>Exporter la liste du nombre de jours facturés et non-facturés par mois</p>
<p>Filtres utiles : Nombre de mois</p>
</div>
</div>
<p></p>
{% endblock %} {% endblock %}

View File

@@ -0,0 +1,8 @@
{% extends "base.html.twig" %}
{% block body %}
<center>Merci d'utiliser l'URL qui vous a été communiquée pour visualiser votre rapport.</center>
{% endblock %}

View File

@@ -90,7 +90,6 @@
{% endblock %} {% endblock %}
{% 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 %}
@@ -127,8 +126,6 @@
<h3>RAPPORT</h3> <h3>RAPPORT</h3>
<div class="small"> <div class="small">
<div class="new-page">&nbsp;</div>
{% for month in project.months %} {% for month in project.months %}
<h3 class="month">{{ month.monthlabel }}</h3> <h3 class="month">{{ month.monthlabel }}</h3>
<table> <table>
@@ -179,7 +176,6 @@
<td class="text-right">{{ month.totala|number_format(2, '.', ' ') }}</td> <td class="text-right">{{ month.totala|number_format(2, '.', ' ') }}</td>
</tr> </tr>
{% endif %} {% endif %}
<tfoot> <tfoot>
<tr> <tr>
<td style="min-width:200px">TOTAL</td> <td style="min-width:200px">TOTAL</td>
@@ -188,12 +184,7 @@
</tfoot> </tfoot>
</table> </table>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<h4>CUMUL HEBDOMADAIRE</h4> <h4>CUMUL HEBDOMADAIRE</h4>
<table> <table>
{% for year, weeks in project.weeks %} {% for year, weeks in project.weeks %}
@@ -219,7 +210,6 @@
</tr> </tr>
{% endfor %} {% endfor %}
</table> </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 %}
@@ -326,8 +316,6 @@
<td class="text-right">{{ (project.proposed - project.validate)|number_format(2, '.', ' ') }}</td> <td class="text-right">{{ (project.proposed - project.validate)|number_format(2, '.', ' ') }}</td>
</tfoot> </tfoot>
</table> </table>
<div class="new-page">&nbsp;</div>
{% endif %} {% endif %}
<h4>CONSOMMATION PASSEE</h4> <h4>CONSOMMATION PASSEE</h4>
{% if project.hors!=0 %} {% if project.hors!=0 %}
@@ -359,7 +347,6 @@
{% endfor %} {% endfor %}
</table> </table>
{% if not project.beforeastreinte is empty %} {% if not project.beforeastreinte is empty %}
<h4>ASTREINTES PASSEES</h4> <h4>ASTREINTES PASSEES</h4>
<table> <table>
@@ -389,6 +376,8 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div>
<div class="new-page">&nbsp;</div>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
<br> <br>

View File

@@ -54,6 +54,7 @@
{{ form_row(form.name) }} {{ form_row(form.name) }}
{{ form_row(form.project) }} {{ form_row(form.project) }}
{{ form_row(form.nature) }} {{ form_row(form.nature) }}
{{ form_row(form.active) }}
{{ form_row(form.quantity) }} {{ form_row(form.quantity) }}
{{ form_row(form.color) }} {{ form_row(form.color) }}
</div> </div>

View File

@@ -30,6 +30,11 @@
<label class="custom-control-label" for="switchactive">Projet Actif</label> <label class="custom-control-label" for="switchactive">Projet Actif</label>
</div> </div>
<div class="custom-control custom-switch float-right" style="margin-right:20px">
<input type="checkbox" class="custom-control-input" id="switchactivetask" {% if app.session.get('activetask') %} checked {% endif %}>
<label class="custom-control-label" for="switchactivetask">Tâche Active</label>
</div>
<p></p> <p></p>
{%for service in services %} {%for service in services %}
@@ -63,6 +68,7 @@
<th width="100px">Nature</th> <th width="100px">Nature</th>
<th width="100px">Projet</th> <th width="100px">Projet</th>
<th>Tâche</th> <th>Tâche</th>
<th>Actif</th>
<th width="100px" class="text-center no-string">Estimation</th> <th width="100px" class="text-center no-string">Estimation</th>
<th width="100px" class="text-center no-string">Validé</th> <th width="100px" class="text-center no-string">Validé</th>
<th width="100px" class="text-center no-string">Planifié</th> <th width="100px" class="text-center no-string">Planifié</th>
@@ -74,6 +80,7 @@
{% for project in service.projects %} {% for project in service.projects %}
{% if app.session.get('activeproject')==project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==project.id) %} {% if app.session.get('activeproject')==project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==project.id) %}
{% for task in project.tasks %} {% for task in project.tasks %}
{% if app.session.get('activetask')==task.active %}
{% set totvalidate=task.validate %} {% set totvalidate=task.validate %}
{% set totplanified=task.validate %} {% set totplanified=task.validate %}
{% for event in task.events %} {% for event in task.events %}
@@ -99,12 +106,14 @@
<td>{{task.nature.name}}</td> <td>{{task.nature.name}}</td>
<td>{{task.project.name}}</td> <td>{{task.project.name}}</td>
<td>{{task.name}}</td> <td>{{task.name}}</td>
<td>{{task.active ? "actif":"non-actif"}}</td>
<td class="text-right">{{task.quantity|number_format(2, '.', ' ')}}</td> <td class="text-right">{{task.quantity|number_format(2, '.', ' ')}}</td>
<td class="text-right">{{(totvalidate*-1)|number_format(2, '.', ' ')}}</td> <td class="text-right">{{(totvalidate*-1)|number_format(2, '.', ' ')}}</td>
<td class="text-right">{{((totplanified-totvalidate)*-1)|number_format(2, '.', ' ')}}</td> <td class="text-right">{{((totplanified-totvalidate)*-1)|number_format(2, '.', ' ')}}</td>
<td class="text-right">{{(task.quantity-totplanified)|number_format(2, '.', ' ')}}</td> <td class="text-right">{{(task.quantity-totplanified)|number_format(2, '.', ' ')}}</td>
<td class="text-center" style="background-color:{{task.color}}; color:#ffffff">{{task.color}}</td> <td class="text-center" style="background-color:{{task.color}}; color:#ffffff">{{task.color}}</td>
</tr> </tr>
{% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
@@ -136,6 +145,9 @@
$('#switchactive').change(function() { $('#switchactive').change(function() {
window.location="{{ path('app_task_activeproject' )}}"; window.location="{{ path('app_task_activeproject' )}}";
}); });
$('#switchactivetask').change(function() {
window.location="{{ path('app_task_activetask' )}}";
});
function myprint() { function myprint() {

View File

@@ -216,7 +216,7 @@
</div> </div>
<ul class="nav navbar-top-links navbar-right"> <ul class="nav navbar-top-links navbar-right">
{% if app.user %} {% if app.user and ("ROLE_USER" in app.user.roles or "ROLE_MASTER" in app.user.roles or "ROLE_VALIDATOR" in app.user.roles or "ROLE_ADMIN" in app.user.roles)%}
<li> <li>
<a href="{{path("app_user_profil")}}"> <a href="{{path("app_user_profil")}}">
<img src="\{{appAlias}}\uploads\avatar\{{app.user.avatar}}" class="avatar"> <img src="\{{appAlias}}\uploads\avatar\{{app.user.avatar}}" class="avatar">