mise en place des budgets

This commit is contained in:
2021-06-07 13:58:56 +02:00
parent 1954c00b39
commit 54dc485503
31 changed files with 1705 additions and 53 deletions

View File

@@ -439,6 +439,37 @@ app_timer_delete:
defaults: { _controller: App\Controller\TimerController:delete } defaults: { _controller: App\Controller\TimerController:delete }
#== Year =====================================================================================================
app_year:
path: /admin/year
defaults: { _controller: App\Controller\YearController:list }
app_year_submit:
path: /admin/year/submit
defaults: { _controller: App\Controller\YearController:submit }
app_year_update:
path: /admin/year/update/{id}
defaults: { _controller: App\Controller\YearController:update }
app_year_delete:
path: /admin/year/delete/{id}
defaults: { _controller: App\Controller\YearController:delete }
#== Budget =====================================================================================================
app_budget_last:
path: /master/budget
defaults: { _controller: App\Controller\BudgetController:list }
app_budget:
path: /master/budget/{id}
defaults: { _controller: App\Controller\BudgetController:list }
app_budget_update:
path: /master/budget/update/{type}/{id}/{year}
defaults: { _controller: App\Controller\BudgetController:update }
#== Customer ====================================================================================================== #== Customer ======================================================================================================
app_customer_home: app_customer_home:
path: /customer path: /customer

View File

