svg
This commit is contained in:
parent
8b0c3e95b4
commit
8170e02dab
|
@ -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' }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -103,4 +103,6 @@ services:
|
|||
- [setContainer, ["@service_container"]]
|
||||
tags:
|
||||
- { name: twig.extension }
|
||||
|
||||
|
||||
App\Controller\RestController:
|
||||
public: true
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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) {
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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 %}
|
|
@ -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
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue