This commit is contained in:
afornerot 2022-02-21 09:36:27 +01:00
parent 8b0c3e95b4
commit 8170e02dab
15 changed files with 354 additions and 36 deletions

View File

@ -1,15 +1,11 @@
# Read the documentation: https://symfony.com/doc/master/bundles/FOSRestBundle/index.html
fos_rest: null
# param_fetcher_listener: true
# allowed_methods_listener: true
# routing_loader: true
# view:
# view_response_listener: true
# exception:
# codes:
# App\Exception\MyException: 403
# messages:
# App\Exception\MyException: Forbidden area.
# format_listener:
# rules:
# - { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json, html ] }
fos_rest:
param_fetcher_listener: true
body_listener: true
format_listener:
enabled: true
rules:
- { path: '/rest', priorities: ['json', 'xml'], fallback_format: 'html' }
- { path: '/', fallback_format: 'html' }

View File

@ -1,9 +1,9 @@
nelmio_api_doc:
documentation:
info:
title: My App
description: This is an awesome app!
title: '%appName%'
description:
version: 1.0.0
areas: # to filter documented areas
path_patterns:
- ^/api(?!/doc$) # Accepts routes under /api except /api/doc
- /rest # Accepts routes under /rest except /rest/doc

View File

@ -60,7 +60,11 @@ app_config_delete:
app_config_logo:
path: /admin/config/logo
defaults: { _controller: App\Controller\ConfigController:logo }
app_config_frame:
path: /admin/config/frame
defaults: { _controller: App\Controller\ConfigController:frame }
#== Theme ================================================================================================================
app_theme:
path: /admin/theme
@ -209,6 +213,10 @@ app_tallyday_userdevalidate:
path: /user/devalidate/{{dateof}}
defaults: { _controller: App\Controller\TallydayController:userdevalidate }
app_tallyday_userrecalcul:
path: /user/recalcul
defaults: { _controller: App\Controller\TallydayController:userrecalcul }
app_tallyday_masterlist:
path: /master/tallydays
defaults: { _controller: App\Controller\TallydayController:mastertallydays }

View File

@ -1,8 +1,8 @@
# Expose your documentation as JSON swagger compliant
app.swagger:
path: /api/doc.json
app_swagger_ui:
path: /rest
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger }
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
## Requires the Asset component and the Twig bundle
## $ composer require twig asset

View File

@ -103,4 +103,6 @@ services:
- [setContainer, ["@service_container"]]
tags:
- { name: twig.extension }
App\Controller\RestController:
public: true

View File