@@ -1,7 +1,7 @@
{ {
"devDependencies": { "devDependencies": {
"@symfony/webpack-encore": "^0.28.2", "@symfony/webpack-encore": "^0.28.2",
"core-js": "^3.0.0", "core-js": "^3.14.0",
"regenerator-runtime": "^0.13.2", "regenerator-runtime": "^0.13.2",
"webpack-notifier": "^1.6.0" "webpack-notifier": "^1.6.0"
}, },
@@ -22,7 +22,7 @@
"bootstrap": "^4.4.1", "bootstrap": "^4.4.1",
"ckeditor": "^4.12.1", "ckeditor": "^4.12.1",
"crop-select-js": "^1.0.1", "crop-select-js": "^1.0.1",
"datatables.net-bs4": "^1.10.20", "datatables.net-bs4": "^1.10.25",
"dropzone": "^5.7.0", "dropzone": "^5.7.0",
"html2canvas": "^1.0.0-rc.5", "html2canvas": "^1.0.0-rc.5",
"jquery": "^3.4.1", "jquery": "^3.4.1",

View File

@@ -3,7 +3,7 @@
"app": { "app": {
"js": [ "js": [
"/schedule/build/runtime.45641845.js", "/schedule/build/runtime.45641845.js",
"/schedule/build/1.c39e6d32.js", "/schedule/build/1.ad66d16d.js",
"/schedule/build/app.d1d8cd91.js" "/schedule/build/app.d1d8cd91.js"
], ],
"css": [ "css": [
@@ -13,8 +13,8 @@
"fullcalendar": { "fullcalendar": {
"js": [ "js": [
"/schedule/build/runtime.45641845.js", "/schedule/build/runtime.45641845.js",
"/schedule/build/2.5e29274c.js", "/schedule/build/2.7b64de8c.js",
"/schedule/build/fullcalendar.a04a7cb3.js" "/schedule/build/fullcalendar.91688d8a.js"
], ],
"css": [ "css": [
"/schedule/build/2.941b44a3.css" "/schedule/build/2.941b44a3.css"

View File

@@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([["fullcalendar"],{"hhX+":function(e,n,t){"use strict";t.r(n),function(e){t("DQNa"),t("07d7"),t("JfAA");var n,r=t("SZB9"),i=t("9mV6"),u=t.n(i),c=t("Gbwi"),o=t("iOEq");t("eV1F"),t("pDWP"),t("pDWP");var a=document.getElementById("sideuser").value;document.addEventListener("DOMContentLoaded",(function(){var t=document.getElementById("fullcalendar");n=new r.a(t,{plugins:[c.a,o.a],locale:u.a,weekNumbers:!0,selectable:!0,eventSources:[{url:"event/load/"+a}],eventLimit:8,eventDrop:function(e){e.revert()},eventRender:function(e){function n(n){return e.apply(this,arguments)}return n.toString=function(){return e.toString()},n}((function(e){eventRender(e)})),select:function(e){eventSelect(e)},eventClick:function(e){function n(n){return e.apply(this,arguments)}return n.toString=function(){return e.toString()},n}((function(e){eventClick(e)}))}),e.calendar=n,n.render()}))}.call(this,t("yLpj"))}},[["hhX+","runtime",2]]]); (window.webpackJsonp=window.webpackJsonp||[]).push([["fullcalendar"],{"hhX+":function(e,n,t){"use strict";t.r(n),function(e){t("DQNa"),t("07d7"),t("JfAA");var n,r=t("SZB9"),i=t("9mV6"),u=t.n(i),c=t("Gbwi"),o=t("iOEq");t("eV1F"),t("pDWP"),t("pDWP");var a=document.getElementById("sideuser").value;document.addEventListener("DOMContentLoaded",(function(){var t=document.getElementById("fullcalendar");n=new r.a(t,{plugins:[c.a,o.a],locale:u.a,weekNumbers:!0,selectable:!0,eventSources:[{id:1,url:"event/load/"+a}],eventLimit:8,eventDrop:function(e){e.revert()},eventRender:function(e){function n(n){return e.apply(this,arguments)}return n.toString=function(){return e.toString()},n}((function(e){eventRender(e)})),select:function(e){eventSelect(e)},eventClick:function(e){function n(n){return e.apply(this,arguments)}return n.toString=function(){return e.toString()},n}((function(e){eventClick(e)}))}),e.calendar=n,n.render()}))}.call(this,t("yLpj"))}},[["hhX+","runtime",2]]]);

View File

@@ -1,14 +1,14 @@
{ {
"schedule/0.c9f3f7bd.js": "/schedule/build/0.c9f3f7bd.js", "schedule/0.c9f3f7bd.js": "/schedule/build/0.c9f3f7bd.js",
"schedule/1.dfadbda5.css": "/schedule/build/1.dfadbda5.css", "schedule/1.dfadbda5.css": "/schedule/build/1.dfadbda5.css",
"schedule/1.c39e6d32.js": "/schedule/build/1.c39e6d32.js", "schedule/1.ad66d16d.js": "/schedule/build/1.ad66d16d.js",
"schedule/2.941b44a3.css": "/schedule/build/2.941b44a3.css", "schedule/2.941b44a3.css": "/schedule/build/2.941b44a3.css",
"schedule/2.5e29274c.js": "/schedule/build/2.5e29274c.js", "schedule/2.7b64de8c.js": "/schedule/build/2.7b64de8c.js",
"schedule/3.34726357.css": "/schedule/build/3.34726357.css", "schedule/3.34726357.css": "/schedule/build/3.34726357.css",
"schedule/3.f3e80157.js": "/schedule/build/3.f3e80157.js", "schedule/3.f3e80157.js": "/schedule/build/3.f3e80157.js",
"schedule/app.js": "/schedule/build/app.d1d8cd91.js", "schedule/app.js": "/schedule/build/app.d1d8cd91.js",
"schedule/dropzone.js": "/schedule/build/dropzone.0d4b0ad2.js", "schedule/dropzone.js": "/schedule/build/dropzone.0d4b0ad2.js",
"schedule/fullcalendar.js": "/schedule/build/fullcalendar.a04a7cb3.js", "schedule/fullcalendar.js": "/schedule/build/fullcalendar.91688d8a.js",
"schedule/runtime.js": "/schedule/build/runtime.45641845.js", "schedule/runtime.js": "/schedule/build/runtime.45641845.js",
"schedule/ckeditor/adapters/jquery.js": "/schedule/build/ckeditor/adapters/jquery.js", "schedule/ckeditor/adapters/jquery.js": "/schedule/build/ckeditor/adapters/jquery.js",
"schedule/ckeditor/ckeditor.js": "/schedule/build/ckeditor/ckeditor.js", "schedule/ckeditor/ckeditor.js": "/schedule/build/ckeditor/ckeditor.js",

View File

@@ -0,0 +1,387 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\FormError;
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
use App\Entity\Yearproject as Yearproject;
use App\Entity\Yeardomaine as Yeardomaine;
use App\Form\YearprojectType as YearprojectType;
use App\Form\YeardomaineType as YeardomaineType;
class BudgetController extends AbstractController
{
private $knpSnappy;
public function __construct(\Knp\Snappy\Pdf $knpSnappy) { $this->knpSnappy = $knpSnappy; }
public function list($id=null,Request $request)
{
$em = $this->getDoctrine()->getManager();
// Rechercher l'exercice demandé sinon le dernier
if($id)
$n2=$em->getRepository("App:Year")->find($id);
else
$n2=$em->getRepository("App:Year")->findOneBy([],['start'=>'DESC']);
// Rechercher l'exercice précendent à celui selectionné
$n1 = $em
->createQueryBuilder('year')
->select('year')
->from('App:Year','year')
->Where('year.end<:start')
->setParameter('start',$n2->getStart())
->orderBy('year.start','DESC')
->setFirstResult(0)->setMaxResults(1)
->getQuery()->getResult();
if(empty($n1)) $n1=null;
else $n1=$n1[0];
if($n1) {
$startn1=clone $n1->getStart();
$startn1->setTime(0,0,0);
$endn1=clone $n1->getEnd();
$endn1->add(new \DateInterval('P1D'))->setTime(0,0,0);
}
if($n2) {
$startn2=clone $n2->getStart();
$startn2->setTime(0,0,0);
$endn2=clone $n2->getEnd();
$endn2->add(new \DateInterval('P1D'))->setTime(0,0,0);
}
// Pour chaque domaine
$tbdomaines=[];
$domaines = $em->getRepository("App:Domaine")->findBy([],['category'=>'ASC','name'=>'ASC']);
foreach($domaines as $domaine) {
// Filtre par Domaine
if($this->get('session')->get('iddomaine')!="all") {
if($domaine->getId()!=$this->get('session')->get('iddomaine'))
continue;
}
// On calcume le réel validé pour les deux périodes pour les domaines
$tbdomaines[$domaine->getId()]=[
"id" => $domaine->getId(),
"category" => $domaine->getCategory(),
"name" => $domaine->getCategory()." - ".$domaine->getName(),
"nbdayrealn1" => 0,
"nbetprealn1" => 0,
"nbcaarealn1" => 0,
"nbdaybudgn1" => 0,
"nbetpbudgn1" => 0,
"nbcaabudgn1" => 0,
"nbdayrealn2" => 0,
"nbetprealn2" => 0,
"nbcaarealn2" => 0,
"nbdaybudgn2" => 0,
"nbetpbudgn2" => 0,
"nbcaabudgn2" => 0,
"projects" => [],
];
// Période précédente n1
if($n1) {
// Events
$start=clone $n1->getStart();
$start->setTime(0,0,0);
$end=clone $n1->getEnd();
$end->add(new \DateInterval('P1D'))->setTime(0,0,0);
$events = $em
->createQueryBuilder('event')
->select('SUM(event.duration) as somme')
->from('App:Project','project')
->from('App:Task','task')
->from('App:Event','event')
->Where('project.domaine=:domaine')
->andWhere('task.project=project')
->andWhere('event.task=task')
->andWhere('event.start >=:start')
->andWhere('event.end <=:end')
->setParameter('domaine',$domaine)
->setParameter('start',$startn1)
->setParameter('end',$endn1)
->getQuery()->getResult();
$tbdomaines[$domaine->getId()]["nbdayrealn1"]=($events[0]["somme"]?$events[0]["somme"]:0);
$tbdomaines[$domaine->getId()]["nbetprealn1"]=$tbdomaines[$domaine->getId()]["nbdayrealn1"]/$n1->getNbday();
// Yeardomaine
$yeardomaine=$em->getRepository("App:Yeardomaine")->findOneBy(["domaine"=>$domaine,"year"=>$n1]);
if($yeardomaine) {
$tbdomaines[$domaine->getId()]["nbcaarealn1"]=$yeardomaine->getCareal();
$tbdomaines[$domaine->getId()]["nbdaybudgn1"]=$yeardomaine->getNbdaybudget();
$tbdomaines[$domaine->getId()]["nbetpbudgn1"]=$yeardomaine->getNbdaybudget()/$n1->getNbday();
$tbdomaines[$domaine->getId()]["nbcaabudgn1"]=$yeardomaine->getCabudget();
}
}
// Période encour n2
if($n2) {
$events = $em
->createQueryBuilder('event')
->select('SUM(event.duration) as somme')
->from('App:Project','project')
->from('App:Task','task')
->from('App:Event','event')
->Where('project.domaine=:domaine')
->andWhere('task.project=project')
->andWhere('event.task=task')
->andWhere('event.start >=:start')
->andWhere('event.end <=:end')
->setParameter('domaine',$domaine)
->setParameter('start',$startn2)
->setParameter('end',$endn2)
->getQuery()->getResult();
$tbdomaines[$domaine->getId()]["nbdayrealn2"]=($events[0]["somme"]?$events[0]["somme"]:0);
$tbdomaines[$domaine->getId()]["nbetprealn2"]=$tbdomaines[$domaine->getId()]["nbdayrealn2"]/$n2->getNbday();
// Yeardomaine
$yeardomaine=$em->getRepository("App:Yeardomaine")->findOneBy(["domaine"=>$domaine,"year"=>$n2]);
if($yeardomaine) {
$tbdomaines[$domaine->getId()]["nbcaarealn2"]=$yeardomaine->getCareal();
$tbdomaines[$domaine->getId()]["nbdaybudgn2"]=$yeardomaine->getNbdaybudget();
$tbdomaines[$domaine->getId()]["nbetpbudgn2"]=$yeardomaine->getNbdaybudget()/$n2->getNbday();
$tbdomaines[$domaine->getId()]["nbcaabudgn2"]=$yeardomaine->getCabudget();
}
}
// Pour chaque project du domaine
foreach($domaine->getProjects() as $project) {
// On calcume le réel validé pour les deux périodes pour les projects
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]=[
"id" => $project->getId(),
"name" => $project->getCustomer()->getName()." - ".$project->getName(),
"nbdayrealn1" => 0,
"nbetprealn1" => 0,
"nbcaarealn1" => 0,
"nbdaybudgn1" => 0,
"nbetpbudgn1" => 0,
"nbcaabudgn1" => 0,
"nbdayrealn2" => 0,
"nbetprealn2" => 0,
"nbcaarealn2" => 0,
"nbdaybudgn2" => 0,
"nbetpbudgn2" => 0,
"nbcaabudgn2" => 0,
];
// Période précédente n1
if($n1) {
$events = $em
->createQueryBuilder('event')
->select('SUM(event.duration) as somme')
->from('App:Task','task')
->from('App:Event','event')
->Where('task.project=:project')
->andWhere('event.task=task')
->andWhere('event.start >=:start')
->andWhere('event.end <=:end')
->setParameter('project',$project)
->setParameter('start',$startn1)
->setParameter('end',$endn1)
->getQuery()->getResult();
$nbdayrealn1=($events[0]["somme"]?$events[0]["somme"]:0);
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbdayrealn1"]=$nbdayrealn1;
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbetprealn1"]=$nbdayrealn1/$n1->getNbday();
// Yearproject
$yearproject=$em->getRepository("App:Yearproject")->findOneBy(["project"=>$project,"year"=>$n1]);
if($yearproject) {
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbcaarealn1"]=$yearproject->getCareal();
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbdaybudgn1"]=$yearproject->getNbdaybudget();
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbetpbudgn1"]=$yearproject->getNbdaybudget()/$n1->getNbday();
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbcaabudgn1"]=$yearproject->getCabudget();
}
}
// Période encour n2
if($n2) {
$start=$n2->getStart()->setTime(0,0,0);;
$end=$n2->getEnd()->add(new \DateInterval('P1D'))->setTime(0,0,0);
$events = $em
->createQueryBuilder('event')
->select('SUM(event.duration) as somme')
->from('App:Task','task')
->from('App:Event','event')
->andWhere('task.project=:project')
->andWhere('event.task=task')
->andWhere('event.start >=:start')
->andWhere('event.end <=:end')
->setParameter('project',$project)
->setParameter('start',$startn2)
->setParameter('end',$endn2)
->getQuery()->getResult();
$nbdayrealn2=($events[0]["somme"]?$events[0]["somme"]:0);
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbdayrealn2"]=$nbdayrealn2;
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbetprealn2"]=$nbdayrealn2/$n2->getNbday();
// Yearproject
$yearproject=$em->getRepository("App:Yearproject")->findOneBy(["project"=>$project,"year"=>$n2]);
if($yearproject) {
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbcaarealn2"]=$yearproject->getCareal();
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbdaybudgn2"]=$yearproject->getNbdaybudget();
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbetpbudgn2"]=$yearproject->getNbdaybudget()/$n2->getNbday();
$tbdomaines[$domaine->getId()]["projects"][$project->getId()]["nbcaabudgn2"]=$yearproject->getCabudget();
}
}
if(!$project->getActive()&&$nbdayrealn1==0&&$nbdayrealn2==0)
unset($tbdomaines[$domaine->getId()]["projects"][$project->getId()]);
}
}
if($request->query->get('fgprint')) {
$render = $this->renderView('Budget/list.html.twig',[
"useheader" => true,
"usesidebar" => true,
"domaines" => $tbdomaines,
"n1" => $n1,
"n2" => $n2,
"fgprint" => true,
]);
return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render),
'domaines.pdf'
);
}
else {
return $this->render('Budget/list.html.twig',[
"useheader" => true,
"usesidebar" => true,
"domaines" => $tbdomaines,
"n1" => $n1,
"n2" => $n2,
]);
}
}
public function update($type,$id,$year,Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
// Returnto
$returnto=$request->get("returnto");
// Recherche de l'exercice
$year=$em->getRepository("App:Year")->find($year);
// Recherche de la ligne projet/domaine associée à l'exercice
if($type=="project") {
$project=$em->getRepository("App:Project")->find($id);
$data=$em->getRepository("App:Yearproject")->findOneBy(["year"=>$year,"project"=>$project]);
if(!$data) {
$data=new Yearproject;
$data->setYear($year);
$data->setProject($project);
$em->persist($data);
$em->flush();
}
// Création du formulaire
$form = $this->createForm(YearprojectType::class,$data,array("mode"=>"update"));
}
else {
$domaine=$em->getRepository("App:Domaine")->find($id);
$data=$em->getRepository("App:Yeardomaine")->findOneBy(["year"=>$year,"domaine"=>$domaine]);
if(!$data) {
$data=new Yeardomaine;
$data->setYear($year);
$data->setProject($domaine);
$em->persist($data);
$em->flush();
}
// Création du formulaire
$form = $this->createForm(YeardomaineType::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
if($returnto)
return $this->redirectToRoute("app_budget",["id"=>$returnto]);
else
return $this->redirectToRoute("app_budget",["id"=>$year->getId()]);
}
// Affichage du formulaire
if($request->query->get('fgprint')) {
$render = $this->renderView('Budget/edit.html.twig', [
'useheader' => true,
'usesidebar' => true,
'budget' => $data,
'type' => $type,
'id' => $id,
'year' => $year,
'mode' => 'update',
'form' => $form->createView(),
"fgprint" => true,
"returnto" => $returnto,
]);
return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render),
'budget.pdf'
);
}
else {
return $this->render('Budget/edit.html.twig', [
'useheader' => true,
'usesidebar' => true,
'budget' => $data,
'type' => $type,
'id' => $id,
'year' => $year,
'mode' => 'update',
'form' => $form->createView(),
"returnto" => $returnto,
]);
}
}
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());
}
}
}
}

View File

@@ -10,6 +10,7 @@ use Symfony\Component\Form\FormError;
use App\Entity\Event as Entity; use App\Entity\Event as Entity;
use App\Form\EventType as Form; use App\Form\EventType as Form;
use App\Entity\Penalty; use App\Entity\Penalty;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class EventController extends AbstractController class EventController extends AbstractController
{ {
@@ -18,9 +19,11 @@ class EventController extends AbstractController
private $render = "Event/"; private $render = "Event/";
private $entity = "App:Event"; private $entity = "App:Event";
private $notificator; private $notificator;
private $router;
public function __construct(\App\Service\notificationService $notificator) { public function __construct(\App\Service\notificationService $notificator,UrlGeneratorInterface $router) {
$this->notificator = $notificator; $this->notificator = $notificator;
$this->router = $router;
} }
public function list(Request $request) public function list(Request $request)
@@ -283,7 +286,8 @@ class EventController extends AbstractController
$em->flush(); $em->flush();
if($task->getNature()->getIsvacation()){ if($task->getNature()->getIsvacation()){
$idevent=$event->getId(); $idevent=$event->getId();
$valid_url = $this->generateUrl('app_validationholiday'); //$valid_url = $this->generateUrl('app_validationholiday',[],true);
$valid_url = $this->router->generate('app_validationholiday', [], urlGeneratorInterface::ABSOLUTE_URL);
$this->notificator->sendNotifAttenteValid("Congés en attente de validation", $iduser, $idevent, $valid_url); $this->notificator->sendNotifAttenteValid("Congés en attente de validation", $iduser, $idevent, $valid_url);
} }

View File

@@ -37,7 +37,8 @@ class ProjectController extends AbstractController
"usesidebar" => true, "usesidebar" => true,
"fgprint" => true, "fgprint" => true,
]); ]);
$render=str_replace("file:///","/var/www/html/",$render);
return new PdfResponse( return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render,["orientation"=>"Landscape"]), $this->knpSnappy->getOutputFromHtml($render,["orientation"=>"Landscape"]),
'projets.pdf' 'projets.pdf'

View File

@@ -0,0 +1,180 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\FormError;
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
use App\Entity\Year as Entity;
use App\Form\YearType as Form;
class YearController extends AbstractController
{
private $data = "year";
private $route = "app_year";
private $render = "Year/";
private $entity = "App:Year";
private $knpSnappy;
public function __construct(\Knp\Snappy\Pdf $knpSnappy) { $this->knpSnappy = $knpSnappy; }
public function list(Request $request)
{
$em = $this->getDoctrine()->getManager();
$datas = $em->getRepository($this->entity)->findAll();
if($request->query->get('fgprint')) {
$render = $this->renderView($this->render.'list.html.twig',[
$this->data."s" => $datas,
"useheader" => true,
"usesidebar" => true,
"fgprint" => true,
]);
return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render),
'years.pdf'
);
}
else {
return $this->render($this->render.'list.html.twig',[
$this->data."s" => $datas,
"useheader" => true,
"usesidebar" => true,
]);
}
}
public function submit(Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data = new Entity();
// 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();
$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);
}
// Affichage du formulaire
if($request->query->get('fgprint')) {
$render = $this->renderView($this->render.'edit.html.twig', [
'useheader' => true,
'usesidebar' => true,
$this->data => $data,
'mode' => 'update',
'form' => $form->createView(),
"fgprint" => true,
]);
return new PdfResponse(
$this->knpSnappy->getOutputFromHtml($render),
'year.pdf'
);
}
else {
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());
}
}
}
}

