Compare commits

..

13 Commits

27 changed files with 544 additions and 167 deletions

1
debian/compat vendored
View File

@ -1 +0,0 @@
7

24
debian/control vendored
View File

@ -1,24 +0,0 @@
Source: eole-ninebadge
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/ninebadge
Vcs-Git: https://forge.cadoles.com/Cadoles/ninebadge
Vcs-Browser: https://forge.cadoles.com/Cadoles/ninebadge
Package: ninebadge-sso
Architecture: all
Depends: ${misc:Depends}, eole-sso
Description: Filtre SSO pour ninebadge "EOLE".
Package: eole-ninebadge
Architecture: all
Depends: ${misc:Depends}, eole-envole-dependances, ninebadge-sso
Description: Eolisation de l'application ninebadge.
Package: ninebadge-apps
Architecture: all
Depends: ${misc:Depends}, envole-dependances-apps
Description: Sources pour ninebadge "EOLE".

44
debian/copyright vendored
View File

@ -1,44 +0,0 @@
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'.

View File

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

3
debian/gbp.conf vendored
View File

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

View File

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

View File

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

8
debian/rules vendored
View File

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

View File

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

View File

@ -68,7 +68,10 @@
"preferred-install": {
"*": "dist"
},
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"symfony/flex": true
}
},
"autoload": {
"psr-4": {
@ -89,6 +92,9 @@
"symfony/polyfill-php56": "*"
},
"scripts": {
"pre-install-cmd": [
"php scripts/checkcomposer.php"
],
"auto-scripts": {
"cache:clear": "symfony-cmd",
"cache:clear --env=prod": "symfony-cmd",

View File

@ -2,9 +2,9 @@ knp_snappy:
temporary_folder: "%kernel.cache_dir%/snappy"
pdf:
enabled: true
binary: '/var/www/html/ninegitea/scripts/wkhtmltopdf/wkhtmltopdf'
binary: '/var/www/html/ninebadge/scripts/wkhtmltopdf/wkhtmltopdf'
options: []
image:
enabled: true
binary: '/var/www/html/ninegitea/scripts/wkhtmltopdf/wkhtmltoimage'
binary: '/var/www/html/ninebadge/scripts/wkhtmltopdf/wkhtmltoimage'
options: []

View File

@ -182,11 +182,11 @@ app_tallyday:
defaults: { _controller: App\Controller\TallydayController:tallyday }
app_tallyday_start:
path: /user/tallyday/start
path: /user/tallyday/start/{istelework}/{ispenaltypassive}/{ispenaltyactive}
defaults: { _controller: App\Controller\TallydayController:start }
app_tallyday_end:
path: /user/tallyday/end
path: /user/tallyday/end/{istelework}/{ispenaltypassive}/{ispenaltyactive}
defaults: { _controller: App\Controller\TallydayController:end }
app_tallyday_userlist:

View File

@ -0,0 +1,13 @@
<?php
$requiredVersion = 'version 1'; // La version interdite
$composerVersion = trim(shell_exec('COMPOSER_ALLOW_SUPERUSER=1 composer --version --no-ansi'));
echo $composerVersion."\n";
if (stripos($composerVersion,$requiredVersion)===false ) {
echo "La version de Composer $requiredVersion n'est pas autorisée" . PHP_EOL;
echo "Veuillez mettre à jour Composer avec 'composer self-update --1'." . PHP_EOL;
echo "Ou executez le scripts/reconfigure.sh" . PHP_EOL;
exit(1); // Quitte avec un code d'erreur
}

View File

@ -28,6 +28,8 @@ fi
# Installation des dépendances composer
echo COMPOSER = Install
export COMPOSER_ALLOW_SUPERUSER=1
composer self-update --1 --quiet
composer install --quiet
php bin/console app:AppInit --env=prod

View File

@ -83,21 +83,36 @@ class BreakdayCommand extends Command
foreach($users as $user) {
if(!$user->hasRole("ROLE_USER")) continue;
$mini=new \Datetime('2022-03-07 00:00');
$start=new \Datetime('00:00');
$start->modify("monday this week");
$this->writeln("");
$this->writeln($user->getUsername());
$start=new \Datetime('2022-03-07 00:00');
$end=new \Datetime('00:00');
$end->modify("last day of this month");
$end->modify("next sunday");
$start->modify("previous month");
if($start<$mini) $start=clone $mini;
// On récupère la première journée de pointage de l'utilisateur
$qb = $this->em->createQueryBuilder()
->select('tallyday')
->from('App:Tallyday','tallyday')
->Where('tallyday.user=:user')
->setParameter('user',$user)
->orderBy('tallyday.dateof', 'ASC')
->setMaxResults(1);
$datas = $qb->getQuery()->getResult();
if(empty($datas)) continue;
$firstday=$datas[0]->getDateof();
$this->writeln("FIRST DAY = ".$firstday->format("d/m/Y"));
$response=$this->api("POST",$url."/getBreakdays",json_encode(["key"=>$key,"username"=>$user->getUsername()]));
if($response&&$response->code=="200") {
while($start<=$end) {
$havebreakday=false;
if($start->format("w")!=0&&$start->format("w")!=6) {
$havebreakdayAM=false;
$havebreakdayPM=false;
if($start->format("w")!=0&&$start->format("w")!=6&&$start>=$firstday) {
foreach($response->body->events as $event) {
if($event->eventallday) {
$manip=clone $start;
@ -146,7 +161,10 @@ class BreakdayCommand extends Command
$data->setIsbreakday(true);
$data->setName($event->taskname);
$data->setDatestart(clone $manip);
$data->setIstelework(false);
$data->setIspenaltypassive(false);
$data->setIspenaltyactive(false);
$manip->add(new \DateInterval("PT7H"));
$data->setDateend(clone $manip);
$this->em->persist($data);
@ -194,6 +212,9 @@ class BreakdayCommand extends Command
$data->setIsbreakday(true);
$data->setName("AM = ".$event->taskname);
$data->setDatestart(clone $manip);
$data->setIstelework(false);
$data->setIspenaltypassive(false);
$data->setIspenaltyactive(false);
$manip->add(new \DateInterval("PT3H"));
$manip->add(new \DateInterval("PT30M"));
@ -203,6 +224,7 @@ class BreakdayCommand extends Command
}
$havebreakday=true;
$havebreakdayAM=true;
}
}
else {
@ -241,8 +263,11 @@ class BreakdayCommand extends Command
$data->setValidatemaster(false);
$data->setIsbreakday(true);
$data->setName("PM = ".$event->taskname);
$data->setDatestart(clone $manip);
$data->setDatestart(clone $manip);
$data->setIstelework(false);
$data->setIspenaltypassive(false);
$data->setIspenaltyactive(false);
$manip->add(new \DateInterval("PT3H"));
$manip->add(new \DateInterval("PT30M"));
$data->setDateend(clone $manip);
@ -251,6 +276,7 @@ class BreakdayCommand extends Command
}
$havebreakday=true;
$havebreakdayPM=true;
}
}
}
@ -266,6 +292,31 @@ class BreakdayCommand extends Command
$this->em->flush();
}
}
else {
// Si congés matin mais par l'après midi on supprime un congés potentiel de l'aprés midi
if($havebreakdayAM && !$havebreakdayPM) {
$manip=clone $start;
$manip->setTime(13,30);
$tallydays=$this->em->getRepository("App:Tallyday")->findBy(["user"=>$user,"dateof"=>$start,"datestart"=>$manip,"validatemaster"=>false,"isbreakday"=>true]);
foreach($tallydays as $tallyday) {
$this->em->remove($tallyday);
$this->em->flush();
}
}
// Si congés aprèsmidi mais pas le matin on supprime un congés potentiel du matin
if(!$havebreakdayAM && $havebreakdayPM) {
$manip=clone $start;
$manip->setTime(8,30);
$tallydays=$this->em->getRepository("App:Tallyday")->findBy(["user"=>$user,"dateof"=>$start,"datestart"=>$manip,"validatemaster"=>false,"isbreakday"=>true]);
foreach($tallydays as $tallyday) {
$this->em->remove($tallyday);
$this->em->flush();
}
}
}
$start->add(new \DateInterval('P1D'));
}

View File

@ -107,6 +107,13 @@ class RestController extends AbstractFOSRestController
* description="User APIKey",
* type="string"
* )
* @SWG\Parameter(
* name="type",
* in="formData",
* required=false,
* description="Type of time = null | istelework | ispenaltypassive | ispenaltyactive",
* type="string"
* )
*/
@ -120,6 +127,7 @@ class RestController extends AbstractFOSRestController
// Récupération des parametres
$key=$request->get("key");
$type=$request->get("type");
// Rechercher l'utilisateur associé à la clé
$user = $em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
@ -127,6 +135,13 @@ class RestController extends AbstractFOSRestController
$view = $this->view("API Key inconnue", 403);
return $this->handleView($view);
}
// Tester le type
if($type!=null && $type!="istelework" && $type!="ispenaltypassive" && $type!="ispenaltyactive") {
$view = $this->view("Type inconnu", 403);
return $this->handleView($view);
}
$datenow=new \DateTime("now");
$datenow->setTime ( $datenow->format("H"), $datenow->format("i"), 0 );
@ -146,6 +161,9 @@ class RestController extends AbstractFOSRestController
$data->setValidateuser(false);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setIstelework(($type=="istelework"));
$data->setIspenaltyactive(($type=="ispenaltyactive"));
$data->setIspenaltypassive(($type=="ispenaltypassive"));
$data->setDatestart($datenow);
$status="started";
}
@ -153,6 +171,9 @@ class RestController extends AbstractFOSRestController
// Sinon c'est que l'on ferme un creneau
elseif($data) {
$data->setDateend($datenow);
$data->setIstelework(($type=="istelework"));
$data->setIspenaltyactive(($type=="ispenaltyactive"));
$data->setIspenaltypassive(($type=="ispenaltypassive"));
$status="stopped";
}
@ -211,6 +232,13 @@ class RestController extends AbstractFOSRestController
* description="User APIKey",
* type="string"
* )
* @SWG\Parameter(
* name="type",
* in="formData",
* required=false,
* description="Type of time = null | istelework | ispenaltypassive | ispenaltyactive",
* type="string"
* )
*/
@ -224,13 +252,21 @@ class RestController extends AbstractFOSRestController
// Récupération des parametres
$key=$request->get("key");
$type=$request->get("type");
// Rechercher l'utilisateur associé à la clé
$user = $em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
if(!$user) {
$view = $this->view("API Key inconnue", 403);
return $this->handleView($view);
}
// Tester le type
if($type!=null && $type!="istelework" && $type!="ispenaltypassive" && $type!="ispenaltyactive") {
$view = $this->view("Type inconnu", 403);
return $this->handleView($view);
}
$datenow=new \DateTime("now");
$datenow->setTime ( $datenow->format("H"), $datenow->format("i"), 0 );
@ -250,6 +286,9 @@ class RestController extends AbstractFOSRestController
$data->setValidateuser(false);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setIstelework(($type=="istelework"));
$data->setIspenaltyactive(($type=="ispenaltyactive"));
$data->setIspenaltypassive(($type=="ispenaltypassive"));
$data->setDatestart($datenow);
}
@ -309,6 +348,13 @@ class RestController extends AbstractFOSRestController
* description="User APIKey",
* type="string"
* )
* @SWG\Parameter(
* name="type",
* in="formData",
* required=false,
* description="Type of time = null | istelework | ispenaltypassive | ispenaltyactive",
* type="string"
* )
*/
@ -322,13 +368,21 @@ class RestController extends AbstractFOSRestController
// Récupération des parametres
$key=$request->get("key");
$type=$request->get("type");
// Rechercher l'utilisateur associé à la clé
$user = $em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
if(!$user) {
$view = $this->view("API Key inconnue", 403);
return $this->handleView($view);
}
// Tester le type
if($type!=null && $type!="istelework" && $type!="ispenaltypassive" && $type!="ispenaltyactive") {
$view = $this->view("Type inconnu", 403);
return $this->handleView($view);
}
$datenow=new \DateTime("now");
$datenow->setTime ( $datenow->format("H"), $datenow->format("i"), 0 );
@ -349,6 +403,9 @@ class RestController extends AbstractFOSRestController
// Sinon c'est que l'on ferme un creneau
elseif($data) {
$data->setDateend($datenow);
$data->setIstelework(($type=="istelework"));
$data->setIspenaltyactive(($type=="ispenaltyactive"));
$data->setIspenaltypassive(($type=="ispenaltypassive"));
}
// Sinon pas normal
@ -423,6 +480,14 @@ class RestController extends AbstractFOSRestController
* description="Date end format YYYY-MM-DD H:I",
* type="string"
* )
*
* @SWG\Parameter(
* name="type",
* in="formData",
* required=false,
* description="Type of time = null | istelework | ispenaltypassive | ispenaltyactive",
* type="string"
* )
*/
public function addtimer(Request $request) {
@ -437,6 +502,7 @@ class RestController extends AbstractFOSRestController
$start=new \DateTime($request->get("start"));
$end=$request->get("end");
if(!is_null($end)) $end=new \DateTime($end);
$type=$request->get("type");
// Rechercher l'utilisateur associé à la clé
$user = $em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
@ -445,6 +511,14 @@ class RestController extends AbstractFOSRestController
return $this->handleView($view);
}
// Tester le type
if($type!=null && $type!="istelework" && $type!="ispenaltypassive" && $type!="ispenaltyactive") {
$view = $this->view("Type inconnu", 403);
return $this->handleView($view);
}
// Controler la validité des timers
if(!$em->getRepository("App:Tallyday")->ctrlTallyday($user,$start)) {
$view = $this->view("Impossible d'entamer une journée sans avoir terminé les jours précédents", 404);
return $this->handleView($view);
@ -459,6 +533,9 @@ class RestController extends AbstractFOSRestController
$data->setValidateuser(false);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setIstelework(($type=="istelework"));
$data->setIspenaltyactive(($type=="ispenaltyactive"));
$data->setIspenaltypassive(($type=="ispenaltypassive"));
$data->setDatestart($start);
$data->setDateend($end);
@ -669,7 +746,10 @@ class RestController extends AbstractFOSRestController
$data->setValidateuser(true);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setIstelework(false);
$data->setIspenaltyactive(false);
$data->setIspenaltypassive(false);
$em->persist($data);
$em->flush();
}
@ -862,7 +942,11 @@ class RestController extends AbstractFOSRestController
foreach($datas as $data) {
$isvalideuser=$data->getValidateuser();
$isvalidemaster=$data->getValidatemaster();
array_push($timers,["start"=>$data->getDatestart(),"end"=>$data->getDateend()]);
$type="";
if($data->getIstelework()) $type="istelework";
if($data->getIspenaltypassive()) $type="ispenaltypassive";
if($data->getIspenaltyactive()) $type="ispenaltyactive";
array_push($timers,["start"=>$data->getDatestart(),"end"=>$data->getDateend(),"type"=>$type]);
$e->add($data->getTimeday());
}
$interval = $f->diff($e);