@ -97,6 +97,16 @@ class ConfigController extends AbstractController
return $this->render($this->render.'logo.html.twig');
}
public function frame(Request $request)
{
$url=$request->query->get('url');
return $this->render($this->render.'frame.html.twig' ,[
'useheader' => true,
'usesidebar' => true,
'url' => $url,
]);
}
protected function getErrorForm($id,$form,$request,$data) {
if ($form->get('submit')->isClicked() && !$form->isValid()) {
$this->get('session')->getFlashBag()->clear();

View File

@ -0,0 +1,114 @@
<?php
namespace App\Controller;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\Annotations as FOSRest;
use Swagger\Annotations as SWG;
use App\Entity\Tallyday as Tallyday;
class RestController extends AbstractFOSRestController
{
private $output=[];
private $cpt;
/**
* Start / Stop timer
*
*
* @FOSRest\Post("/rest/timer")
* @SWG\Response(
* response=200,
* description="Start / Stop Timer"
* )
* )
* @SWG\Parameter(
* name="key",
* in="formData",
* required=true,
* description="User APIKey",
* type="string"
* )
*/
public function timer(Request $request) {
set_time_limit(0);
ini_set('memory_limit', '1024M');
// Initalisation Manager
$em = $this->getDoctrine()->getManager();
// Récupération des parametres
$key=$request->get("key");
// 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);
}
$datenow=new \DateTime("now");
$datenow->setTime ( $datenow->format("H"), $datenow->format("i"), 0 );
// On recherche le dernier pointage de la journée
$data = $em->getRepository("App:Tallyday")->findOneBy(["user"=>$user,"dateof"=>$datenow],["datestart"=>"DESC"]);
// Si pas d'entrée ou si la dernière entrée à une date de fin, c'est que l'on ouvre un créneau
if(!$data||$data->getDateend()) {
$data = new Tallyday();
$data->setDateof(new \DateTime("now"));
$data->setUser($this->getUser());
$data->setValidateuser(false);
$data->setValidatemaster(false);
$data->setIsbreakday(false);
$data->setDatestart($datenow);
}
// Sinon c'est que l'on ferme un creneau
elseif($data) {
$data->setDateend($datenow);
}
// Sinon pas normal
else {
$view = $this->view("Incohérence dans vos créneaux horaires", 404);
return $this->handleView($view);
}
// On vérifie quand meme la cohérance des crénaux
if(!$em->getRepository("App:Tallyday")->vefifTallytime($data)) {
$view = $this->view("Incohérence dans vos créneaux horaires", 404);
return $this->handleView($view);
}
// C'est ok on fluh
$em->persist($data);
$em->flush();
// Calcul du temps de la journée
$datas = $em->getRepository("App:Tallyday")->findTallyday($user,clone $datenow);
$e = new \DateTime('00:00');
$f = clone $e;
foreach($datas as $data) {
$e->add($data->getTimeday());
}
$interval = $f->diff($e);
$timeday = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
$output = [
"timeday" => $timeday,
"capitaltime" => $em->getRepository("App:Tallyday")->getCapitaltime($user),
];
$view = $this->view($output, 200);
return $this->handleView($view);
}
}

View File

@ -531,9 +531,10 @@ class TallydayController extends AbstractController
// Validation
$data->setValidateuser(true);
$em->persist($data);
$em->flush();
}
$em->flush();
if($request->get("from")=="list")
return $this->redirectToRoute("app_tallyday_userlist",["week"=>$request->get("week")]);
else
@ -680,6 +681,21 @@ class TallydayController extends AbstractController
}
public function mastermonth($monthof, Request $request) {
// On calcul le nombre de jour ouvrable dans le mois
$datenow=new \DateTime($monthof."01");
$dateend=clone $datenow;
$dateend->modify("last day of this month");
$nbopendays=0;
while ($datenow <= $dateend) {
// jour différent de samedi et dimanche
if($datenow->format("w")!=0&&$datenow->format("w")!=6)
$nbopendays++;
$datenow->add(new \DateInterval('P1D'));
}
$timetowork=($nbopendays*7).":00";
// Pour l'ensemble des utlisateurs
$em = $this->getDoctrine()->getManager();
$users = $em->getRepository("App:User")->findBy([],["firstname"=>"ASC","lastname"=>"ASC"]);
@ -731,8 +747,8 @@ class TallydayController extends AbstractController
}
$interval = $fmonth->diff($emonth);
$timeweek = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
$dates[$user->getId()]["timemonth"]=$timeweek;
$timemonth = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
$dates[$user->getId()]["timemonth"]=$timemonth;
}
}
@ -752,6 +768,7 @@ class TallydayController extends AbstractController
"monthof" => $dateend,
"nextmonth" => $nextmonth->format("Ym"),
"prevmonth" => $prevmonth->format("Ym"),
"timetowork" => $timetowork,
"dates" => $dates,
"fgprint" => true,
"message" => $request->get("message"),
@ -775,6 +792,7 @@ class TallydayController extends AbstractController
"monthof" => $dateend,
"nextmonth" => $nextmonth->format("Ym"),
"prevmonth" => $prevmonth->format("Ym"),
"timetowork" => $timetowork,
"dates" => $dates,
"fgprint" => false,
"message" => $request->get("message"),
@ -878,6 +896,63 @@ class TallydayController extends AbstractController
return $this->redirectToRoute("app_tallyday");
}
public function userrecalcul() {
$em = $this->getDoctrine()->getManager();
// On recherche le dernier pointage de la journée
$datenow=new \DateTime("now");
$datenow->setTime ( $datenow->format("H"), $datenow->format("i"), 0 );
$datas = $em->getRepository($this->entity)->findTallyday($this->getUser(),clone $datenow);
// Cumul des temps de la journée
$e = new \DateTime('00:00');
$f = clone $e;
foreach($datas as $data) {
$e->add($data->getTimeday());
}
// On recherche le dernier pointage de la journée non terminé et on simule le créneau avec la date du moment
$data = $em->getRepository($this->entity)->findOneBy(["user"=>$this->getUser(),"dateof"=>$datenow],["datestart"=>"DESC"]);
if($data&&$data->getDatestart()&&!$data->getDateend()) {
$interval2 = $datenow->diff($data->getDatestart());
$e->add($interval2);
}
// Calcul de temps global de la journée = réel + simulé
$interval = $e->diff($f);
$timeday = $interval->format("%R").(($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
// On récupère le capital
$capital=$em->getRepository("App:Tallyday")->getCapitaltimeinterval($this->getUser());
$e = new \DateTime('00:00');
// Si la journée n'est finalisé on ajoute le créneau simulé
if($data&&$data->getDatestart()&&!$data->getDateend()) {
$f = new \DateTime('00:00');
$f->add($interval);
$f->sub(new \DateInterval('PT7H'));
$f->add($capital);
}
// Si la journée n'est pas encore validé : on ajoute la journée à la simulation
else if($data && (!$data->getValidateuser()||!$data->getValidateuser())) {
$f = new \DateTime('00:00');
$f->add($interval);
$f->sub(new \DateInterval('PT7H'));
$f->add($capital);
}
$interval = $e->diff($f);
$newcapital = $interval->format("%R").(($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
return new JsonResponse([
'success' => true,
'tosimulatetime' => ($data&&$data->getDatestart()&&!$data->getDateend()),
'timeday' => $timeday,
'tosimulatecapital' => ($data&&(!$data->getValidateuser()||!$data->getValidateuser())),
'capital' => $newcapital,
]);
}
protected function getErrorForm($id,$form,$request,$data,$mode) {

View File

@ -51,7 +51,7 @@ class TallydayRepository extends ServiceEntityRepository
return $datas;
}
public function getCapitaltime($user,$monthof=null) {
public function getCapitaltimeinterval($user) {
$datenow=new \DateTime('00:00');
$datas = $this->_em->getRepository('App:Tallyday')->findBy(["user"=>$user],["datestart"=>"DESC"]);
$tbweek=[];
@ -87,13 +87,20 @@ class TallydayRepository extends ServiceEntityRepository
$etowork = new \DateTime('00:00');
$etowork->sub(new \DateInterval("PT".($nbdaywork*7)."H"));
$interval = $etowork->diff($ework);
$timeday = (($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
if($ework>$etowork) $timeday="-".$timeday;
$interval = $ework->diff($etowork);
return $interval;
}
public function getCapitaltime($user) {
$interval=$this->getCapitaltimeinterval($user);
$timeday = $interval->format("%R").(($interval->days*24) + $interval->h).":".sprintf("%02s",$interval->i);
return $timeday;
}
public function vefifTallytime($tallyday) {
$qb = $this->createQueryBuilder('tallydate')
->Where('tallydate.user=:user')

View File

@ -0,0 +1,52 @@
{% extends "base.html.twig" %}
{% block localstyle %}
html {
height:100%;
}
body {
overflow: hidden;
height:100%;
}
#main {
padding-right: 0px;
}
.contentsidebar {
margin-left: 235px;
}
iframe {
width: 100%;
border: none;
}
{% endblock %}
{% block body %}
<iframe id="frameresized" src="{{url}}"></iframe>
{% endblock %}
{% block localjavascript %}
$(window).resize(function() {
resizeFrame();
});
$('document').ready(function(){
resizeFrame();
});
function resizeFrame() {
var heightbody = $('html').height();
var heightframe = heightbody;
if($("#frameresized").length>0) {
$("#frameresized").height(heightframe);
}
}
{% endblock %}

View File

@ -30,8 +30,15 @@
</a>
</li>
{% if appCron %}
<li class="title">Outils</li>
<li>
<a href="{{path("app_config_frame",{"url":"/"~appAlias~"/rest"})}}">
<i class="fas fa-star-of-life"></i> API Documentation
</a>
</li>
{% if appCron %}
<li>
<a href="{{path("app_cron")}}">
<i class="fa fa-cogs"></i>Jobs

View File

@ -69,6 +69,9 @@ td {
<div class="card mr-1 mb-1 float-left {% if nbusers==2 %}breakpage{% endif %} ">
<div class="card-header">
<img src="{{date.avatar|urlavatar}}" class="avatar"> {{ date.displayname }}
<div class="float-right">
{{date.timemonth}} / {{ timetowork }}
</div>
</div>
<div class="card-body">

View File

@ -64,7 +64,8 @@
<a href="{{path("app_tallyday_start")}}" class="btn btn-success" style="font-size:150%; width:250px;">Début Pointage</a>
{% 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>
<a href="{{path("app_tallyday_end")}}" class="btn btn-success" style="font-size:150%; width:250px;">Fin Pointage</a>
{% endif %}
@ -91,7 +92,15 @@
<td colspan=2>{{tallyday.name}}</td>
{% else %}
<td>{{tallyday.datestart|date("H:i")}}</td>
<td>{% if tallyday.dateend %} {{tallyday.dateend|date("H:i")}} {%endif%}</td>
<td>
{% if tallyday.dateend %}
{{tallyday.dateend|date("H:i")}}
{% else %}
{% set isrunning=true %}
{% set timedayrunning=tallyday.timeday %}
{% set datestart=tallyday.datestart %}
{%endif%}
</td>
{% endif %}
<td>{{tallyday.timedayformatted}}</td>
</tr>
@ -101,8 +110,16 @@
</table>
</div>
<div class="mt-3 mb-3" style="width:250px">Temps de travail<br><span style="font-size:150%">{{timeday}}</span></div>
<div class="mt-3 mb-3" style="width:250px">Capital Temps<br><span style="font-size:150%">{{capitaltime}}</span></div>
<div class="mt-3 mb-3" style="width:250px">
Temps de travail
<div style="font-size:150%">{{timeday}}</div>
<div id="ifstoptimeday" style="font-size:10px; margin-top: -5px"></div>
</div>
<div class="mt-3 mb-3" style="width:250px">
Capital Temps
<div style="font-size:150%">{{capitaltime}}</div>
<div id="ifstopcapitaltime" style="font-size:10px; margin-top: -5px"></div>
</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>
@ -129,10 +146,37 @@
{% block localjavascript %}
var now=new Date();
var nextrecalcul=new Date();
var firstrecalcul=true;
function showTime(){
// to get current time/ date.
var date = new Date();
moment(date).set({second:0,millisecond:0});
// Recalcul du temps de travail si running
if(firstrecalcul||moment(date).diff(moment(nextrecalcul), "minutes")!=0) {
$.ajax({
method: "POST",
url: "{{path("app_tallyday_userrecalcul")}}",
success: function(data, dataType)
{
$("#ifstoptimeday").html("");
$("#ifstopcapitaltime").html("");
if(data.success) {
if(data.tosimulatetime) $("#ifstoptimeday").html("Si fin de journée<br> >> "+data.timeday+" << ");
if(data.tosimulatecapital) $("#ifstopcapitaltime").html("Si journée validée<br> >> "+data.capital+" << ");
}
},
});
nextrecalcul=new Date();
moment(nextrecalcul).set({second:0,millisecond:0});
firstrecalcul=false;
}
// Recharger la page au cas où on change de jour
if(moment(date).diff(moment(now), "days")!=0) location.reload();

View File

@ -83,7 +83,7 @@
de {{tallyday.datestart|date("H:i")}}
{%endif%}
{% if tallyday.dateend is not null %}
de {{tallyday.dateend|date("H:i")}}
à {{tallyday.dateend|date("H:i")}}
{%endif%}
{% endif %}
= {{tallyday.timedayformatted}}