View File

@@ -49,10 +49,16 @@ class Domaine
*/ */
private $projects; private $projects;
/**
* @ORM\OneToMany(targetEntity="Yeardomaine", mappedBy="domaine", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $years;
public function __construct() public function __construct()
{ {
$this->users = new ArrayCollection(); $this->users = new ArrayCollection();
$this->projects = new ArrayCollection(); $this->projects = new ArrayCollection();
$this->years = new ArrayCollection();
} }
@@ -163,6 +169,37 @@ class Domaine
{ {
$this->category = $category; $this->category = $category;
return $this;
}
/**
* @return Collection|Yeardomaine[]
*/
public function getYears(): Collection
{
return $this->years;
}
public function addYear(Yeardomaine $year): self
{
if (!$this->years->contains($year)) {
$this->years[] = $year;
$year->setDomaine($this);
}
return $this;
}
public function removeYear(Yeardomaine $year): self
{
if ($this->years->contains($year)) {
$this->years->removeElement($year);
// set the owning side to null (unless already changed)
if ($year->getDomaine() === $this) {
$year->setDomaine(null);
}
}
return $this; return $this;
} }

View File

@@ -67,10 +67,15 @@ class Project
private $tasks; private $tasks;
/** /**
* @ORM\OneToMany(targetEntity="Userproject", mappedBy="project", cascade={"persist"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="Userproject", mappedBy="project", cascade={"persist", "remove"}, orphanRemoval=true)
*/ */
private $userprojects; private $userprojects;
/**
* @ORM\OneToMany(targetEntity="Yearproject", mappedBy="project", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $years;
public function getDisplayname(): ?string public function getDisplayname(): ?string
{ {
@@ -83,6 +88,7 @@ class Project
$this->task = new ArrayCollection(); $this->task = new ArrayCollection();
$this->tasks = new ArrayCollection(); $this->tasks = new ArrayCollection();
$this->userprojects = new ArrayCollection(); $this->userprojects = new ArrayCollection();
$this->years = new ArrayCollection();
} }
public function __toString() public function __toString()
{ {
@@ -259,5 +265,36 @@ class Project
return $this; return $this;
} }
/**
* @return Collection|Yearproject[]
*/
public function getYears(): Collection
{
return $this->years;
}
public function addYear(Yearproject $year): self
{
if (!$this->years->contains($year)) {
$this->years[] = $year;
$year->setProject($this);
}
return $this;
}
public function removeYear(Yearproject $year): self
{
if ($this->years->contains($year)) {
$this->years->removeElement($year);
// set the owning side to null (unless already changed)
if ($year->getProject() === $this) {
$year->setProject(null);
}
}
return $this;
}
} }