View File

@ -137,6 +137,8 @@ class TallydayController extends AbstractController
$users = $em->getRepository("App:User")->findBy([],["firstname"=>"ASC","lastname"=>"ASC"]);
foreach($users as $user) {
if($user->hasRole("ROLE_USER")) {
$dates[$user->getId()] = [
"id"=>$user->getId(),
"avatar"=>$user->getAvatar(),
@ -298,6 +300,9 @@ class TallydayController extends AbstractController
$data->setValidateuser(false);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setIstelework(false);
$data->setIspenaltyactive(false);
$data->setIspenaltypassive(false);
// Création du formulaire
$form = $this->createForm(Form::class,$data);
@ -517,6 +522,9 @@ class TallydayController extends AbstractController
$data->setValidateuser(true);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setIstelework(false);
$data->setIspenaltyactive(false);
$data->setIspenaltypassive(false);
$em->persist($data);
$em->flush();
@ -567,6 +575,9 @@ class TallydayController extends AbstractController
$data->setValidateuser(false);
$data->setValidatemaster(true);
$data->setIsbreakday(false);
$data->setIstelework(false);
$data->setIspenaltyactive(false);
$data->setIspenaltypassive(false);
$em->persist($data);
$em->flush();
@ -709,6 +720,9 @@ class TallydayController extends AbstractController
"avatar"=>$user->getAvatar(),
"displayname"=>$user->getDisplayname(),
"timemonth"=>"00:00",
"timetelework"=>"00:00",
"timepenaltypassive"=>"00:00",
"timepenaltyactive"=>"00:00",
"validates"=>[],
];
@ -724,6 +738,15 @@ class TallydayController extends AbstractController
$emonth = new \DateTime('00:00');
$fmonth = clone $emonth;
$eteleworkmonth = new \DateTime('00:00');
$fteleworkmonth = clone $eteleworkmonth;
$epenaltypassivemonth = new \DateTime('00:00');
$fpenaltypassivemonth = clone $epenaltypassivemonth;
$epenaltyactivemonth = new \DateTime('00:00');
$fpenaltyactivemonth = clone $epenaltyactivemonth;
while($datenow<=$dateend) {
$eday = new \DateTime('00:00');
@ -733,6 +756,15 @@ class TallydayController extends AbstractController
foreach($datas as $data) {
$emonth->add($data->getTimeday());
$eday->add($data->getTimeday());
if($data->getIstelework())
$eteleworkmonth->add($data->getTimeday());
if($data->getIspenaltypassive())
$epenaltypassivemonth->add($data->getTimeday());
if($data->getIspenaltyactive())
$epenaltyactivemonth->add($data->getTimeday());
}
$interval = $fday->diff($eday);
@ -750,6 +782,18 @@ class TallydayController extends AbstractController
$interval = $fmonth->diff($emonth);
$timemonth = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
$dates[$user->getId()]["timemonth"]=$timemonth;
$interval = $fteleworkmonth->diff($eteleworkmonth);
$timemonth = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
$dates[$user->getId()]["timetelework"]=$timemonth;
$interval = $fpenaltypassivemonth->diff($epenaltypassivemonth);
$timemonth = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
$dates[$user->getId()]["timepenaltypassive"]=$timemonth;
$interval = $fpenaltyactivemonth->diff($epenaltyactivemonth);
$timemonth = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
$dates[$user->getId()]["timepenaltyactive"]=$timemonth;
}
}
@ -779,7 +823,6 @@ class TallydayController extends AbstractController
$appAlias=$this->getParameter("appAlias");
$render=str_replace("/$appAlias/","https://$appWeburl/$appAlias/",$render);
//dump($render);
$this->knpSnappy->generateFromHtml($render,$fileloc);
return $this->file($fileloc);
@ -839,7 +882,7 @@ class TallydayController extends AbstractController
return $response;
}
public function start() {
public function start(bool $istelework,bool $ispenaltypassive,bool $ispenaltyactive) {
$em = $this->getDoctrine()->getManager();
$datenow=new \DateTime("now");
@ -856,6 +899,10 @@ class TallydayController extends AbstractController
$data->setValidateuser(false);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setIstelework($istelework);
$data->setIspenaltyactive($ispenaltyactive);
$data->setIspenaltypassive($ispenaltypassive);
$data->setDatestart($datenow);
}
@ -871,7 +918,7 @@ class TallydayController extends AbstractController
}
public function end() {
public function end(bool $istelework,bool $ispenaltypassive,bool $ispenaltyactive) {
$em = $this->getDoctrine()->getManager();
// On recherche le dernier pointage de la journée
@ -898,6 +945,10 @@ class TallydayController extends AbstractController
}
$data->setDateend($datenow);
$data->setIstelework($istelework);
$data->setIspenaltyactive($ispenaltyactive);
$data->setIspenaltypassive($ispenaltypassive);
$em->persist($data);
$em->flush();
@ -965,7 +1016,7 @@ class TallydayController extends AbstractController
protected function getErrorForm($id,$form,$request,$data,$mode) {
$em = $this->getDoctrine()->getManager();
if(!$em->getRepository("App:Tallyday")->ctrlTallyday($data->getUser(),$data->getDateof()));
if(!$em->getRepository("App:Tallyday")->ctrlTallyday($data->getUser(),$data->getDateof()))
$form->addError(new FormError("Impossible d'entamer une journée sans avoir terminé les jours précédents"));
if ($form->get('submit')->isClicked()) {

View File

@ -52,6 +52,21 @@ class Tallyday
*/
private $isbreakday;
/**
* @ORM\Column(type="boolean")
*/
private $istelework;
/**
* @ORM\Column(type="boolean")
*/
private $ispenaltypassive;
/**
* @ORM\Column(type="boolean")
*/
private $ispenaltyactive;
/**
* @ORM\Column(type="string", nullable=true)
*/
@ -181,6 +196,42 @@ class Tallyday
return $this;
}
public function getIstelework(): ?bool
{
return $this->istelework;
}
public function setIstelework(bool $istelework): self
{
$this->istelework = $istelework;
return $this;
}
public function getIspenaltypassive(): ?bool
{
return $this->ispenaltypassive;
}
public function setIspenaltypassive(bool $ispenaltypassive): self
{
$this->ispenaltypassive = $ispenaltypassive;
return $this;
}
public function getIspenaltyactive(): ?bool
{
return $this->ispenaltyactive;
}
public function setIspenaltyactive(bool $ispenaltyactive): self
{
$this->ispenaltyactive = $ispenaltyactive;
return $this;
}
}

View File

@ -52,6 +52,30 @@ class TallydayType extends AbstractType
"attr" => ["class"=>"timepicker"],
]
);
$choices=["non" => "0","oui" => "1"];
$builder->add("istelework",
ChoiceType::class,[
"label" =>"En Télétravail ?",
"choices" => $choices
]
);
$choices=["non" => "0","oui" => "1"];
$builder->add("ispenaltypassive",
ChoiceType::class,[
"label" =>"En Astreinte passive ?",
"choices" => $choices
]
);
$choices=["non" => "0","oui" => "1"];
$builder->add("ispenaltyactive",
ChoiceType::class,[
"label" =>"En Astreinte active ?",
"choices" => $choices
]
);
}
public function configureOptions(OptionsResolver $resolver)