View File

@@ -0,0 +1,160 @@
<?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;
/**
* Year
*
* @ORM\Table(name="year")
* @ORM\Entity()
*/
class Year
{
/**
* @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(type="integer")
*/
private $nbday;
/**
* @ORM\OneToMany(targetEntity="Yearproject", mappedBy="year", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $projects;
/**
* @ORM\OneToMany(targetEntity="Yeardomaine", mappedBy="year", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $domaines;
public function __construct()
{
$this->projects = new ArrayCollection();
$this->domaines = new ArrayCollection();
}
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 getNbday()
{
return $this->nbday;
}
public function setNbday($nbday): self
{
$this->nbday = $nbday;
return $this;
}
/**
* @return Collection|Yearproject[]
*/
public function getProjects(): Collection
{
return $this->projects;
}
public function addProject(Yearproject $project): self
{
if (!$this->projects->contains($project)) {
$this->projects[] = $project;
$project->setYear($this);
}
return $this;
}
public function removeProject(Yearproject $project): self
{
if ($this->projects->contains($project)) {
$this->projects->removeElement($project);
// set the owning side to null (unless already changed)
if ($project->getYear() === $this) {
$project->setYear(null);
}
}
return $this;
}
/**
* @return Collection|Yeardomaine[]
*/
public function getDomaines(): Collection
{
return $this->domaines;
}
public function addDomaine(Yeardomaine $domaine): self
{
if (!$this->domaines->contains($domaine)) {
$this->domaines[] = $domaine;
$domaine->setYear($this);
}
return $this;
}
public function removeDomaine(Yeardomaine $domaine): self
{
if ($this->domaines->contains($domaine)) {
$this->domaines->removeElement($domaine);
// set the owning side to null (unless already changed)
if ($domaine->getYear() === $this) {
$domaine->setYear(null);
}
}
return $this;
}
}

View File

@@ -0,0 +1,114 @@
<?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;
/**
* @ORM\Table(name="yeardomaine")
* @ORM\Entity()
*/
class Yeardomaine
{ /**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Year", inversedBy="domaines")
*/
private $year;
/**
* @ORM\ManyToOne(targetEntity="Domaine", inversedBy="years")
*/
private $domaine;
/**
* @ORM\Column(type="integer")
*/
private $nbdaybudget;
/**
* @ORM\Column(type="integer")
*/
private $cabudget;
/**
* @ORM\Column(type="integer")
*/
private $careal;
public function getId(): ?int
{
return $this->id;
}
public function getNbdaybudget(): ?int
{
return $this->nbdaybudget;
}
public function setNbdaybudget(int $nbdaybudget): self
{
$this->nbdaybudget = $nbdaybudget;
return $this;
}
public function getCabudget(): ?int
{
return $this->cabudget;
}
public function setCabudget(int $cabudget): self
{
$this->cabudget = $cabudget;
return $this;
}
public function getCareal(): ?int
{
return $this->careal;
}
public function setCareal(int $careal): self
{
$this->careal = $careal;
return $this;
}
public function getYear(): ?Year
{
return $this->year;
}
public function setYear(?Year $year): self
{
$this->year = $year;
return $this;
}
public function getDomaine(): ?Domaine
{
return $this->domaine;
}
public function setDomaine(?Domaine $domaine): self
{
$this->domaine = $domaine;
return $this;
}
}

View File

@@ -0,0 +1,113 @@
<?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;
/**
* @ORM\Table(name="yearproject")
* @ORM\Entity()
*/
class Yearproject
{ /**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Year", inversedBy="projects")
*/
private $year;
/**
* @ORM\ManyToOne(targetEntity="Project", inversedBy="years")
*/
private $project;
/**
* @ORM\Column(type="integer")
*/
private $nbdaybudget=0;
/**
* @ORM\Column(type="integer")
*/
private $cabudget=0;
/**
* @ORM\Column(type="integer")
*/
private $careal=0;
public function getId(): ?int
{
return $this->id;
}
public function getNbdaybudget(): ?int
{
return $this->nbdaybudget;
}
public function setNbdaybudget(int $nbdaybudget): self
{
$this->nbdaybudget = $nbdaybudget;
return $this;
}
public function getCabudget(): ?int
{
return $this->cabudget;
}
public function setCabudget(int $cabudget): self
{
$this->cabudget = $cabudget;
return $this;
}
public function getCareal(): ?int
{
return $this->careal;
}
public function setCareal(int $careal): self
{
$this->careal = $careal;
return $this;
}
public function getYear(): ?Year
{
return $this->year;
}
public function setYear(?Year $year): self
{
$this->year = $year;
return $this;
}
public function getProject(): ?Project
{
return $this->project;
}
public function setProject(?Project $project): self
{
$this->project = $project;
return $this;
}
}