View File

@ -37,7 +37,7 @@ class TimeextraType extends AbstractType
$builder->add('hour',
IntegerType::class, [
"label" => "Nombre d'Heure",
"label" => "Nombre de Minutes",
"required" => true,
]
);

View File

@ -65,17 +65,20 @@ class TallydayRepository extends ServiceEntityRepository
}
public function getCapitaltimeinterval($user,$getnovalidate=false) {
$datenow=new \DateTime('00:00');
$datas = $this->_em->getRepository('App:Tallyday')->findBy(["user"=>$user],["datestart"=>"DESC"]);
$tbdays=[];
$ework = new \DateTime('00:00');
// Cumuler les temps de travail sans fuseau
$datenow=new \DateTime('00:00');
$ework = new \DateTime('00:00', new \DateTimeZone('UTC'));
$i=0;
foreach($datas as $data) {
if($data->getDateof()<$datenow) {
$iddayweek=$data->getDateof()->format("w");
if($iddayweek>=1&&$iddayweek<=5) {
if(!in_array($data->getDateof(),$tbdays)) array_push($tbdays,$data->getDateof());
}
$ework->add($data->getTimeday());
}
@ -84,19 +87,21 @@ class TallydayRepository extends ServiceEntityRepository
if($iddayweek>=1&&$iddayweek<=5) {
if(!in_array($data->getDateof(),$tbdays)) array_push($tbdays,$data->getDateof());
}
$ework->add($data->getTimeday());
}
}
// Enlever du temps travailler les heures sup payé
// Enlever du temps travailler les minutes sup payé
$timeextra=$this->_em->getRepository("App:Timeextra")->getTimeextrauser($user, new \DateTime());
if($timeextra[1]) {
$ework->sub(new \DateInterval("PT".$timeextra[1]."H"));
$ework->sub(new \DateInterval("PT".$timeextra[1]."M"));
}
// Nbday worked
$nbdaywork=count($tbdays);
$etowork = new \DateTime('00:00');
$etowork = new \DateTime('00:00', new \DateTimeZone('UTC'));
$etowork->add(new \DateInterval("PT".($nbdaywork*7)."H"));
$interval = $etowork->diff($ework);