View File

@@ -32,6 +32,13 @@ class DomaineType extends AbstractType
] ]
); );
$builder->add('category',
ChoiceType::class, [
'label' => "Catégorie",
'choices' => array("Administratif" => "Administratif","Opérationnel" => "Opérationnel","Interne" => "Interne")
]
);
$builder->add('name', $builder->add('name',
TextType::class, [ TextType::class, [
"label" =>"Nom" "label" =>"Nom"

View File

@@ -0,0 +1,63 @@
<?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\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 FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class YearType 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('start',
DateType::class, [
"label" =>"Début"
]
);
$builder->add('end',
DateType::class, [
"label" =>"Fin"
]
);
$builder->add('nbday',
IntegerType::class, [
"label" =>"Nombre de jours travaillé pour un temps plein"
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Year',
'mode' => 'string',
));
}
}

View File

@@ -0,0 +1,63 @@
<?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\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 FOS\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\EntityManager;
class YearprojectType 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('nbdaybudget',
IntegerType::class, [
"label" =>"Nombre de jours prévus pour l'exercice"
]
);
$builder->add('cabudget',
IntegerType::class, [
"label" =>"Budget prévu pour l'exercice"
]
);
$builder->add('careal',
IntegerType::class, [
"label" =>"Budget réel pour l'exercice"
]
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Yearproject',
'mode' => 'string',
));
}
}

View File

@@ -26,6 +26,8 @@ class notificationService
$user=$this->em->getRepository("App:User")->find($iduser); $user=$this->em->getRepository("App:User")->find($iduser);
$event=$this->em->getRepository("App:Event")->find($idevent); $event=$this->em->getRepository("App:Event")->find($idevent);
$users=$this->em->getRepository("App:User")->findAll(); $users=$this->em->getRepository("App:User")->findAll();
$valid_url=str_replace("http://","https://",$valid_url);
$tbemails=[]; $tbemails=[];
foreach($users as $usr) { foreach($users as $usr) {
if(in_array("ROLE_VALIDATOR",$usr->getRoles())) { if(in_array("ROLE_VALIDATOR",$usr->getRoles())) {

View File

@@ -0,0 +1,65 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
<h1 class="page-header">
{% if fgprint is defined and fgprint %}
EXERCICE
{% elseif mode=="update" %}
Modification EXERCICE
{% elseif mode=="submit" %}
Création EXERCICE
{% endif %}
</h1>
{{ form_widget(form.submit) }}
{% if returnto is empty %}
<a class="btn btn-secondary" href={{ path('app_budget',{id:year.id}) }}>Annuler</a>
{% else %}
<a class="btn btn-secondary" href={{ path('app_budget',{id:returnto}) }}>Annuler</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.nbdaybudget) }}
{{ form_row(form.cabudget) }}
{{ form_row(form.careal) }}
</div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$("#year_name").focus();
});
function myprint() {
href=document.location.href;
document.location.href=href+"?fgprint=true";
}
{% endblock %}

View File

@@ -0,0 +1,235 @@
{% 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; }
{%endif%}
{% endblock %}
{% block body %}
<h1 class="page-header">
BUDGET
</h1>
<p><a class="btn btn-success" href={{ path('app_year_submit') }}>Ajouter</a></p>
<div class="card">
<div class="card-header">
<i class="fa fa-table fa-fw"></i> Budget
</div>
<div class="card-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th rowspan=2>Domaine</th>
<th rowspan=2>Projet</th>
<th class="text-center" style="width:150px" colspan=3>{{n1.start|date("m/Y")}}</th>
<th class="text-center" style="width:150px" colspan=3>{{n2.start|date("m/Y")}}</th>
</tr>
<tr>
<th width="20px" class="no-sort no-print" rowspan=2></th>
<th class="text-center" style="width:150px">Réel</th>
<th class="text-center" style="width:150px">Budget</th>
<th width="20px" class="no-sort no-print" rowspan=2></th>
<th class="text-center" style="width:150px">Réel</th>
<th class="text-center" style="width:150px">Budget</th>
</tr>
</thead>
<tbody>
{% for domaine in domaines %}
{% set nbdayrealn1 = 0 %}
{% set nbetprealn1 = 0 %}
{% set nbcaarealn1 = 0 %}
{% set nbdaybudgn1 = 0 %}
{% set nbetpbudgn1 = 0 %}
{% set nbcaabudgn1 = 0 %}
{% set nbdayrealn2 = 0 %}
{% set nbetprealn2 = 0 %}
{% set nbcaarealn2 = 0 %}
{% set nbdaybudgn2 = 0 %}
{% set nbetpbudgn2 = 0 %}
{% set nbcaabudgn2 = 0 %}
{% for project in domaine.projects %}
{% set nbdayrealn1 = nbdayrealn1+project.nbdayrealn1 %}
{% set nbetprealn1 = nbetprealn1+project.nbetprealn1 %}
{% set nbcaarealn1 = nbcaarealn1+project.nbcaarealn1 %}
{% set nbdaybudgn1 = nbdaybudgn1+project.nbdaybudgn1 %}
{% set nbetpbudgn1 = nbetpbudgn1+project.nbetpbudgn1 %}
{% set nbcaabudgn1 = nbcaabudgn1+project.nbcaabudgn1 %}
{% set nbdayrealn2 = nbdayrealn2+project.nbdayrealn2 %}
{% set nbetprealn2 = nbetprealn2+project.nbetprealn2 %}
{% set nbcaarealn2 = nbcaarealn2+project.nbcaarealn2 %}
{% set nbdaybudgn2 = nbdaybudgn2+project.nbdaybudgn2 %}
{% set nbetpbudgn2 = nbetpbudgn2+project.nbetpbudgn2 %}
{% set nbcaabudgn2 = nbcaabudgn2+project.nbcaabudgn2 %}
<tr>
<td>{{domaine.name}}</td>
<td>{{project.name}}</td>
<td class="text-center">
<a href="{{path("app_budget_update",{type:"project",id:project.id,year:n1.id,returnto:n2.id})}}"><i class="fa fa-file"></i></a>
</td>
<td class="text-center">
{{project.nbdayrealn1}} jours<br>
<small>
{{project.nbetprealn1|number_format(2)}}ETP / {{project.nbcaarealn1}}
</small>
</td>
<td class="text-center">
{{project.nbdaybudgn1}} jours<br>
<small>
{{project.nbetpbudgn1|number_format(2)}}ETP / {{project.nbcaabudgn1}}
</small>
</td>
<td class="text-center">
<a href="{{path("app_budget_update",{type:"project",id:project.id,year:n2.id})}}"><i class="fa fa-file"></i></a>
</td>
<td class="text-center">
{{project.nbdayrealn2}} jours<br>
<small>
{{project.nbetprealn2|number_format(2)}}ETP / {{project.nbcaarealn2}}
</small>
</td>
<td class="text-center">
{{project.nbdaybudgn2}} jours<br>
<small>
{{project.nbetpbudgn2|number_format(2)}}ETP / {{project.nbcaabudgn2}}
</small>
</td>
</tr>
{% endfor %}
<tr>
<td>{{domaine.name}}</td>
<td>Hors Projet</td>
<td class="text-center">
<a href="{{path("app_budget_update",{type:"budget",id:domaine.id,year:n1.id})}}"><i class="fa fa-file"></i></a>
</td>
<td class="text-center">
{{(domaine.nbdayrealn1-nbdayrealn1)}} jours<br>
<small>
{{(domaine.nbetprealn1-nbetprealn1)|number_format(2)}}ETP / {{domaine.nbcaarealn1}}
</small>
</td>
<td class="text-center">
{{(domaine.nbdaybudgn1)}} jours<br>
<small>
{{domaine.nbetpbudgn1|number_format(2)}}ETP / {{(domaine.nbcaabudgn1)}}
</small>
</td>
<td class="text-center">
<a href="{{path("app_budget_update",{type:"budget",id:domaine.id,year:n2.id})}}"><i class="fa fa-file"></i></a>
</td>
<td class="text-center">
{{(domaine.nbdayrealn2-nbdayrealn2)}} jours<br>
<small>
{{(domaine.nbetprealn2-nbetprealn2)|number_format(2)}}ETP / {{domaine.nbcaarealn2}}
</small>
</td>
<td class="text-center">
{{(domaine.nbdaybudgn2)}} jours<br>
<small>
{{domaine.nbetpbudgn2|number_format(2)}}ETP / {{(domaine.nbcaabudgn2)}}
</small>
</td>
</tr>
<tr>
<td>{{domaine.name}}</td>
<td>TOTAL</td>
<td class="no-print"> </td>
<td class="text-center">
{{domaine.nbdayrealn1}} jours<br>
<small>
{{domaine.nbetprealn1|number_format(2)}}ETP / {{domaine.nbcaarealn1+nbcaarealn1}}
</small>
</td>
<td class="text-center">
{{domaine.nbdaybudgn1+nbdaybudgn1}} jours<br>
<small>
{{(domaine.nbetpbudgn1+nbetpbudgn1)|number_format(2)}}ETP / {{domaine.nbcaabudgn1+nbcaabudgn1}}
</small>
</td>
<td class="no-print"> </td>
<td class="text-center">
{{domaine.nbdayrealn2}} jours<br>
<small>
{{domaine.nbetprealn2|number_format(2)}}ETP / {{domaine.nbcaarealn2+nbcaarealn2}}
</small>
</td>
<td class="text-center">
{{domaine.nbdaybudgn2+nbdaybudgn2}} jours<br>
<small>
{{(domaine.nbetpbudgn2+nbetpbudgn2)|number_format(2)}}ETP / {{domaine.nbcaabudgn2+nbcaabudgn2}}
</small>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
var groupColumn = 1;
var table = $('#dataTables').DataTable({
"columnDefs": [
{ "visible": false, "targets": groupColumn }
],
"order": [[ groupColumn, 'asc' ]],
"displayLength": 1500,
"drawCallback": function ( settings ) {
var api = this.api();
var rows = api.rows( {page:'current'} ).nodes();
var last=null;
api.column(groupColumn, {page:'current'} ).data().each( function ( group, i ) {
if ( last !== group ) {
$(rows).eq( i ).before(
'<tr class="group"><td colspan="6">'+group+'</td></tr>'
);
last = group;
}
} );
}
} );
// Order by the grouping
$('#dataTables tbody').on( 'click', 'tr.group', function () {
var currentOrder = table.order()[0];
if ( currentOrder[0] === groupColumn && currentOrder[1] === 'asc' ) {
table.order( [ groupColumn, 'desc' ] ).draw();
}
else {
table.order( [ groupColumn, 'asc' ] ).draw();
}
} );
});
function myprint() {
href=document.location.href;
document.location.href=href+"?fgprint=true";
}
{% endblock %}

View File

@@ -51,6 +51,7 @@
</div> </div>
<div class="card-body"> <div class="card-body">
{{ form_row(form.category) }}
{{ form_row(form.name) }} {{ form_row(form.name) }}
{{ form_row(form.description) }} {{ form_row(form.description) }}
</div> </div>

View File