View File

@ -81,19 +81,27 @@
{% block localjavascript %}
$(document).ready(function() {
/*
$('.timepicker').timepicki({
show_meridian:false,
min_hour_value:0,
max_hour_value:23,
step_size_minutes:5,
overflow_minutes:true,
increase_direction:'up',
disable_keyboard_mobile: true,
reset: true
$("#tallyday_istelework").change(function(){
if($("#tallyday_istelework").val()==1) {
$("#tallyday_ispenaltypassive").val(0);
$("#tallyday_ispenaltyactive").val(0);
}
});
*/
$("#tallyday_ispenaltypassive").change(function(){
if($("#tallyday_ispenaltypassive").val()==1) {
$("#tallyday_istelework").val(0);
$("#tallyday_ispenaltyactive").val(0);
}
});
$("#tallyday_ispenaltyactive").change(function(){
if($("#tallyday_ispenaltyactive").val()==1) {
$("#tallyday_ispenaltypassive").val(0);
$("#tallyday_istelework").val(0);
}
});
$('.timepicker').timepicker({
timeFormat: 'HH:mm',
interval:5,

View File

@ -6,7 +6,7 @@ th, td {
color: #ffffff;
background-color: #37474F;
text-align: center;
width: 100px;
width: 115px;
}
td {
@ -44,7 +44,7 @@ td {
</div>
{% endif %}
<div class="mt-3" style="margin:auto; max-width:1800px;">
<div class="mt-3" style="margin:auto; max-width:2035px;">
{% for date in dates %}
{% if date.validates or date.notvalidates %}
<div class="card mr-1 mb-1 float-left">
@ -93,6 +93,16 @@ td {
{% else %}
{%if tallyday.datestart %} de {{tallyday.datestart|date("H:i") }} {% endif %}
{%if tallyday.dateend %} à {{tallyday.dateend|date("H:i") }} {% endif %}
{% if tallyday.istelework %}
<i class="fas fa-home" title="Télétravail"></i>
{% endif %}
{% if tallyday.ispenaltypassive %}
<i class="fas fa-glasses" title="Astreinte Passive"></i>
{% endif %}
{% if tallyday.ispenaltyactive %}
<i class="fas fa-fire" title="Astreinte Active"></i>
{% endif %}
{%endif%}
<br>
{% endfor %}
@ -137,6 +147,15 @@ td {
<a href="{{path("app_tallyday_masterupdate",{id:tallyday.id})}}">
{%if tallyday.datestart %} de {{tallyday.datestart|date("H:i") }} {% endif %}
{%if tallyday.dateend %} à {{tallyday.dateend|date("H:i") }} {% endif %}
{% if tallyday.istelework %}
<i class="fas fa-home" title="Télétravail"></i>
{% endif %}
{% if tallyday.ispenaltypassive %}
<i class="fas fa-glasses" title="Astreinte Passive"></i>
{% endif %}
{% if tallyday.ispenaltyactive %}
<i class="fas fa-fire" title="Astreinte Active"></i>
{% endif %}
</a>
{% endif %}
<br>

View File

@ -6,7 +6,7 @@ th, td {
color: #ffffff;
background-color: #37474F;
text-align: center;
width: {% if fgprint %}120px{%else%}100px{%endif%};
width: {% if fgprint %}135px{%else%}115px{%endif%};
padding: 0px;
}
@ -19,13 +19,21 @@ td {
{% if fgprint %}color:#000000 !important;{%endif%}
}
{% if fgprint %}
@media print {
.noprint { display:none; }
body,h1,.card-header {font-family: 'arial' !important}
.card {float: none !important; }
.card, .card-header {border: none;}
.breakpage {
page-break-after: always;
}
{% endif %}
.nobreakpage{
page-break-after: unset;
}
.card-body {padding:0px;}
.fulltable{width:100%;}
}
.date {
color: #ffffff;
@ -43,40 +51,43 @@ td {
RAPPORT MENSUEL = {{ monthof|date("m/Y") }}
</h1>
<div class="noprint">
{% if not fgprint %}
<a class="btn btn-secondary mr-2" href={{ path('app_tallyday') }}>Retour</a>
<a class="btn btn-secondary mr-2" href={{ path('app_tallyday_mastermonth',{monthof:prevmonth}) }}>Mois Précédent</a>
<a class="btn btn-secondary mr-2" href={{ path('app_tallyday_mastermonth',{monthof:nextmonth}) }}>Mois Suivant</a>
<a class="btn btn-secondary mr-2" href={{ path('app_tallyday_mastermonth',{monthof:monthof|date("Ym"),type:"pdf"}) }}>Export PDF</a>
<a class="btn btn-secondary mr-2" href={{ path('app_tallyday') }}>Retour</a>
<a class="btn btn-secondary mr-2" href={{ path('app_tallyday_mastermonth',{monthof:prevmonth}) }}>Mois Précédent</a>
<a class="btn btn-secondary mr-2" href={{ path('app_tallyday_mastermonth',{monthof:nextmonth}) }}>Mois Suivant</a>
<!-- <a class="btn btn-secondary mr-2" href={{ path('app_tallyday_mastermonth',{monthof:monthof|date("Ym"),type:"pdf"}) }}>Export PDF</a> -->
<a id="btnprint" class="btn btn-secondary mr-2" href="#">Imprimer</a>
<a class="btn btn-secondary float-right" href={{ path('app_tallyday_masterexport') }}>Export CSV</a>
<a class="btn btn-secondary float-right mr-2" href={{ path('app_tallyday_masterlist') }}>Gestion des Pointages</a>
<a class="btn btn-secondary float-right mr-2" href={{ path('app_timeextra') }}>Gestion Heures Sup</a>
{% if message is defined and not message is empty %}
<div class='alert alert-danger' style='margin: 5px 0px'>
<strong>Erreur</strong><br>
{{ message|raw }}<br>
</div>
{% endif %}
<a class="btn btn-secondary float-right" href={{ path('app_tallyday_masterexport') }}>Export CSV</a>
<a class="btn btn-secondary float-right mr-2" href={{ path('app_tallyday_masterlist') }}>Gestion des Pointages</a>
<a class="btn btn-secondary float-right mr-2" href={{ path('app_timeextra') }}>Gestion Heures Sup</a>
{% if message is defined and not message is empty %}
<div class='alert alert-danger' style='margin: 5px 0px'>
<strong>Erreur</strong><br>
{{ message|raw }}<br>
</div>
{% endif %}
{% endif %}
</div>
<div class="mt-3" style="margin:auto; max-width:1800px;">
<div class="mt-3" style="margin:auto; max-width:1810px;">
{% set nbusers=0 %}
{% for date in dates %}
{% if date.validates %}
{% set nbusers=nbusers+1 %}
<div class="card mr-1 mb-1 float-left {% if nbusers==2 %}breakpage{% endif %} ">
<div class="card mr-1 mb-1 float-left {% if nbusers==2 %}breakpage{%else%}nobreakpage{% endif %} ">
<div class="card-header">
<img src="{{date.avatar|urlavatar}}" class="avatar"> {{ date.displayname }}
<div class="float-right">
{% if not fgprint %} <img src="{{date.avatar|urlavatar}}" class="avatar noprint">{%endif%} {{ date.displayname }}
<div class="float-right text-right">
{{date.timemonth}} / {{ timetowork }}
</div>
</div>
<div class="card-body">
<table>
<table class="fulltable">
<thead>
<tr>
<th style="width:50px !important">s</th>
@ -104,13 +115,14 @@ td {
{{validate.dateof|date("W")}}
</td>
{% if loop.first %}
{% for i in 2..(validate.dateof|date("N")) %}
<td></td>
{% endfor %}
{%endif %}
{% endif %}
{% if loop.first and validate.dateof|date("l")!="Monday"%}
{% for i in 2..(validate.dateof|date("N")) %}
<td></td>
{% endfor %}
{%endif %}
<td style="align:top">
<div class="date">{{validate.dateof|date("d/m")}}</div>
<div class="datedetail" style="min-height:28px">
@ -123,6 +135,17 @@ td {
{% else %}
{%if tallyday.datestart %} de {{tallyday.datestart|date("H:i") }} {% endif %}
{%if tallyday.dateend %} à {{tallyday.dateend|date("H:i") }} {% endif %}
{% if tallyday.istelework %}
<i class="fas fa-home" title="Télétravail"></i>
{% endif %}
{% if tallyday.ispenaltypassive %}
<i class="fas fa-glasses" title="Astreinte Passive"></i>
{% endif %}
{% if tallyday.ispenaltyactive %}
<i class="fas fa-fire" title="Astreinte Active"></i>
{% endif %}
{%endif%}
<br>
{% endfor %}
@ -139,6 +162,27 @@ td {
{% endfor %}
</tbody>
</table>
{%if date.timetelework!="0:00" or date.timepenaltypassive!="0:00" or date.timepenaltyactive!="0:00" %}
<div class="mt-3" style="font-family:var(--fontbody)">
<table><tr>
{% endif %}
{%if date.timetelework!="0:00"%}
<td class="p-2" ><i class="fas fa-home fa-2x"></i><br>Télétravail<br>{{date.timetelework}}</td>
{%endif%}
{%if date.timepenaltypassive!="0:00"%}
<td class="p-2"><i class="fas fa-glasses fa-2x"></i><br>Astreinte Passive<br>{{date.timepenaltypassive}}</td>
{%endif%}
{%if date.timepenaltyactive!="0:00"%}
<td class="p-2"><i class="fas fa-fire fa-2x"></i><br>Astreinte Active<br>{{date.timepenaltyactive}}</td>
{%endif%}
{%if date.timetelework!="0:00" or date.timepenaltypassive!="0:00" or date.timepenaltyactive!="0:00" %}
</tr></table></div>
{% endif %}
</div>
</div>
@ -169,6 +213,11 @@ td {
maxheight=$(this).height();
});
$( ".card" ).height(maxheight);
$("#btnprint").click(function(){
window.print();
return false;
});
});
{% endblock %}

View File

@ -18,7 +18,7 @@
font-size: 40px;
text-align: center;
line-height:30px;
width:250px;
width:300px;
border-radius: 0.25rem;
}
.clock small {
@ -27,11 +27,11 @@
}
.alert {
width:250px;
width:300px;
}
.tallydaydetail {
width:250px;
width:300px;
text-align: left;
margin-top: 20px;
}
@ -61,12 +61,10 @@
{% if not tallydays or not tallydays|last.dateend is null %}
{% if not isvalideuser and not isvalidemaster %}
<a href="{{path("app_tallyday_start")}}" class="btn btn-success" style="font-size:150%; width:250px;">Début Pointage</a>
<bouton id="btnstart" class="btn btn-success" style="font-size:220%; width:300px;">Début Pointage</bouton>
{% endif %}
{% elseif not isvalideuser and not isvalidemaster %}
<a href="{{path("app_tallyday_end")}}" class="btn btn-success" style="font-size:150%; width:250px;">Fin Pointage</a>
<bouton id="btnend" class="btn btn-success" style="font-size:220%; width:300px;">Fin Pointage</bouton>
{% endif %}
<div class="tallydaydetail">
@ -76,16 +74,24 @@
<th>Début</th>
<th>Fin</th>
<th>Temps</th>
<th></th>
</tr>
</thead>
<tbody>
{% set isvalideuser=false %}
{% set isvalidemaster=false %}
{% set istelework=false %}
{% set ispenaltypassive=false %}
{% set ispenaltyactive=false %}
{% for tallyday in tallydays %}
{% set isvalideuser=tallyday.validateuser %}
{% set isvalidemaster=tallyday.validatemaster %}
{% set istelework=tallyday.istelework %}
{% set ispenaltypassive=tallyday.ispenaltypassive %}
{% set ispenaltyactive=tallyday.ispenaltyactive %}
{% if tallyday.datestart %}
<tr>
{% if tallyday.isbreakday %}
@ -103,6 +109,17 @@
</td>
{% endif %}
<td>{{tallyday.timedayformatted}}</td>
<td>
{% if tallyday.istelework %}
<i class="fas fa-home" title="Télétravail"></i>
{% endif %}
{% if tallyday.ispenaltypassive %}
<i class="fas fa-glasses" title="Astreinte Passive"></i>
{% endif %}
{% if tallyday.ispenaltyactive %}
<i class="fas fa-fire" title="Astreinte Active"></i>
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
@ -122,20 +139,37 @@
</div>
{% if not isvalideuser and not isvalidemaster %}
<a href="{{path("app_tallyday_uservalidate",{dateof:"now"|date("Y-m-d")})}}" class="btn btn-danger mt-3" style="width:380px" data-method="confirm" data-confirm="Êtes-vous sûr de vouloir valider votre journée ?">Valider ma journée</a>
<div style="width:300px; text-align:left">
<div class="custom-control custom-switch" style="zoom:130%">
<input type="checkbox" class="custom-control-input" id="istelework" {%if istelework%}checked{%endif%}>
<label class="custom-control-label" for="istelework">Télétravail</label>
</div>
<div class="custom-control custom-switch" style="zoom:130%">
<input type="checkbox" class="custom-control-input" id="ispenaltypassive" {%if ispenaltypassive%}checked{%endif%}>
<label class="custom-control-label" for="ispenaltypassive">Astreinte Passive</label>
</div>
<div class="custom-control custom-switch" style="zoom:130%">
<input type="checkbox" class="custom-control-input" id="ispenaltyactive" {%if ispenaltyactive%}checked{%endif%}>
<label class="custom-control-label" for="ispenaltyactive">Astreinte Active</label>
</div>
</div>
<a href="{{path("app_tallyday_uservalidate",{dateof:"now"|date("Y-m-d")})}}" class="btn btn-danger mt-3" style="width:300px" data-method="confirm" data-confirm="Êtes-vous sûr de vouloir valider votre journée ?">Valider ma journée</a>
<br>
{% endif %}
<a href="{{path("app_tallyday_userlist")}}" class="btn btn-secondary mt-3" style="width:380px">Gérer mes Pointages</a>
<a href="{{path("app_tallyday_userlist")}}" class="btn btn-secondary mt-3" style="width:300px">Gérer mes Pointages</a>
{% if isvalideuser and not isvalidemaster %}
<br><a href="{{path("app_tallyday_userdevalidate",{dateof:"now"|date("Y-m-d")})}}" class="btn btn-warning mt-3" style="width:380px">Dévalider ma journée</a>
<br><a href="{{path("app_tallyday_userdevalidate",{dateof:"now"|date("Y-m-d")})}}" class="btn btn-warning mt-3" style="width:300px">Dévalider ma journée</a>
{% endif %}
{% if is_granted('ROLE_MASTER') %}
<hr class="mt-5" style="width: 300px; background-color:var(--colorbgbodylight);">
<h3>GESTION</h3>
<a href="{{path("app_tallyday_masterlist")}}" class="btn btn-success mt-3" style="width:380px">Gestion des Pointages</a>
<a href="{{path("app_tallyday_masterlist")}}" class="btn btn-success mt-3 mb-3" style="width:300px">Gestion des Pointages</a>
{% endif %}
@ -149,6 +183,59 @@
var nextrecalcul=new Date();
var firstrecalcul=true;
$('#istelework').change(function() {
if($("#istelework").is(":checked")) {
$("#ispenaltyactive").prop("checked",false);
$("#ispenaltypassive").prop("checked",false);
}
});
$('#ispenaltypassive').change(function() {
if($("#ispenaltypassive").is(":checked")) {
$("#istelework").prop("checked",false);
$("#ispenaltyactive").prop("checked",false);
}
});
$('#ispenaltyactive').change(function() {
if($("#ispenaltyactive").is(":checked")) {
$("#istelework").prop("checked",false);
$("#ispenaltypassive").prop("checked",false);
}
});
$("#btnstart").click(function() {
istelework=0;
ispenaltypassive=0;
ispenaltyactive=0;
if($("#istelework").is(":checked")) istelework=1;
if($("#ispenaltypassive").is(":checked")) ispenaltypassive=1;
if($("#ispenaltyactive").is(":checked")) ispenaltyactive=1;
url="{{ path("app_tallyday_start",{istelework:'xxx',ispenaltypassive:'yyy',ispenaltyactive:'zzz'}) }}";
url=url.replace('xxx',istelework);
url=url.replace('yyy',ispenaltypassive);
url=url.replace('zzz',ispenaltyactive);
document.location.href=url;
});
$("#btnend").click(function() {
istelework=0;
ispenaltypassive=0;
ispenaltyactive=0;
if($("#istelework").is(":checked")) istelework=1;
if($("#ispenaltypassive").is(":checked")) ispenaltypassive=1;
if($("#ispenaltyactive").is(":checked")) ispenaltyactive=1;
url="{{ path("app_tallyday_end",{istelework:'xxx',ispenaltypassive:'yyy',ispenaltyactive:'zzz'}) }}";
url=url.replace('xxx',istelework);
url=url.replace('yyy',ispenaltypassive);
url=url.replace('zzz',ispenaltyactive);
document.location.href=url;
});
function showTime(){
// to get current time/ date.
var date = new Date();

View File

@ -87,6 +87,17 @@
{%endif%}
{% endif %}
= {{tallyday.timedayformatted}}
{% if tallyday.istelework %}
<i class="fas fa-home" title="Télétravail"></i>
{% endif %}
{% if tallyday.ispenaltypassive %}
<i class="fas fa-glasses" title="Astreinte Passive"></i>
{% endif %}
{% if tallyday.ispenaltyactive %}
<i class="fas fa-fire" title="Astreinte Active"></i>
{% endif %}
<br>
{% endif %}
{% endfor %}

View File

@ -28,7 +28,7 @@ GESTION DES HEURES SUPPLEMENTAIRES
<th width="70px" class="no-sort">Action</th>
<th>Utilisateur</th>
<th>Date</th>
<th>Nb Heure</th>
<th>Nb Minutes</th>
</tr>
</thead>
<tbody>