@@ -30,6 +30,7 @@ DOMAINES
<thead> <thead>
<tr> <tr>
<th width="70px" class="no-sort no-print">Action</th> <th width="70px" class="no-sort no-print">Action</th>
<th>Catégorie</th>
<th>Nom</th> <th>Nom</th>
</tr> </tr>
</thead> </thead>
@@ -39,6 +40,7 @@ DOMAINES
<td class="no-print"> <td class="no-print">
<a href="{{path("app_domaine_update",{id:domaine.id})}}"><i class="fa fa-file"></i></a> <a href="{{path("app_domaine_update",{id:domaine.id})}}"><i class="fa fa-file"></i></a>
</td> </td>
<td>{{domaine.category}}</td>
<td>{{domaine.name}}</td> <td>{{domaine.name}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -105,7 +105,6 @@
{% endfor %} {% endfor %}
</optgroup> </optgroup>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
@@ -266,7 +265,6 @@ $(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');
@@ -354,8 +352,6 @@ function eventSelect(selectionInfo) {
// Formulaire Modification d'un événement // Formulaire Modification d'un événement
function eventClick(info) { function eventClick(info) {
if(info.event.extendedProps.editable) { if(info.event.extendedProps.editable) {
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;
@@ -453,7 +449,6 @@ function eventSubmit() {
$("#modalsubmit .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>"); $("#modalsubmit .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
} }
else { else {
console.log(response);
calendar.refetchEvents(); calendar.refetchEvents();
$('#modalsubmit').modal('hide'); $('#modalsubmit').modal('hide');
} }

View File

@@ -17,7 +17,7 @@
<b>Type =</b> Congé <b>Type =</b> Congé
</p> </p>
<p> <p>
<b>Lien pour valider =</b> {{ valid_link }} <b>Lien pour valider =</b> <a href="{{ valid_link }}">{{ valid_link }}</a>
</p> </p>
{% endautoescape %} {% endautoescape %}

View File

@@ -95,7 +95,7 @@
</td> </td>
<td>{{project.customer.name}}</td> <td>{{project.customer.name}}</td>
<td>{{project.name}}</td> <td>{{project.name}}</td>
<td>{% if app.session.get('viewservice') %}{%if not project.domaine is empty %}{{project.domaine.name}}{%endif%}{%else%}{{project.service.name}}{%endif%}</td> <td>{% if app.session.get('viewservice') %}{{project.domaine.name}}{%else%}{{project.service.name}}{%endif%}</td>
<td class="text-right"> <td class="text-right">
{% set tottask=0 %} {% set tottask=0 %}
{% set totvalidate=0 %} {% set totvalidate=0 %}
@@ -111,8 +111,6 @@
{% for task in project.tasks %} {% for task in project.tasks %}
{% set tottask=tottask+task.quantity %} {% set tottask=tottask+task.quantity %}
{% 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 %}
{% if event.validate %} {% if event.validate %}

View File

@@ -0,0 +1,71 @@
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
<h1 class="page-header">
{% if fgprint is defined and fgprint %}
EXERCICE
{% elseif mode=="update" %}
Modification EXERCICE
{% elseif mode=="submit" %}
Création EXERCICE
{% endif %}
</h1>
{{ form_widget(form.submit) }}
<a class="btn btn-secondary" href={{ path('app_year') }}>Annuler</a>
{% if mode=="update" %}
<a href="{{ path('app_year_delete',{'id':year.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.start) }}
{{ form_row(form.end) }}
{{ form_row(form.nbday) }}
</div>
</div>
{{ form_end(form) }}
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$("#year_name").focus();
});
function myprint() {
href=document.location.href;
document.location.href=href+"?fgprint=true";
}
{% endblock %}

View File

@@ -0,0 +1,74 @@
{% 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; }
{%endif%}
{% endblock %}
{% block body %}
<h1 class="page-header">
EXERCICES COMPTABLE
</h1>
<p><a class="btn btn-success" href={{ path('app_year_submit') }}>Ajouter</a></p>
<div class="card">
<div class="card-header">
<i class="fa fa-table fa-fw"></i> Liste des Exercices
</div>
<div class="card-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th width="70px" class="no-sort no-print">Action</th>
<th>Début</th>
<th>Fin</th>
<th>Nb jour travail</th>
</tr>
</thead>
<tbody>
{% for year in years %}
<tr>
<td class="no-print">
<a href="{{path("app_year_update",{id:year.id})}}"><i class="fa fa-file"></i></a>
</td>
<td>{{year.start|date("d/m/Y")}}</td>
<td>{{year.end|date("d/m/Y")}}</td>
<td>{{year.nbday}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
{% if not fgprint is defined or not fgprint %}
$('#dataTables').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";
}
{% endblock %}

View File

@@ -219,7 +219,7 @@
{% 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)%} {% 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">
</a> </a>
</li> </li>
{% endif %} {% endif %}
@@ -440,11 +440,17 @@
</a> </a>
</li> </li>
<li class="last"> <li>
<a href="{{path("app_task")}}"> <a href="{{path("app_task")}}">
<i class="fa fa-tasks"></i>Tâches <i class="fa fa-tasks"></i>Tâches
</a> </a>
</li> </li>
<li class="last">
<a href="{{path("app_budget_last")}}">
<i class="fa fa-money-bill-alt"></i>Budgets
</a>
</li>
{% endif %} {% endif %}
{% if is_granted('ROLE_ADMIN') %} {% if is_granted('ROLE_ADMIN') %}
@@ -480,6 +486,12 @@
</a> </a>
</li> </li>
<li>
<a href="{{path("app_year")}}">
<i class="fa fa-calendar-alt"></i>Exercices Comptable
</a>
</li>
<li class="last"> <li class="last">
<a href="{{path("app_breakday")}}"> <a href="{{path("app_breakday")}}">
<i class="fa fa-gifts"></i>Jours Fériés <i class="fa fa-gifts"></i>Jours Fériés

View File

@@ -5,7 +5,7 @@ APP_AUTH=CAS
# MAIL sendmail / smtp # MAIL sendmail / smtp
MAILER_METHOD=sendmail MAILER_METHOD=smtp
MAILER_URL=%%getVar('schedule_email_url', '') MAILER_URL=%%getVar('schedule_email_url', '')
MAILER_NOREPLY=noreply@noreply.fr MAILER_NOREPLY=noreply@noreply.fr
MAILER_DEFAULT_NOTIF=%%getVar('schedule_email_global_notif', '') MAILER_DEFAULT_NOTIF=%%getVar('schedule_email_global_notif', '')