svg
This commit is contained in:
62
templates/Breakday/edit.html.twig
Executable file
62
templates/Breakday/edit.html.twig
Executable file
@@ -0,0 +1,62 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if mode=="update" %}
|
||||
Modification JOUR FERIE
|
||||
{% elseif mode=="submit" %}
|
||||
Création JOUR FERIE
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_breakday') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_breakday_delete',{'id':breakday.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) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#breakday_name").focus();
|
||||
});
|
||||
{% endblock %}
|
78
templates/Breakday/list.html.twig
Normal file
78
templates/Breakday/list.html.twig
Normal file
@@ -0,0 +1,78 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
|
||||
{% 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">
|
||||
JOURS FERIES
|
||||
</h1>
|
||||
|
||||
<p><a class="btn btn-success" href={{ path('app_breakday_submit') }}>Ajouter</a></p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Jours Fériés
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-sort no-print">Action</th>
|
||||
<th>Ordre</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for breakday in breakdays %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_breakday_update",{id:breakday.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{breakday.start|date("Ymd")}}</td>
|
||||
<td>{{breakday.start|date("d/m/Y")}}</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: [[ 2, "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 %}
|
65
templates/Budget/edit.html.twig
Executable file
65
templates/Budget/edit.html.twig
Executable 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 %}
|
373
templates/Budget/list.html.twig
Normal file
373
templates/Budget/list.html.twig
Normal file
@@ -0,0 +1,373 @@
|
||||
{% 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%}
|
||||
.group td, .tbsynthese .tdtotalgene {
|
||||
font-size:120%;
|
||||
text-transform: uppercase;
|
||||
background-color:#212529;
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
.total td{
|
||||
font-size:120%;
|
||||
background-color:#cdcdcd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tbsynthese .tbhide {display:none}
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
BUDGET
|
||||
</h1>
|
||||
|
||||
<div class="form-group ">
|
||||
<label class="control-label" for="project_active">Exercice</label>
|
||||
|
||||
<select id="exercice" class="form-control">
|
||||
{% for year in years %}
|
||||
{% set selected=""%}
|
||||
{% if year.id==n2.id%}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{year.id}}" {{selected}}>{{year.start|date("m/Y")}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Budget Synthèse
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-bordered tbsynthese" id="dataTables" style="width:100%; zoom:70%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan=2>Domaine</th>
|
||||
<th rowspan=2 class="tbhide">Projet</th>
|
||||
<th class="text-center" style="width:150px" colspan=2>{{n1.start|date("m/Y")}}</th>
|
||||
<th class="text-center" style="width:150px" colspan=2>{{n2.start|date("m/Y")}}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th width="20px" class="no-sort no-print tbhide"></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 tbhide"></th>
|
||||
<th class="text-center" style="width:150px">Réel</th>
|
||||
<th class="text-center" style="width:150px">Budget</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tbsynthesebody">
|
||||
<tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Budget
|
||||
</div>
|
||||
|
||||
{% set totdayrealn1 = 0 %}
|
||||
{% set totetprealn1 = 0 %}
|
||||
{% set totcaarealn1 = 0 %}
|
||||
{% set totdaybudgn1 = 0 %}
|
||||
{% set totetpbudgn1 = 0 %}
|
||||
{% set totcaabudgn1 = 0 %}
|
||||
|
||||
{% set totdayrealn2 = 0 %}
|
||||
{% set totetprealn2 = 0 %}
|
||||
{% set totcaarealn2 = 0 %}
|
||||
{% set totdaybudgn2 = 0 %}
|
||||
{% set totetpbudgn2 = 0 %}
|
||||
{% set totcaabudgn2 = 0 %}
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-bordered tbdetail" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan=2>Domaine</th>
|
||||
<th rowspan=2 class="tbhide">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 tbhide"></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 tbhide"></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 class="tbhide">{{project.name}}</td>
|
||||
|
||||
<td class="text-center tbhide">
|
||||
<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 tbhide">
|
||||
<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,returnto:n2.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,returnto: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 class="total" data-domaine="{{domaine.name}}">
|
||||
<td>{{domaine.name}}</td>
|
||||
<td class="tbhide" >TOTAL</td>
|
||||
|
||||
<td class="no-print tbhide"> </td>
|
||||
<td class="text-center">
|
||||
{{domaine.nbdayrealn1}} jours<br>
|
||||
<small>
|
||||
{{domaine.nbetprealn1|number_format(2)}}ETP / {{domaine.nbcaarealn1+nbcaarealn1}}€
|
||||
</small>
|
||||
|
||||
{% set totdayrealn1 = totdayrealn1 + domaine.nbdayrealn1 %}
|
||||
{% set totetprealn1 = totetprealn1 + domaine.nbetprealn1 %}
|
||||
{% set totcaarealn1 = totcaarealn1 + domaine.nbcaarealn1+nbcaarealn1 %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{{domaine.nbdaybudgn1+nbdaybudgn1}} jours<br>
|
||||
<small>
|
||||
{{(domaine.nbetpbudgn1+nbetpbudgn1)|number_format(2)}}ETP / {{domaine.nbcaabudgn1+nbcaabudgn1}}€
|
||||
</small>
|
||||
|
||||
{% set totdaybudgn1 = totdaybudgn1 + domaine.nbdaybudgn1+nbdaybudgn1 %}
|
||||
{% set totetpbudgn1 = totetpbudgn1 + domaine.nbetpbudgn1+nbetpbudgn1 %}
|
||||
{% set totcaabudgn1 = totcaabudgn1 + domaine.nbcaabudgn1+nbcaabudgn1 %}
|
||||
</td>
|
||||
|
||||
<td class="no-print tbhide"> </td>
|
||||
<td class="text-center">
|
||||
{{domaine.nbdayrealn2}} jours<br>
|
||||
<small>
|
||||
{{domaine.nbetprealn2|number_format(2)}}ETP / {{domaine.nbcaarealn2+nbcaarealn2}}€
|
||||
</small>
|
||||
|
||||
{% set totdayrealn2 = totdayrealn2 + domaine.nbdayrealn2 %}
|
||||
{% set totetprealn2 = totetprealn2 + domaine.nbetprealn2 %}
|
||||
{% set totcaarealn2 = totcaarealn2 + domaine.nbcaarealn2+nbcaarealn2 %}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
{{domaine.nbdaybudgn2+nbdaybudgn2}} jours<br>
|
||||
<small>
|
||||
{{(domaine.nbetpbudgn2+nbetpbudgn2)|number_format(2)}}ETP / {{domaine.nbcaabudgn2+nbcaabudgn2}}€
|
||||
</small>
|
||||
|
||||
|
||||
{% set totdaybudgn2 = totdaybudgn2 + domaine.nbdaybudgn2+nbdaybudgn2 %}
|
||||
{% set totetpbudgn2 = totetpbudgn2 + domaine.nbetpbudgn2+nbetpbudgn2 %}
|
||||
{% set totcaabudgn2 = totcaabudgn2 + domaine.nbcaabudgn2+nbcaabudgn2 %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
<tr class="total totalgene" data-domaine="TOTAL">
|
||||
<td class="tdtotalgene" >RESULTAT</td>
|
||||
<td class="tdtotalgene tbhide">RESULTAT</td>
|
||||
|
||||
<td class="no-print tbhide tdtotalgene"> </td>
|
||||
<td class="text-center tdtotalgene">
|
||||
{{totdayrealn1}} jours<br>
|
||||
<small>
|
||||
{{totetprealn1|number_format(2)}}ETP / {{totcaarealn1}}€
|
||||
</small>
|
||||
</td>
|
||||
<td class="text-center tdtotalgene">
|
||||
{{totdaybudgn1}} jours<br>
|
||||
<small>
|
||||
{{totetpbudgn1|number_format(2)}}ETP / {{totcaabudgn1}}€
|
||||
</small>
|
||||
</td>
|
||||
|
||||
<td class="no-print tbhide tdtotalgene"> </td>
|
||||
<td class="text-center tdtotalgene">
|
||||
{{totdayrealn2}} jours<br>
|
||||
<small>
|
||||
{{totetprealn2|number_format(2)}}ETP / {{totcaarealn2}}€
|
||||
</small>
|
||||
</td>
|
||||
<td class="text-center tdtotalgene">
|
||||
{{totdaybudgn2}} jours<br>
|
||||
<small>
|
||||
{{totetpbudgn2|number_format(2)}}ETP / {{totcaabudgn2}}€
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
var groupColumn = 0;
|
||||
|
||||
html="";
|
||||
$('.total').each(function() {
|
||||
html+="<tr>"+$(this).html()+"</tr>";
|
||||
});
|
||||
$("#tbsynthesebody").html(html);
|
||||
|
||||
|
||||
var table = $('.tbdetail').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="7">'+group+'</td></tr>'
|
||||
);
|
||||
|
||||
last = group;
|
||||
}
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
// Order by the grouping
|
||||
$('.tbdetail 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();
|
||||
}
|
||||
} );
|
||||
|
||||
$('#exercice').change(function() {
|
||||
id=$(this).val();
|
||||
url="{{ path('app_budget',{id:'xxx'}) }}";
|
||||
url=url.replace("xxx",id);
|
||||
document.location=url;
|
||||
});
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
{% endblock %}
|
59
templates/Cron/edit.html.twig
Normal file
59
templates/Cron/edit.html.twig
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if mode=="update" %}
|
||||
Modification JOB
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_cron') }}>Annuler</a>
|
||||
|
||||
<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.command) }}
|
||||
{{ form_row(form.jsonargument) }}
|
||||
{{ form_row(form.statut) }}
|
||||
{{ form_row(form.repeatcall) }}
|
||||
{{ form_row(form.repeatinterval) }}
|
||||
{{ form_row(form.nextexecdate) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#command").focus();
|
||||
});
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
54
templates/Cron/list.html.twig
Normal file
54
templates/Cron/list.html.twig
Normal file
@@ -0,0 +1,54 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
JOBS
|
||||
</h1>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Jobs
|
||||
</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">Action</th>
|
||||
<th>Prochaine exécution</th>
|
||||
<th>Command</th>
|
||||
<th>Description</th>
|
||||
<th>Statut</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for cron in crons %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{{path("app_cron_update",{id:cron.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{cron.nextexecdate|date("d/m/Y H:i")}}</td>
|
||||
<td>{{cron.command}}</td>
|
||||
<td>{{cron.description}}</td>
|
||||
<td>{{cron.statutlabel}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$('#dataTables').DataTable({
|
||||
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
|
||||
responsive: true,
|
||||
iDisplayLength: 100,
|
||||
order: [[ 1, "asc" ]]
|
||||
});
|
||||
});
|
||||
{% endblock %}
|
||||
|
16
templates/Cron/logs.html.twig
Normal file
16
templates/Cron/logs.html.twig
Normal file
@@ -0,0 +1,16 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
Télécharger les logs
|
||||
</h1>
|
||||
|
||||
{% if appCron %}
|
||||
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"cron"}) }}>Log CRON</a>
|
||||
{% endif %}
|
||||
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"prod"}) }}>Log PROD</a>
|
||||
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"dev"}) }}>Log DEV</a>
|
||||
{% if appCron %}
|
||||
<a class="btn btn-secondary" href={{ path("app_cron_getlog",{"id":"dump"}) }}>Dump de la Base</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
35
templates/Crop/crop01.html.twig
Normal file
35
templates/Crop/crop01.html.twig
Normal file
@@ -0,0 +1,35 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block head_style %}
|
||||
{{ encore_entry_link_tags('app') }}
|
||||
{{ encore_entry_link_tags('dropzone') }}
|
||||
{% endblock head_style %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
<h3 class="page-header"></h3>
|
||||
<button class="btn btn-secondary" onClick="closeModal();">Annuler</button>
|
||||
|
||||
<form action="{{ oneup_uploader_endpoint('avatar') }}" class="dropzone" id="MyDropZone" style="margin-top:10px">
|
||||
|
||||
{{ encore_entry_script_tags('dropzone') }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block localjavascript %}
|
||||
window.parent.$(".modal-title").html("ETAPE 1 - Téléchargez votre image");
|
||||
|
||||
Dropzone.options.MyDropZone = {
|
||||
maxFiles: 1,
|
||||
acceptedMimeTypes: 'image/*',
|
||||
//renameFilename: false,
|
||||
success: function(file, response){
|
||||
$(location).attr('href',"{{ path('app_crop02') }}");
|
||||
}
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
window.parent.$("#extraLargeModal").modal('hide');
|
||||
}
|
||||
{% endblock %}
|
71
templates/Crop/crop02.html.twig
Normal file
71
templates/Crop/crop02.html.twig
Normal file
@@ -0,0 +1,71 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
{{ form_widget(form.submit) }}
|
||||
<button class="btn btn-secondary" onClick="closeModal();">Annuler</button>
|
||||
|
||||
<div id='preview' style='overflow:hidden; width:90px; height:90px; position: absolute; top: 0px; right: 10px;'>
|
||||
<img src="/{{ appAlias }}/uploads/avatar/{{ app.session.get('uploadavatar') }}" style='position: relative;' alt='Thumbnail Preview' />
|
||||
</div>
|
||||
|
||||
<div style="width:800px; height:590px; overflow:hidden; margin:65px auto 0px auto;">
|
||||
<div id="largeimg" class="crop-select-js" style="width:800px;">
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block localjavascript %}
|
||||
function move(data) {
|
||||
$('#form_x').val(data.xScaledToImage);
|
||||
$('#form_y').val(data.yScaledToImage);
|
||||
|
||||
preview();
|
||||
}
|
||||
|
||||
function resize(data) {
|
||||
$('#form_w').val(data.widthScaledToImage);
|
||||
$('#form_h').val(data.heightScaledToImage);
|
||||
|
||||
preview();
|
||||
}
|
||||
|
||||
function preview(data) {
|
||||
var scaleX = 90 / $('#form_w').val();
|
||||
var scaleY = 90 / $('#form_h').val();
|
||||
|
||||
$('#preview img').css({
|
||||
width: Math.round(scaleX * $('#largeimg').width()) + 'px',
|
||||
height: Math.round(scaleY * $('#largeimg').height()) + 'px',
|
||||
marginLeft: '-' + Math.round(scaleX * $('#form_x').val()) + 'px',
|
||||
marginTop: '-' + Math.round(scaleY * $('#form_y').val()) + 'px'
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function reportThumb() {
|
||||
window.parent.$("#user_avatar").val("thumb_{{ app.session.get('uploadavatar') }}");
|
||||
window.parent.$("#user_avatar_img").attr("src","/{{ appAlias }}/uploads/avatar/thumb_{{ app.session.get('uploadavatar') }}");
|
||||
closeModal();
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
window.parent.$("#extraLargeModal").modal('hide');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
window.parent.$(".modal-title").html("ETAPE 2 - Découper votre image");
|
||||
|
||||
$('#largeimg').CropSelectJs({
|
||||
imageSrc: "/{{ appAlias }}/uploads/avatar/{{ app.session.get('uploadavatar') }}",
|
||||
selectionResize: function(data) { resize(data); },
|
||||
selectionMove: function(data) { move(data); },
|
||||
});
|
||||
$('#largeimg').CropSelectJs('setSelectionAspectRatio',1);
|
||||
|
||||
|
||||
});
|
||||
{% endblock %}
|
71
templates/Customer/edit.html.twig
Executable file
71
templates/Customer/edit.html.twig
Executable file
@@ -0,0 +1,71 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
CLIENT
|
||||
{% elseif mode=="update" %}
|
||||
Modification CLIENT
|
||||
{% elseif mode=="submit" %}
|
||||
Création CLIENT
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_customer') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_customer_delete',{'id':customer.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.name) }}
|
||||
{{ form_row(form.keypass) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#customer_name").focus();
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
|
||||
{% endblock %}
|
81
templates/Customer/list.html.twig
Normal file
81
templates/Customer/list.html.twig
Normal file
@@ -0,0 +1,81 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
|
||||
{% 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">
|
||||
CLIENTS
|
||||
</h1>
|
||||
|
||||
<p><a class="btn btn-success" href={{ path('app_customer_submit') }}>Ajouter</a></p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Clients
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-print no-sort">Action</th>
|
||||
<th>Nom</th>
|
||||
<th>Clé</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for customer in customers %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_customer_update",{id:customer.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{customer.name}}</td>
|
||||
<td>
|
||||
{% if customer.keypass %}
|
||||
<a href="{{path("app_customer_report",{"key":customer.keypass})}}">{{customer.keypass}}</a>
|
||||
{% endif %}
|
||||
</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 %}
|
71
templates/Domaine/edit.html.twig
Executable file
71
templates/Domaine/edit.html.twig
Executable file
@@ -0,0 +1,71 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
DOMAINE
|
||||
{% elseif mode=="update" %}
|
||||
Modification DOMAINE
|
||||
{% elseif mode=="submit" %}
|
||||
Création DOMAINE
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_domaine') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_domaine_delete',{'id':domaine.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.category) }}
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.description) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#domaine_name").focus();
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
{% endblock %}
|
72
templates/Domaine/list.html.twig
Normal file
72
templates/Domaine/list.html.twig
Normal file
@@ -0,0 +1,72 @@
|
||||
{% 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">
|
||||
DOMAINES
|
||||
</h1>
|
||||
|
||||
<p><a class="btn btn-success" href={{ path('app_domaine_submit') }}>Ajouter</a></p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Domaines
|
||||
</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>Catégorie</th>
|
||||
<th>Nom</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for domaine in domaines %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_domaine_update",{id:domaine.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{domaine.category}}</td>
|
||||
<td>{{domaine.name}}</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 %}
|
537
templates/Event/list.html.twig
Normal file
537
templates/Event/list.html.twig
Normal file
@@ -0,0 +1,537 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block head_style %}
|
||||
{{ encore_entry_link_tags('app') }}
|
||||
{{ encore_entry_link_tags('fullcalendar') }}
|
||||
{% endblock head_style %}
|
||||
|
||||
{% block localstyle %}
|
||||
.fc-header-toolbar h2 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.fc-day-grid-event {
|
||||
padding:0px;
|
||||
border-radius:0px;
|
||||
border: none;
|
||||
}
|
||||
.fc-content {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.fc-title {
|
||||
font-weight: bolder;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.eventAvatar {
|
||||
width: 20px;
|
||||
margin: 0px 5px 0px 0px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.eventInfo{
|
||||
margin: -5px 5px 0px 0px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.eventUser{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.eventEstimate {
|
||||
margin: -3px 10px;
|
||||
}
|
||||
.select2-results__group {
|
||||
font-size:12px !important;
|
||||
}
|
||||
.select2-results__option{
|
||||
font-size: 14px;
|
||||
padding-left:15px
|
||||
}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="fullcalendar" style="width:100%; margin-top:10px;"></div>
|
||||
|
||||
<div id="modalsubmit" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Création Evènement</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<button onClick="eventSubmit()" class="btn btn-success">Valider</button>
|
||||
<button onClick="" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
|
||||
|
||||
<p></p>
|
||||
<div class="form-group">
|
||||
<label class="control-label required" for="usersubmit">
|
||||
Intervenant<span class="mandatory">*</span>
|
||||
</label>
|
||||
<select class="select2entity" id="usersubmit" name="usersubmit">
|
||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_MASTER') or is_granted('ROLE_VALIDATOR')%}
|
||||
|
||||
{% for user in app.session.get('users') %}
|
||||
{% set selected="" %}
|
||||
{%if user.id==app.session.get('iduser') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{user.id}}" {{selected}}>{{user.displayname}}</option>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<option value="{{app.user.id}}">{{app.user.displayname}}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label required" for="tasksubmit">
|
||||
Project<span class="mandatory">*</span>
|
||||
</label>
|
||||
<select class="select2entity" id="tasksubmit" name="tasksubmit">
|
||||
<option></option>
|
||||
{% for project in projects|sort((a, b) => a.displayname <=> b.displayname) %}
|
||||
<optgroup label="{{project.displayname}}">
|
||||
{% for task in project.tasks|sort((a, b) => a.displayname <=> b.displayname) %}
|
||||
{% if task.active %}
|
||||
<option value="{{task.id}}">{{task.displayname}}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="amsubmit">
|
||||
<label class="custom-control-label" for="amsubmit">Evènement sur la matinée</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="apsubmit">
|
||||
<label class="custom-control-label" for="apsubmit">Evènement sur l'après-midi</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="astreinte">
|
||||
<label class="custom-control-label" for="astreinte">Astreinte</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="externaltrip">
|
||||
<label class="custom-control-label" for="externaltrip">Déplacement externe</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description" class="control-label">
|
||||
Description
|
||||
</label>
|
||||
<textarea id="description" id="description" class="form-control" placeholder="Description" style="height:200px">
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
|
||||
<input type="hidden" id="start" name="start" class="form-control" value="">
|
||||
<input type="hidden" id="end" name="end" class="form-control" value="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="modalupdate" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Modification Evènement</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<button onClick="eventUpdate()" class="btn btn-success">Valider</button>
|
||||
<button onClick="" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
|
||||
<button onClick="eventDelete()" class="btn btn-danger float-right">Supprimer</button>
|
||||
|
||||
<p></p>
|
||||
<div class="form-group">
|
||||
<label class="control-label required" for="service_name">
|
||||
Intervenant<span class="mandatory">*</span>
|
||||
</label>
|
||||
<select class="select2entity" id="userupdate" name="userupdate">
|
||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_MASTER') or is_granted('ROLE_VALIDATOR')%}
|
||||
{% for user in users %}
|
||||
<option value="{{user.id}}">{{user.displayname}}</option>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<option value="{{app.user.id}}">{{app.user.displayname}}</option>
|
||||
{% endif %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label required" for="taskupdate">
|
||||
Project<span class="mandatory">*</span>
|
||||
</label>
|
||||
<select class="select2entity" id="taskupdate" name="taskupdate">
|
||||
<option></option>
|
||||
{% for project in projects|sort((a, b) => a.displayname <=> b.displayname) %}
|
||||
<optgroup label="{{project.displayname}}">
|
||||
{% for task in project.tasks|sort((a, b) => a.displayname <=> b.displayname) %}
|
||||
<option value="{{task.id}}">{{task.displayname}}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="amupdate">
|
||||
<label class="custom-control-label" for="amupdate">Evènement sur la matinée</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="apupdate">
|
||||
<label class="custom-control-label" for="apupdate">Evènement sur l'après-midi</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-switch">
|
||||
<input type="checkbox" class="custom-control-input" id="externaltripupdate">
|
||||
<label class="custom-control-label" for="externaltripupdate">Déplacement externe</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="description" class="control-label">
|
||||
Description
|
||||
</label>
|
||||
<textarea id="description" id="description" class="form-control" placeholder="Description" style="height:200px">
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="idevent" name="idevent" class="form-control" value="">
|
||||
<input type="hidden" id="fgastreinte" name="fgastreinte" class="form-control" value="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ encore_entry_script_tags('fullcalendar') }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#modalsubmit #user").select2({
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
|
||||
$("#modalsubmit #task").select2({
|
||||
placeholder: "Selectionnez un projet",
|
||||
allowClear: true,
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
|
||||
$("#modalupdate #user").select2({
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
|
||||
$("#modalupdate #task").select2({
|
||||
placeholder: "Selectionnez un projet",
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
});
|
||||
|
||||
// Rendu d'un évenement
|
||||
function eventRender(info) {
|
||||
// Récupération des divers élements du rendu event
|
||||
var content=$(info.el).children('.fc-content');
|
||||
var title=$(content).children('.fc-title');
|
||||
|
||||
// Ajouter l'avatar
|
||||
content.prepend("<img src="+info.event.extendedProps.avatar+" class='eventAvatar'>");
|
||||
content.append("<span class='eventUser float-left small'>"+info.event.extendedProps.username+"</span>");
|
||||
var eventInfo=$(content).children('.eventUser');
|
||||
|
||||
// Ajout container
|
||||
content.append("<span style='margin-top:-12px' class='eventInfo float-right'></span>");
|
||||
var eventInfo=$(content).children('.eventInfo');
|
||||
|
||||
// Ajouter le verrou si event non editable
|
||||
if(info.event.extendedProps.locked) {
|
||||
eventInfo.append("<i class='fa fa-lock float-right'></i>");
|
||||
}
|
||||
if(info.event.extendedProps.externaltrip) {
|
||||
eventInfo.append("<i class='fas fa-bed float-right'></i>");
|
||||
}
|
||||
if(info.event.extendedProps.holiday) {
|
||||
eventInfo.append("<i class='fas fa-umbrella-beach float-right'></i>");
|
||||
}
|
||||
// Ajout estimation
|
||||
eventInfo.append("<span class='eventEstimate float-right small'>"+info.event.extendedProps.estimate+"</span>");
|
||||
|
||||
// Description
|
||||
content.attr("title",info.event.extendedProps.fulldescription);
|
||||
}
|
||||
|
||||
// Formulaire Création d'un événement
|
||||
var allDay;
|
||||
function eventSelect(selectionInfo) {
|
||||
var start=moment(selectionInfo.start);
|
||||
var end=moment(selectionInfo.end);
|
||||
var end=end.subtract(1, 'd');
|
||||
allDay=(start.format("DD/MM/YYYY") != end.format("DD/MM/YYYY"));
|
||||
|
||||
// Controle
|
||||
if(start.month()!=end.month()) {
|
||||
alert("Une tâche ne peut être sur deux mois différents");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(start.week()!=end.week()) {
|
||||
alert("Une tâche ne peut être sur deux semaines différentes");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Valeur par défaut
|
||||
{% if (is_granted('ROLE_ADMIN') or is_granted('ROLE_VALIDATOR') or is_granted('ROLE_MASTER')) and app.session.get('iduser')!="all" %}
|
||||
$('#usersubmit').val({{app.session.get('iduser')}}).trigger("change");
|
||||
{% else %}
|
||||
$('#usersubmit').val({{app.user.id}}).trigger("change");
|
||||
{% endif %}
|
||||
|
||||
// Si jour de fin un samedi ou un dimanche : on est forcement en astreinte
|
||||
if(moment(end).day()==0||moment(end).day()==6) {
|
||||
$("#modalsubmit #astreinte").prop("checked",true);
|
||||
$("#modalsubmit #astreinte").attr("disabled",true);
|
||||
allDay=true;
|
||||
}
|
||||
else {
|
||||
$("#modalsubmit #astreinte").prop('checked', false);
|
||||
$("#modalsubmit #astreinte").attr('disabled', false);
|
||||
}
|
||||
|
||||
$('#modalsubmit #amsubmit').prop("checked",true);
|
||||
$('#modalsubmit #apsubmit').prop("checked",true);
|
||||
$('#modalsubmit #amsubmit').attr("disabled",allDay);
|
||||
$('#modalsubmit #apsubmit').attr("disabled",allDay);
|
||||
|
||||
$('#modalsubmit #start').val(start.format("YYYY-MM-DD"));
|
||||
$('#modalsubmit #end').val(end.format("YYYY-MM-DD"));
|
||||
|
||||
$('#modalsubmit #description').val("");
|
||||
$('#modalsubmit #externaltrip').prop("checked",false);
|
||||
|
||||
$("#modalsubmit .alert").remove();
|
||||
|
||||
// Formulaire de création d'un évènement
|
||||
$('#modalsubmit').modal();
|
||||
}
|
||||
|
||||
// Formulaire Modification d'un événement
|
||||
function eventClick(info) {
|
||||
if(info.event.extendedProps.editable) {
|
||||
var id=info.event.id;
|
||||
var description=info.event.extendedProps.description;
|
||||
var userid=info.event.extendedProps.userid;
|
||||
var taskid=info.event.extendedProps.taskid;
|
||||
var fgastreinte=info.event.extendedProps.astreinte;
|
||||
var eventallday = info.event.allDay;
|
||||
var eventstart = info.event.start;
|
||||
var eventend = info.event.end;
|
||||
var externaltrip = info.event.extendedProps.externaltrip;
|
||||
var holiday = info.event.extendedProps.holiday;
|
||||
$('#userupdate').val(userid).trigger("change");
|
||||
$('#taskupdate').val(taskid).trigger("change");
|
||||
$('#modalupdate #idevent').val(id);
|
||||
|
||||
$('#modalupdate #fgastreinte').val(fgastreinte);
|
||||
$('#modalupdate #description').val(description);
|
||||
if (holiday) {
|
||||
$('#modalupdate #externaltripupdate').prop("checked",false);
|
||||
$('#modalupdate #externaltripupdate').prop("disabled",true);
|
||||
}else{
|
||||
$('#modalupdate #externaltripupdate').prop("disabled",false);
|
||||
$('#modalupdate #externaltripupdate').prop("checked",externaltrip);
|
||||
}
|
||||
$("#modalupdate .alert").remove();
|
||||
eDayStart=eventstart.toString().split(" ")[2]
|
||||
eDayEnd=eventend.toString().split(" ")[2]
|
||||
if ((eDayEnd - eDayStart) >1) {
|
||||
$('#modalupdate #amupdate').prop("checked",true);
|
||||
$('#modalupdate #apupdate').prop("checked",true);
|
||||
$('#modalupdate #amupdate').prop("disabled",true);
|
||||
$('#modalupdate #apupdate').prop("disabled",true);
|
||||
}else{
|
||||
$('#modalupdate #amupdate').prop("disabled",false);
|
||||
$('#modalupdate #apupdate').prop("disabled",false);
|
||||
if (!eventallday){
|
||||
eStart = eventstart.toString().split(" ")[4].split(":")[0]
|
||||
//eEnd = eventend.toString().split(" ")[4].split(":")[0]
|
||||
|
||||
//AM
|
||||
if (eStart == 09){
|
||||
$('#modalupdate #amupdate').prop("checked",true);
|
||||
$('#modalupdate #apupdate').prop("checked",false);
|
||||
}
|
||||
//AP
|
||||
if (eStart == 13){
|
||||
$('#modalupdate #amupdate').prop("checked",false);
|
||||
$('#modalupdate #apupdate').prop("checked",true);
|
||||
}
|
||||
}else{
|
||||
$('#modalupdate #amupdate').prop("checked",true);
|
||||
$('#modalupdate #apupdate').prop("checked",true);
|
||||
}
|
||||
}
|
||||
|
||||
// Formulaire de création d'un évènement
|
||||
$('#modalupdate').modal();
|
||||
}
|
||||
}
|
||||
|
||||
// Création de l'évènement
|
||||
function eventSubmit() {
|
||||
$("#modalsubmit .alert").remove();
|
||||
var error=false;
|
||||
|
||||
// Tache obligatoire
|
||||
if($("#modalsubmit #task").val()=="") {
|
||||
error=true;
|
||||
$("#modalsubmit .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>Tâche obligatoire</div>");
|
||||
}
|
||||
|
||||
// AM ou PM obligatoire
|
||||
if(!$("#modalsubmit #amsubmit").prop("checked")&&!$("#modalsubmit #apsubmit").prop("checked")) {
|
||||
error=true;
|
||||
$("#modalsubmit .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>Vous devez choisir un moment de la journée</div>");
|
||||
}
|
||||
|
||||
if(!error) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
iduser: $("#usersubmit").val(),
|
||||
idtask: $("#tasksubmit").val(),
|
||||
start: $("#modalsubmit #start").val(),
|
||||
end: $("#modalsubmit #end").val(),
|
||||
am: $("#modalsubmit #amsubmit").prop("checked"),
|
||||
ap: $("#modalsubmit #apsubmit").prop("checked"),
|
||||
astreinte: $("#modalsubmit #astreinte").prop("checked"),
|
||||
externaltrip: $("#modalsubmit #externaltrip").prop("checked"),
|
||||
description: $("#modalsubmit #description").val()
|
||||
},
|
||||
url: "{{ path('app_event_submit') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
$("#modalsubmit .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
|
||||
}
|
||||
else {
|
||||
calendar.refetchEvents();
|
||||
$('#modalsubmit').modal('hide');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Modification de l'évènement
|
||||
function eventUpdate() {
|
||||
$("#modalupdate .alert").remove();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
idevent: $("#modalupdate #idevent").val(),
|
||||
iduser: $("#userupdate").val(),
|
||||
idtask: $("#taskupdate").val(),
|
||||
am: $("#modalupdate #amupdate").prop("checked"),
|
||||
ap: $("#modalupdate #apupdate").prop("checked"),
|
||||
fgastreinte: $("#modalupdate #fgastreinte").val(),
|
||||
externaltrip: $("#modalupdate #externaltripupdate").prop("checked"),
|
||||
description: $("#modalupdate #description").val()
|
||||
},
|
||||
url: "{{ path('app_event_update') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
$("#modalupdate .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
|
||||
}
|
||||
else {
|
||||
var event = calendar.getEventById($("#modalupdate #idevent").val());
|
||||
event.remove();
|
||||
|
||||
calendar.addEvent(response);
|
||||
calendar.render;
|
||||
$('#modalupdate').modal('hide');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Suppression de l'évènement
|
||||
function eventDelete() {
|
||||
$("#modalupdate .alert").remove();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
idevent: $("#modalupdate #idevent").val(),
|
||||
fgastreinte: $("#modalupdate #fgastreinte").val()
|
||||
},
|
||||
url: "{{ path('app_event_delete') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
$("#modalupdate .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
|
||||
}
|
||||
else {
|
||||
var event = calendar.getEventById($("#modalupdate #idevent").val());
|
||||
event.remove();
|
||||
$('#modalupdate').modal('hide');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// On change astreinte
|
||||
$("#astreinte").change(function() {
|
||||
if(this.checked) {
|
||||
$("#amsubmit").prop("disabled",true);
|
||||
$("#apsubmit").prop("disabled",true);
|
||||
|
||||
$('#modalsubmit #amsubmit').prop("checked",true);
|
||||
$('#modalsubmit #apsubmit').prop("checked",true);
|
||||
}
|
||||
else {
|
||||
$("#amsubmit").prop("disabled",allDay);
|
||||
$("#apsubmit").prop("disabled",allDay);
|
||||
|
||||
$('#modalsubmit #amsubmit').prop("checked",true);
|
||||
$('#modalsubmit #apsubmit').prop("checked",true);
|
||||
}
|
||||
});
|
||||
|
||||
{% endblock %}
|
8
templates/Export/export_full_worked_days.csv.twig
Normal file
8
templates/Export/export_full_worked_days.csv.twig
Normal file
@@ -0,0 +1,8 @@
|
||||
{% block body %}
|
||||
Utilisateur;Jour;Journée entière;Astreinte;AM;AP;Taches;AM;Tache AM;AP;Tache AP;Astreinte;Description Astreintes
|
||||
{% for user in users %}
|
||||
{% for day, event in user.events %}
|
||||
{{ user.user.displayname }};{{day}};{{event.allday}};{{event.astreinte}};{{event.am}};{{event.ap}};{{event.descriptionday|trim}} {{event.descriptionam|trim}} {{event.descriptionap|trim}} {{event.descriptionastreinte|trim}}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
6
templates/Export/export_month_charged_days.csv.twig
Normal file
6
templates/Export/export_month_charged_days.csv.twig
Normal file
@@ -0,0 +1,6 @@
|
||||
{% block body %}
|
||||
Mois;Jours_facturés;Jour_non_facturés
|
||||
{% for month, event in events %}
|
||||
{{month}};{{event.f}};{{event.nf}}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
8
templates/Export/export_offers.csv.twig
Normal file
8
templates/Export/export_offers.csv.twig
Normal file
@@ -0,0 +1,8 @@
|
||||
{% block body %}
|
||||
Client;Projet;Proposition;Ref;Qt;PU;Total;
|
||||
{% for project in projects %}
|
||||
{% for offer in project.offers %}
|
||||
{{ project.customer }};{{project.name}};{{offer.name}};{{offer.ref}};{{offer.quantity}};{{offer.pu}};{{offer.total}}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
6
templates/Export/export_penalty_additional.csv.twig
Normal file
6
templates/Export/export_penalty_additional.csv.twig
Normal file
@@ -0,0 +1,6 @@
|
||||
{% block body %}
|
||||
Tâche;Astr.Act;H.Supp;Utilisateur;Début;Fin;Durée;Description;
|
||||
{% for timer in timers %}
|
||||
{{timer.taskname}};{{timer.activepenalty}};{{timer.additionalhour}};{{timer.user}};{{timer.start|date("d/m/Y H:i")}};{{timer.end|date("d/m/Y H:i")}};{{timer.duration|date("H:i")}};{{timer.description}};
|
||||
{% endfor %}
|
||||
{% endblock %}
|
16
templates/Export/export_project_weekly.csv.twig
Normal file
16
templates/Export/export_project_weekly.csv.twig
Normal file
@@ -0,0 +1,16 @@
|
||||
{% block body %}
|
||||
Client;Projet;Tâche;Activité;Domaine;Nature;Utilisateur;Année;Semaine;Cumul;
|
||||
{% for project in projects %}
|
||||
{% if project.weeks_by_task_by_user is defined %}
|
||||
{% for year,weeks in project.weeks_by_task_by_user %}
|
||||
{% for week in weeks %}
|
||||
{% for task in week.tasks%}
|
||||
{% for user in task.users%}
|
||||
{{project.customer}};{{project.name}};{{task.taskname|replace({"&": "et"})}};{{project.service}};{{project.domaine}};{{task.nature}};{{user.displayname}};{{week.isoyear}};{{week.isoweek}};{{user.cumul|replace({".": ","})}};
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
56
templates/Export/list.html.twig
Normal file
56
templates/Export/list.html.twig
Normal file
@@ -0,0 +1,56 @@
|
||||
{% extends "base.html.twig" %}
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
EXPORTS DE DONNEES
|
||||
</h1>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a href="{{ path('export_project_weekly') }}" class="btn btn-success">Export des Projets par semaine par participant</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Exporter le cumul des points éffectués sur un/des projets, par tâche par utilisateur.</p>
|
||||
<p>Filtres utiles : Nombres de mois, Projet, Service</p>
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a class="btn btn-success" href={{ path('app_export_penalty_additional') }}>Export des astreintes actives et heures supplémentaires</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Exporter la liste des astreintes actives réalisés, ainsi que les saisies en heure supplémentaires.</p>
|
||||
<p>Filtres utiles : Intervenant (hors "Tout le monde")</p>
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a class="btn btn-success" href={{ path('export_full_worked_days') }}>Export des jours pleins travaillés</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Exporter la liste des jours travaillés pleinement éligibles aux tickets restaurants</p>
|
||||
<p>Filtres utiles : Nombre de mois, Intervenant</p>
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a class="btn btn-success" href={{ path('export_offers') }}>Export des commandes</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Exporter la liste des commandes</p>
|
||||
<p>Filtres utiles : Projet, Service</p>
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<a class="btn btn-success" href={{ path('export_month_charged_days') }}>Export des jours facturés/non-facturés</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Exporter la liste du nombre de jours facturés et non-facturés par mois</p>
|
||||
<p>Filtres utiles : Nombre de mois</p>
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
{% endblock %}
|
175
templates/Form/fields.html.twig
Normal file
175
templates/Form/fields.html.twig
Normal file
@@ -0,0 +1,175 @@
|
||||
{% extends 'form_div_layout.html.twig' %}
|
||||
|
||||
{# Voir https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig #}
|
||||
|
||||
{# On commence par simplement ajouter le form-group au row de nos formulaires #}
|
||||
{% block form_row -%}
|
||||
{% set attr = attr|merge({'help': (attr.help|default(true)) }) %}
|
||||
<div class="form-group {{ errors|length > 0 ? 'has-error' : '' }}">
|
||||
{{- form_label(form) }}
|
||||
{{- form_widget(form) }}
|
||||
{{ form_errors(form) }}
|
||||
</div>
|
||||
{%- endblock form_row %}
|
||||
|
||||
{# Puis on modifie très simplement nos input et textarea
|
||||
les plus importants pour y ajouter le class imposée par Bootstrap 3 #}
|
||||
{% block textarea_widget %}
|
||||
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
|
||||
{{ parent() }}
|
||||
{% endblock textarea_widget %}
|
||||
|
||||
{% block form_widget_simple %}
|
||||
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
|
||||
{{ parent() }}
|
||||
{% endblock form_widget_simple %}
|
||||
|
||||
{% block form_label -%}
|
||||
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' control-label')|trim}) %}
|
||||
{% if 'checkbox' not in block_prefixes %}
|
||||
{% if label is not same as(false) -%}
|
||||
{% if not compound -%}
|
||||
{% set label_attr = label_attr|merge({'for': id}) %}
|
||||
{%- endif %}
|
||||
{% if required -%}
|
||||
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
|
||||
{%- endif %}
|
||||
{% if label is empty -%}
|
||||
{% set label = name|humanize %}
|
||||
{%- endif -%}
|
||||
|
||||
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
|
||||
{{ label|trans({}, translation_domain)|raw }}
|
||||
<span class="mandatory">{% if required %}*{% endif %}</span>
|
||||
</label>
|
||||
{%- endif %}
|
||||
{% endif %}
|
||||
{%- endblock form_label %}
|
||||
|
||||
{# et enfin les erreurs #}
|
||||
{% block form_errors %}
|
||||
{% if errors|length > 0 %}
|
||||
{% if attr.help is defined and attr.help %}
|
||||
<p class="help-block text-danger">
|
||||
{% for error in errors %}
|
||||
{{ error.message }}<br />
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% else %}
|
||||
<div class="alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert">
|
||||
<span aria-hidden="true">×</span>
|
||||
<span class="sr-only">Close</span>
|
||||
</button>
|
||||
{% for error in errors %}
|
||||
{{ error.message|raw }}<br />
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock form_errors %}
|
||||
|
||||
{# Personnalisation des boutons #}
|
||||
{% block button_widget -%}
|
||||
{% if label is empty -%}
|
||||
{% set label = name|humanize %}
|
||||
{%- endif -%}
|
||||
{% set attr = attr|merge({'class': (attr.class|default('') ~ '')|trim}) %}
|
||||
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{
|
||||
label|trans({}, translation_domain) }}
|
||||
{% if type is defined and type == 'submit' -%}
|
||||
|
||||
{% endif %}
|
||||
</button>
|
||||
{%- endblock button_widget %}
|
||||
|
||||
{# Personnalisation des attributs des boutons #}
|
||||
{% block button_attributes -%}
|
||||
{% if type is defined and type == 'submit' -%}
|
||||
{% set class = 'btn-primary' %}
|
||||
{% else %}
|
||||
{% set class = 'btn-default' %}
|
||||
{%- endif -%}
|
||||
|
||||
{% set attr = attr|merge({'class': (attr.class|default('') ~ ' btn ' ~ class)|trim}) %}
|
||||
{{ parent() }}
|
||||
{%- endblock button_attributes %}
|
||||
|
||||
|
||||
{# Personnalisation des select #}
|
||||
{% block choice_widget_collapsed %}
|
||||
{% set attr = attr|merge({'class': (attr.class|default('') ~ ' form-control')|trim}) %}
|
||||
{{ parent() }}
|
||||
{%- endblock choice_widget_collapsed %}
|
||||
|
||||
{% block choice_widget %}
|
||||
{% if expanded %}
|
||||
<ul {{ block('widget_container_attributes') }} style="list-style: none; padding-left: 0">
|
||||
{% for child in form %}
|
||||
<li>
|
||||
{{ form_widget(child) }}
|
||||
{{ form_label(child) }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
{{ parent() }}
|
||||
{% endif %}
|
||||
{% endblock choice_widget %}
|
||||
|
||||
{% block checkbox_widget %}
|
||||
<label for="{{ id }}">
|
||||
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
||||
{{ label|trans({}, translation_domain) }}</label>
|
||||
{% endblock checkbox_widget %}
|
||||
|
||||
{% block radio_widget %}
|
||||
<label for="{{ id }}">
|
||||
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
|
||||
{{ label|trans({}, translation_domain) }}
|
||||
</label>
|
||||
{% endblock radio_widget %}
|
||||
|
||||
{# Inline date marcro #}
|
||||
{% macro date_form_widget(form) %}
|
||||
<div class="col col-xs-4">
|
||||
{{ form_widget(form) }}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{# Inline date #}
|
||||
{% block date_widget %}
|
||||
{% if widget == 'single_text' %}
|
||||
{{ block('form_widget_simple') }}
|
||||
{% else %}
|
||||
{% import _self as self %}
|
||||
<div class="row">
|
||||
{{ date_pattern|replace({
|
||||
'{{ year }}': self.date_form_widget(form.year),
|
||||
'{{ month }}': self.date_form_widget(form.month),
|
||||
'{{ day }}': self.date_form_widget(form.day),
|
||||
})|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock date_widget %}
|
||||
|
||||
{# Inline date_time
|
||||
{% block time_widget %}
|
||||
{% if widget == 'single_text' %}
|
||||
{{ block('form_widget_simple') }}
|
||||
{% else %}
|
||||
{% import _self as self %}
|
||||
<div class="row">
|
||||
{{ time_pattern|replace({
|
||||
'{{ hour }}': self.date_form_widget(form.hour),
|
||||
'{{ minute }}': self.date_form_widget(form.minute),
|
||||
})|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock time_widget %}
|
||||
#}
|
||||
|
||||
{% block file_widget %}
|
||||
{% set type = type|default('file') %}
|
||||
<input type="{{ type }}" {{ block('widget_attributes') }} />
|
||||
{% endblock file_widget %}
|
7
templates/Home/admin.html.twig
Normal file
7
templates/Home/admin.html.twig
Normal file
@@ -0,0 +1,7 @@
|
||||
{% extends "CRWhizBundle::base.html.twig" %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
8
templates/Home/customer.html.twig
Normal file
8
templates/Home/customer.html.twig
Normal file
@@ -0,0 +1,8 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<center>Merci d'utiliser l'URL qui vous a été communiquée pour visualiser votre rapport.</center>
|
||||
|
||||
{% endblock %}
|
||||
|
16
templates/Home/home.html.twig
Normal file
16
templates/Home/home.html.twig
Normal file
@@ -0,0 +1,16 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
body {
|
||||
background-color: #efefef;
|
||||
}
|
||||
.homecard {
|
||||
padding-top: 20px;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% endblock %}
|
||||
|
36
templates/Home/login.html.twig
Executable file
36
templates/Home/login.html.twig
Executable file
@@ -0,0 +1,36 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
body {
|
||||
background-color: #efefef;
|
||||
}
|
||||
.homecard {
|
||||
padding-top: 20px;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div style="text-align:center">
|
||||
<img src="/{{appAlias}}/images/logo.png" style="height:120px;margin-top:10px;"><br>
|
||||
<h1>{{appName}}</h1>
|
||||
<form action="{{ path('app_login') }}" method="post">
|
||||
<div class="card homecard" style="width:400px; margin:auto">
|
||||
<div class="card-body">
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
|
||||
{% endif %}
|
||||
|
||||
<label for="username">Login</label>
|
||||
<input type="text" id="username" name="_username" value="{{ last_username }}" class="form-control" style="margin-bottom:15px;" />
|
||||
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="_password" class="form-control" style="margin-bottom:15px;" />
|
||||
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
|
||||
|
||||
<input type="submit" name="login" class="btn btn-success form-control" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
72
templates/Job/edit.html.twig
Executable file
72
templates/Job/edit.html.twig
Executable file
@@ -0,0 +1,72 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
METIER
|
||||
{% elseif mode=="update" %}
|
||||
Modification METIER
|
||||
{% elseif mode=="submit" %}
|
||||
Création METIER
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_job') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_job_delete',{'id':job.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.name) }}
|
||||
{{ form_row(form.type) }}
|
||||
{{ form_row(form.description) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#job_name").focus();
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
|
||||
{% endblock %}
|
77
templates/Job/list.html.twig
Normal file
77
templates/Job/list.html.twig
Normal file
@@ -0,0 +1,77 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
|
||||
{% 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">
|
||||
METIERS
|
||||
</h1>
|
||||
|
||||
<p><a class="btn btn-success" href={{ path('app_job_submit') }}>Ajouter</a></p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Métiers
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-print no-sort">Action</th>
|
||||
<th>Type</th>
|
||||
<th>Nom</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for job in jobs %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_job_update",{id:job.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{job.type}}</td>
|
||||
<td>{{job.name}}</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 %}
|
62
templates/Nature/edit.html.twig
Executable file
62
templates/Nature/edit.html.twig
Executable file
@@ -0,0 +1,62 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if mode=="update" %}
|
||||
Modification NATURE
|
||||
{% elseif mode=="submit" %}
|
||||
Création NATURE
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_nature') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_nature_delete',{'id':nature.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.name) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#nature_name").focus();
|
||||
});
|
||||
{% endblock %}
|
70
templates/Nature/list.html.twig
Normal file
70
templates/Nature/list.html.twig
Normal file
@@ -0,0 +1,70 @@
|
||||
{% 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">
|
||||
NATURES
|
||||
</h1>
|
||||
|
||||
<p><a class="btn btn-success" href={{ path('app_nature_submit') }}>Ajouter</a></p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Natures
|
||||
</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>Nom</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for nature in natures %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_nature_update",{id:nature.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{nature.name}}</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: [[ 2, "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 %}
|
25
templates/Notif/attentevalidation.html.twig
Normal file
25
templates/Notif/attentevalidation.html.twig
Normal file
@@ -0,0 +1,25 @@
|
||||
{% block body %}
|
||||
{% autoescape %}
|
||||
<h2>Date de la demande : {{ date|date("d/m/Y H:i") }} </h2>
|
||||
<p>
|
||||
<b>Utilisateur =</b> {{ username }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Début =</b> {{ start|date("d/m/Y H:i") }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Fin =</b> {{ end|date("d/m/Y H:i") }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Durée =</b> {{ duration }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Type =</b> Congé
|
||||
</p>
|
||||
<p>
|
||||
<b>Lien pour valider =</b> <a href="{{ valid_link }}">{{ valid_link }}</a>
|
||||
</p>
|
||||
|
||||
{% endautoescape %}
|
||||
{% endblock %}
|
||||
|
23
templates/Notif/validation.html.twig
Normal file
23
templates/Notif/validation.html.twig
Normal file
@@ -0,0 +1,23 @@
|
||||
{% block body %}
|
||||
{% autoescape %}
|
||||
<h2>VALIDATION</h2>
|
||||
<p>
|
||||
<b>Utilisateur =</b> {{ username }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Début =</b> {{ start|date("d/m/Y H:i") }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Fin =</b> {{ end|date("d/m/Y H:i") }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Durée =</b> {{ duration }}
|
||||
</p>
|
||||
<p>
|
||||
<b>Type =</b> Congé
|
||||
</p>
|
||||
|
||||
|
||||
{% endautoescape %}
|
||||
{% endblock %}
|
||||
|
116
templates/Offer/dolibarr.html.twig
Normal file
116
templates/Offer/dolibarr.html.twig
Normal file
@@ -0,0 +1,116 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<h1 class="page-header">
|
||||
Récupération Commande Client Dolibarr
|
||||
</h1>
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_offer') }}>Annuler</a>
|
||||
|
||||
<br><br>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-pencil-alt fa-fw"></i> Informations
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="form-group ">
|
||||
<label class="control-label required" for="id">ID Proposition<span class="mandatory">*</span></label>
|
||||
<input type="text" id="ref" name="ref" required="required" class=" form-control" value="CO2311-0222">
|
||||
<button id="search" class="btn btn-success mt-1" style="width:100%">Rechercher</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="card-propal" class="card mt-3" style="display:none">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-pencil-alt fa-fw"></i> Lignes propositions
|
||||
</div>
|
||||
|
||||
<div class="card-body" id="propal">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="card-offer" class="card mt-3 mb-3" style="display:none">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-pencil-alt fa-fw"></i> Importer dans Schedule
|
||||
</div>
|
||||
|
||||
<div class="card-body" id="propal">
|
||||
{{ form_start(form) }}
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.project) }}
|
||||
{{ form_widget(form.submit) }}
|
||||
{{ form_end(form) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$("#search").click(function() {
|
||||
console.log("search propositions = "+$("#ref").val());
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
ref: $("#ref").val(),
|
||||
},
|
||||
url: "{{ path('app_offer_getdolibarr') }}",
|
||||
success: function (datas) {
|
||||
console.log(datas);
|
||||
console.log("-----------");
|
||||
if(datas.error||Object.keys(datas).length === 0) {
|
||||
$("#propal").html("");
|
||||
$("#card-propal").hide();
|
||||
$("#card-offer").hide();
|
||||
}
|
||||
else {
|
||||
html ="<h3>"+$("#ref").val()+"</h3>";
|
||||
if(datas.note_public) html+="<strong>Note public</strong><br><small style='display: block;line-height: 14px;'>"+datas.note_public.replace(/(\r\n|\r|\n)/g, '<br>')+"</small><br><br>";
|
||||
if(datas.note_private) html+="<strong>Note privée</strong><br><small style='display: block;line-height: 14px;'>"+datas.note_private.replace(/(\r\n|\r|\n)/g, '<br>')+"</small><br><br>";
|
||||
|
||||
tbtask={};
|
||||
datas.lines.forEach(function(line){
|
||||
console.log(line);
|
||||
if(!tbtask[line.product_ref]) tbtask[line.product_ref]={idoffer:"", idline: "", ref: "", label: "", qty: 0, price:0 };
|
||||
|
||||
tbtask[line.product_ref]["idoffer"]=$("#ref").val();
|
||||
tbtask[line.product_ref]["idline"]=line.id;
|
||||
tbtask[line.product_ref]["ref"]=line.product_ref;
|
||||
tbtask[line.product_ref]["label"]=line.product_label;
|
||||
tbtask[line.product_ref]["qty"]=parseInt(line.qty)+tbtask[line.product_ref]["qty"];
|
||||
tbtask[line.product_ref]["price"]=parseInt(line.price);
|
||||
|
||||
});
|
||||
|
||||
html+="<table style='width:100%;'>";
|
||||
html+="<thead><tr>";
|
||||
html+="<th>Ref</th>";
|
||||
html+="<th>Designation</th>";
|
||||
html+="<th>Qte</th>";
|
||||
html+="<th>PU</th>";
|
||||
html+="<th>Total</th>";
|
||||
html+="</tr></thead>";
|
||||
Object.values(tbtask).forEach(task => {
|
||||
html+="<tr>";
|
||||
html+="<td>"+task.ref+"</td>";
|
||||
html+="<td>"+task.label+"</td>";
|
||||
html+="<td>"+task.qty+"</td>";
|
||||
html+="<td>"+task.price+"</td>";
|
||||
html+="<td>"+(task.qty*task.price)+"</td>";
|
||||
html+="</tr>";
|
||||
});
|
||||
html+="</table>";
|
||||
$("#propal").html(html);
|
||||
|
||||
$("#card-propal").show();
|
||||
$("#card-offer").show();
|
||||
$("#offerdolibarr_tasks").val(JSON.stringify(tbtask));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
{% endblock %}
|
78
templates/Offer/edit.html.twig
Executable file
78
templates/Offer/edit.html.twig
Executable file
@@ -0,0 +1,78 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
COMMANDE
|
||||
{% elseif mode=="update" %}
|
||||
Modification COMMANDE
|
||||
{% elseif mode=="submit" %}
|
||||
Création COMMANDE
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_offer') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_offer_delete',{'id':offer.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.name) }}
|
||||
{{ form_row(form.ref) }}
|
||||
{{ form_row(form.service) }}
|
||||
{{ form_row(form.project) }}
|
||||
|
||||
{{ form_row(form.quantity) }}
|
||||
{{ form_row(form.pu) }}
|
||||
{{ form_row(form.validate) }}
|
||||
{{ form_row(form.cost) }}
|
||||
{{ form_row(form.active) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#offer_name").focus();
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
{% endblock %}
|
187
templates/Offer/list.html.twig
Normal file
187
templates/Offer/list.html.twig
Normal file
@@ -0,0 +1,187 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
{% 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">
|
||||
COMMANDES {% if app.session.get('viewservice') %}PAR ACTVITE{%else%}PAR DOMAINE{%endif%}
|
||||
</h1>
|
||||
|
||||
<a class="btn btn-success" href={{ path('app_offer_submit') }}>Ajouter</a>
|
||||
{% if doliactive == "true" %}
|
||||
<a class="btn btn-success" href={{ path('app_offer_dolibarr') }}>Récupérer les commandes de Dolibarr</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="custom-control custom-switch float-right">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactiveproject" {% if app.session.get('activeproject') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactiveproject">Projet Actif</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-switch float-right" style="margin-right:10px">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactiveoffer" {% if app.session.get('activeoffer') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactiveoffer">Proposition Active</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-switch float-right mr-3">
|
||||
<input type="checkbox" class="custom-control-input" id="switchservice" {% if app.session.get('viewservice') %} checked {% endif %}>
|
||||
{% if app.session.get('viewservice') %}
|
||||
<label class="custom-control-label" for="switchservice">Vue par Activité</label>
|
||||
{% else %}
|
||||
<label class="custom-control-label" for="switchservice">Vue par Domaine</label>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
|
||||
{% if app.session.get('viewservice') %}
|
||||
{% set loop01s=services %}
|
||||
{% else %}
|
||||
{% set loop01s=domaines %}
|
||||
{% endif %}
|
||||
|
||||
{%for loop01 in loop01s %}
|
||||
{% if not loop01.projects is empty %}
|
||||
{% set haveoffer=false %}
|
||||
{% set haveproject=false %}
|
||||
{% for offer in loop01.offers %}
|
||||
{% if app.session.get('activeoffer')==offer.active and app.session.get('activeproject')==offer.project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==offer.project.id) %}
|
||||
{% set haveoffer=true %}
|
||||
{% set haveproject=true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if haveoffer and haveproject %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> {{ loop01.name }}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-sort no-print">Action</th>
|
||||
<th width="200px">Client</th>
|
||||
<th>Projet</th>
|
||||
<th width="100px">Proposition</th>
|
||||
<th width="100px">Ref</th>
|
||||
<th width="70px" class="text-center no-string">Validé hors</th>
|
||||
<th width="70px" class="text-center no-string">Frais</th>
|
||||
<th width="70px" class="text-center no-string">Qt</th>
|
||||
<th width="70px" class="text-center no-string">PU</th>
|
||||
<th width="100px" class="text-center no-string">Total</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if loop01.offers is defined %}
|
||||
{% for offer in loop01.offers %}
|
||||
{% if app.session.get('activeoffer')==offer.active and app.session.get('activeproject')==offer.project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==offer.project.id) %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_offer_update",{id:offer.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{offer.project.customer.name}}</td>
|
||||
<td>{{offer.project.name}}</td>
|
||||
<td>{{offer.name}}</td>
|
||||
|
||||
{% if offer.iddolibarr %}
|
||||
<td><a href="{{doliUri}}/commande/card.php?ref={{offer.ref}}" target="_blank">{{offer.ref}}</td>
|
||||
{% else %}
|
||||
<td>{{offer.ref}}</td>
|
||||
{% endif %}
|
||||
|
||||
<td class="text-right">{{offer.validate|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{offer.cost|number_format(2, '.', ' ')}}</td>
|
||||
|
||||
<td class="text-right">{{offer.quantity|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{offer.pu|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{offer.total|number_format(2, '.', ' ')}}</td>
|
||||
</tr>
|
||||
{%endif%}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for project in loop01.projects %}
|
||||
{% for offer in project.offers %}
|
||||
{% if app.session.get('activeoffer')==offer.active and app.session.get('activeproject')==offer.project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==offer.project.id) %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_offer_update",{id:offer.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{offer.project.customer.name}}</td>
|
||||
<td>{{offer.project.name}}</td>
|
||||
<td>{{offer.name}}</td>
|
||||
{% if offer.iddolibarr %}
|
||||
<td><a href="{{doliUri}}/commande/card.php?ref={{offer.ref}}" target="_blank">{{offer.ref}}</td>
|
||||
{% else %}
|
||||
<td>{{offer.ref}}</td>
|
||||
{% endif %}
|
||||
<td class="text-right">{{offer.validate|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{offer.cost|number_format(2, '.', ' ')}}</td>
|
||||
|
||||
<td class="text-right">{{offer.quantity|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{offer.pu|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{offer.total|number_format(2, '.', ' ')}}</td>
|
||||
</tr>
|
||||
{%endif%}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
{% if not fgprint is defined or not fgprint %}
|
||||
$('.table ').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";
|
||||
}
|
||||
|
||||
$('#switchactiveproject').change(function() {
|
||||
window.location="{{ path('app_offer_activeproject' )}}";
|
||||
});
|
||||
|
||||
$('#switchactiveoffer').change(function() {
|
||||
window.location="{{ path('app_offer_activeoffer' )}}";
|
||||
});
|
||||
|
||||
$('#switchservice').change(function() {
|
||||
window.location="{{ path('app_offer_viewservice' )}}";
|
||||
});
|
||||
{% endblock %}
|
76
templates/Project/edit.html.twig
Executable file
76
templates/Project/edit.html.twig
Executable file
@@ -0,0 +1,76 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
PROJET
|
||||
{% elseif mode=="update" %}
|
||||
Modification PROJET
|
||||
{% elseif mode=="submit" %}
|
||||
Création PROJET
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_project') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_project_delete',{'id':project.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.name) }}
|
||||
{{ form_row(form.active) }}
|
||||
{{ form_row(form.customer) }}
|
||||
{{ form_row(form.visible) }}
|
||||
{{ form_row(form.service) }}
|
||||
{{ form_row(form.domaine) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$("#project_customer").addClass("select2entity");
|
||||
$(document).ready(function() {
|
||||
$("#project_name").focus();
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
|
||||
{% endblock %}
|
182
templates/Project/list.html.twig
Normal file
182
templates/Project/list.html.twig
Normal file
@@ -0,0 +1,182 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
{% 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">
|
||||
PROJETS {% if app.session.get('viewservice') %} PAR ACTVITE{%else%} PAR DOMAINE{%endif%}
|
||||
</h1>
|
||||
|
||||
<a class="btn btn-success" href={{ path('app_project_submit') }}>Ajouter</a>
|
||||
|
||||
<div class="custom-control custom-switch float-right">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactive" {% if app.session.get('activeproject') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactive">Projet Actif</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-switch float-right mr-3">
|
||||
<input type="checkbox" class="custom-control-input" id="switchservice" {% if app.session.get('viewservice') %} checked {% endif %}>
|
||||
{% if app.session.get('viewservice') %}
|
||||
<label class="custom-control-label" for="switchservice">Vue par Activité</label>
|
||||
{% else %}
|
||||
<label class="custom-control-label" for="switchservice">Vue par Domaine</label>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
|
||||
{% if app.session.get('viewservice') %}
|
||||
{% set loop01s=services %}
|
||||
{% else %}
|
||||
{% set loop01s=domaines %}
|
||||
{% endif %}
|
||||
|
||||
{%for loop01 in loop01s %}
|
||||
{% if not loop01.projects is empty %}
|
||||
{% set haveproject=false %}
|
||||
|
||||
{% for project in loop01.projects %}
|
||||
{% if app.session.get('activeproject')==project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==project.id) %}
|
||||
{% set haveproject=true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if haveproject %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> {{ loop01.name }}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-sort no-print">Action</th>
|
||||
<th width="200px">Client</th>
|
||||
<th>Nom</th>
|
||||
<th width="200px">{% if app.session.get('viewservice') %}Domaine{%else%}Activité{%endif%}</th>
|
||||
<th width="100px" class="text-center no-string">Estimé</th>
|
||||
<th width="100px" class="text-center no-string">Commandé</th>
|
||||
<th width="100px" class="text-center no-string">Validé</th>
|
||||
<th width="100px" class="text-center no-string">Solde Validé</th>
|
||||
<th width="100px" class="text-center no-string">Plannifié</th>
|
||||
<th width="100px" class="text-center no-string">Solde</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for project in loop01.projects %}
|
||||
{% if app.session.get('activeproject')==project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==project.id) %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_project_update",{id:project.id})}}"><i class="fa fa-file"></i></a>
|
||||
<a href="{{path("app_project_users",{id:project.id})}}"
|
||||
data-toggle="tooltip"
|
||||
data-placement="right"
|
||||
data-html="true"
|
||||
title="{% for user in project.userprojects %}<b>{{user.user.username}}:</b> {{user.job.name}} <br />{% endfor %}"
|
||||
><i class="fa fa-users"></i></a>
|
||||
|
||||
</td>
|
||||
<td>{{project.customer.name}}</td>
|
||||
<td>{{project.name}}</td>
|
||||
<td>{% if app.session.get('viewservice') %}{{project.domaine.name}}{%else%}{{project.service.name}}{%endif%}</td>
|
||||
<td class="text-right">
|
||||
{% set tottask=0 %}
|
||||
{% set totvalidate=0 %}
|
||||
{% set totplanified=0 %}
|
||||
{% set totoffer=0 %}
|
||||
|
||||
{% for offer in project.offers %}
|
||||
{% set totoffer=(totoffer+offer.quantity) %}
|
||||
{% set totvalidate=totvalidate+offer.validate %}
|
||||
{% set totplanified=totplanified+offer.validate %}
|
||||
{% endfor %}
|
||||
|
||||
{% for task in project.tasks %}
|
||||
{% set tottask=tottask+task.quantity %}
|
||||
|
||||
{% for event in task.events %}
|
||||
{% set totplanified=totplanified+event.duration %}
|
||||
{% if event.validate %}
|
||||
{% set totvalidate=totvalidate+event.duration %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for penalty in task.penaltys %}
|
||||
{% set totplanified=totplanified+penalty.duration %}
|
||||
{% if penalty.validate %}
|
||||
{% set totvalidate=totvalidate+penalty.duration %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{{ tottask|number_format(2, '.', ' ') }}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{ totoffer|number_format(2, '.', ' ') }}
|
||||
</td>
|
||||
<td class="text-right">{{ (totvalidate*-1)|number_format(2, '.', ' ') }}</td>
|
||||
<td class="text-right">{{ (totoffer-totvalidate)|number_format(2, '.', ' ') }}</td>
|
||||
<td class="text-right">{{ ((totplanified-totvalidate)*-1)|number_format(2, '.', ' ') }}</td>
|
||||
<td class="text-right">{{ (totoffer-totplanified)|number_format(2, '.', ' ') }}</td>
|
||||
</tr>
|
||||
{%endif%}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
})
|
||||
$(document).ready(function() {
|
||||
{% if not fgprint is defined or not fgprint %}
|
||||
$('.table').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 %}
|
||||
});
|
||||
|
||||
$('#switchactive').change(function() {
|
||||
window.location="{{ path('app_project_activeproject' )}}";
|
||||
});
|
||||
|
||||
$('#switchservice').change(function() {
|
||||
window.location="{{ path('app_project_viewservice' )}}";
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
|
||||
{% endblock %}
|
210
templates/Project/users.html.twig
Normal file
210
templates/Project/users.html.twig
Normal file
@@ -0,0 +1,210 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
{% 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">
|
||||
PROJET METIERS<br>
|
||||
{{project.displayname}}
|
||||
</h1>
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_project') }}>Fermer</a>
|
||||
|
||||
<p></p>
|
||||
|
||||
<div class="row" style="margin: 0px">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Utilisateurs
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-sort no-print">Action</th>
|
||||
<th>Nom</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for user in users %}
|
||||
{% if "ROLE_USER" in user.roles %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<button class="btn btn-link" onClick="modalJob({{user.id}})"><i class="fa fa-plus"></i></a>
|
||||
</td>
|
||||
|
||||
<td>{{user.displayname}}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
{% for userproject in userprojects %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> {{ userproject.name }}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-sort no-print">Action</th>
|
||||
<th>Nom</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for user in userproject.users %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<button class="btn btn-link" onClick="delJob({{user.id}})"><i class="fa fa-minus"></i></a>
|
||||
</td>
|
||||
|
||||
<td>{{user.user.displayname}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modaljob" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Métier</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<button onClick="addJob()" class="btn btn-success">Valider</button>
|
||||
<button onClick="" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
|
||||
|
||||
<p></p>
|
||||
<div class="form-group">
|
||||
<label class="control-label required" for="idjob">
|
||||
Métier<span class="mandatory">*</span>
|
||||
</label>
|
||||
<select class="select2entity" id="idjob" name="idjob">
|
||||
<option></option>
|
||||
{% for job in jobs %}
|
||||
<option value="{{job.id}}">{{job.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="iduser" name="iduser" class="form-control" value="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
{% if not fgprint is defined or not fgprint %}
|
||||
$('.table').DataTable({
|
||||
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
|
||||
responsive: true,
|
||||
iDisplayLength: 100,
|
||||
order: [[ 1, "asc" ]],
|
||||
searching: false,
|
||||
paging: false,
|
||||
info: false
|
||||
});
|
||||
{%else%}
|
||||
$('#dataTables').removeClass("table table-striped table-bordered table-hover small dataTable no-footer");
|
||||
{% endif %}
|
||||
});
|
||||
|
||||
function modalJob(iduser) {
|
||||
$("#iduser").val(iduser);
|
||||
$("#modaljob .alert").remove();
|
||||
$("#modaljob").modal('show');
|
||||
}
|
||||
|
||||
function addJob() {
|
||||
$("#modaljob .alert").remove();
|
||||
|
||||
iduser=$("#iduser").val();
|
||||
idjob=$("#idjob").val();
|
||||
if(idjob) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
idproject: {{project.id}},
|
||||
idjob: idjob,
|
||||
iduser: iduser,
|
||||
},
|
||||
url: "{{ path('app_project_users_add') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
$("#modaljob .modal-body").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
|
||||
}
|
||||
else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function delJob(iduser) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
iduser: iduser,
|
||||
},
|
||||
url: "{{ path('app_project_users_del') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
}
|
||||
else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
|
||||
{% endblock %}
|
103
templates/Report/holiday.html.twig
Normal file
103
templates/Report/holiday.html.twig
Normal file
@@ -0,0 +1,103 @@
|
||||
{% 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; }
|
||||
.homecard {width: 100% }
|
||||
{%endif%}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
MES CONGES
|
||||
</h1>
|
||||
|
||||
<div class="custom-control custom-switch float-right">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactive" {% if app.session.get('activeholiday') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactive">Congès à Valider</label>
|
||||
</div>
|
||||
<div style="height:30px;">
|
||||
</div>
|
||||
|
||||
<div class="card homecard">
|
||||
<div class="card-header">
|
||||
Mes Congés
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<th>Utilisateur</th>
|
||||
<th>Tâche</th>
|
||||
<th>Début</th>
|
||||
<th>Fin</th>
|
||||
<th>Durée</th>
|
||||
</thead>
|
||||
|
||||
{% for user in users %}
|
||||
{% for event in user.holidays %}
|
||||
<tr id="row-{{event.id}}">
|
||||
<td>
|
||||
{{ user.user.displayname }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.task }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.start|date("d/m/Y H:i") }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.end|date("d/m/Y H:i") }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.duration }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
{% if not fgprint is defined or not fgprint %}
|
||||
$('.table ').DataTable({
|
||||
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
|
||||
responsive: true,
|
||||
iDisplayLength: 100,
|
||||
order: [[ 0, "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";
|
||||
}
|
||||
|
||||
$('#switchactive').change(function() {
|
||||
window.location="{{ path('app_holiday_activeholiday' )}}";
|
||||
});
|
||||
|
||||
{% endblock %}
|
192
templates/Report/planning.html.twig
Normal file
192
templates/Report/planning.html.twig
Normal file
@@ -0,0 +1,192 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
.card {
|
||||
margin: 20px 20px 0px 0px;
|
||||
}
|
||||
|
||||
.card-body .month {
|
||||
margin: 20px 0px 0px 0px;
|
||||
|
||||
}
|
||||
.card-body .month:first-child {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.card-header h2 {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.card-header .synthese {
|
||||
float:right;
|
||||
font-size:12px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th,td {
|
||||
border: 1px solid #37474F;
|
||||
color: #000000;
|
||||
background-color:#cccccc;
|
||||
}
|
||||
|
||||
.intervenant {
|
||||
width:200px;
|
||||
padding-left:5px;
|
||||
}
|
||||
|
||||
.total {
|
||||
text-align:center;
|
||||
width:70px;
|
||||
background-color:#888888;
|
||||
}
|
||||
.day {
|
||||
text-align:center;
|
||||
width: 40px;
|
||||
height:40px;
|
||||
}
|
||||
.astreinte {
|
||||
height: 12px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
|
||||
{% if fgprint is defined and fgprint %}
|
||||
h2, h3 {
|
||||
display:block !important;
|
||||
float:none !important;
|
||||
}
|
||||
|
||||
table { width:100%; font-size:10px;}
|
||||
|
||||
.card-header .synthese {
|
||||
float:none !important;
|
||||
text-align:left !important;
|
||||
}
|
||||
|
||||
.day {
|
||||
height:auto !important;
|
||||
}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
{% if fgprint is defined and fgprint %}<h1>Planning</h1>{%endif%}
|
||||
|
||||
{% if access=="customer" and not app.user %}
|
||||
<div class="no-print" style="margin-top:10px;">
|
||||
<style> .select2-container { display:inline-block} </style>
|
||||
<a class="btn btn-info" href="{{ path("app_customer_report",{"key":key})}}">Rapport</a>
|
||||
<a class="btn btn-success" href="{{ path("app_customer_planning",{"key":key})}}">Planning</a>
|
||||
Nombre de mois
|
||||
<select class="form-control select2entity" id="sidemonth" name="sidemonth" style="width:auto; display:inline-block">
|
||||
{% set selected="" %}
|
||||
{% for i in 1..48 %}
|
||||
{% set selected="" %}
|
||||
{%if i==app.session.get('nbmonth') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{i}}" {{selected}}>{{i}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% for project in projects %}
|
||||
{% if not project.months is empty %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2>{{ project.displayname }}</h2>
|
||||
<div class="synthese">
|
||||
Estimé = {{ project.estimate }}<br>
|
||||
Commandé = {{ project.proposed }}<br>
|
||||
Validé = {{ project.validate }}<br>
|
||||
Planifié = {{ project.planified }}<br>
|
||||
<b>RESTE = {{ ( project.proposed - project.validate - project.planified) }}</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
{% set month="" %}
|
||||
|
||||
{% for month in project.months %}
|
||||
<h3 class="month">{{ month.monthlabel }}</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<th class="intervenant">Intervenant</th>
|
||||
{% for day in month.days %}
|
||||
<th class="day" style="background-color: {{ day.daycolor }}">
|
||||
{{ day.daylabel }}<br>
|
||||
{{ day.daynumber }}
|
||||
</th>
|
||||
{% endfor %}
|
||||
<th class="total">Total</th>
|
||||
</thead>
|
||||
|
||||
{% for user in month.users %}
|
||||
<tr>
|
||||
<td class="intervenant">{{ user.displayname }}</td>
|
||||
|
||||
{% for day in user.days %}
|
||||
<td class="day" style="background-color: {{ day.daycolor }}">
|
||||
{% if day.duration > 0 %}
|
||||
{{ day.duration }}
|
||||
{% endif %}
|
||||
{% if day.astreinte > 0 %}
|
||||
<div class="astreinte">A</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
<td class="total">{{user.total}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% if month.total > 0 %}
|
||||
<br>
|
||||
<table class="recaptask small">
|
||||
{% for task in month.tasks %}
|
||||
<tr>
|
||||
<td>{{ task.displayname }}</td>
|
||||
<td class="text-right">{{ task.duration|number_format(2, '.', ' ') }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% if month.totala > 0 %}
|
||||
<tr>
|
||||
<td>Astreinte</td>
|
||||
<td class="text-right">{{ month.totala|number_format(2, '.', ' ') }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td style="min-width:200px">TOTAL</td>
|
||||
<td class="text-right" style="min-width:100px">{{ (month.total + month.totala)|number_format(2, '.', ' ') }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if month.total > 0 %}
|
||||
<i>Total = {{ month.total }}</i>
|
||||
{% endif %}
|
||||
|
||||
{% if month.totala > 0 %}
|
||||
<i>Total Astreinte = {{ month.totala }}</i>
|
||||
{% endif %}
|
||||
<div class="new-page"> </div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<br>
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
{% endblock %}
|
391
templates/Report/report.html.twig
Normal file
391
templates/Report/report.html.twig
Normal file
@@ -0,0 +1,391 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
.card {
|
||||
margin: 20px 20px 0px 0px;
|
||||
}
|
||||
|
||||
.card-body .month {
|
||||
margin: 20px 0px 0px 0px;
|
||||
|
||||
}
|
||||
.card-body .month:first-child {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.card-header h2 {
|
||||
float:left;
|
||||
}
|
||||
|
||||
.card-header .synthese {
|
||||
float:right;
|
||||
font-size:12px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.card-body h4 { margin: 20px 0px 0px 0px;}
|
||||
.card-body h4:first-child { margin: 0px;}
|
||||
|
||||
th,td, tfoot {
|
||||
border: 1px solid #37474F;
|
||||
color: #000000;
|
||||
background-color:#cccccc;
|
||||
}
|
||||
|
||||
.recaptask td, .recapoffer td {
|
||||
background-color:#ffffff;
|
||||
color: #212529;
|
||||
padding: 3px;
|
||||
}
|
||||
.recaptask tfoot td, .recapoffer thead td, .recapoffer tfoot td {
|
||||
background-color:#cccccc;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.intervenant {
|
||||
width:200px;
|
||||
padding-left:5px;
|
||||
}
|
||||
|
||||
.total {
|
||||
text-align:center;
|
||||
width:70px;
|
||||
background-color:#888888;
|
||||
}
|
||||
.day {
|
||||
text-align:center;
|
||||
width: 40px;
|
||||
height:40px;
|
||||
}
|
||||
.astreinte {
|
||||
height: 12px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
{% if fgprint is defined and fgprint %}
|
||||
h2, h3 {
|
||||
display:block !important;
|
||||
float:none !important;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
table { width:100%; font-size:10px;}
|
||||
|
||||
.card-header .synthese {
|
||||
float:none !important;
|
||||
text-align:left !important;
|
||||
}
|
||||
|
||||
.day {
|
||||
height:auto !important;
|
||||
}
|
||||
|
||||
.small { font-size:10px;}
|
||||
|
||||
h4 {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% if fgprint is defined and fgprint %}<h1>Planning</h1>{%endif%}
|
||||
{% if access=="customer" and not app.user %}
|
||||
<div class="no-print" style="margin-top:10px;">
|
||||
<style> .select2-container { display:inline-block} </style>
|
||||
<a class="btn btn-success" href="{{ path("app_customer_report",{"key":key})}}">Rapport</a>
|
||||
<a class="btn btn-info" href="{{ path("app_customer_planning",{"key":key})}}">Planning</a>
|
||||
Nombre de mois
|
||||
<select class="form-control select2entity" id="sidemonth" name="sidemonth" style="width:auto; display:inline-block">
|
||||
{% set selected="" %}
|
||||
{% for i in 1..48 %}
|
||||
{% set selected="" %}
|
||||
{%if i==app.session.get('nbmonth') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{i}}" {{selected}}>{{i}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% for project in projects %}
|
||||
{% if not project.months is empty or project.hors!=0 or not project.before is empty or not project.beforeastreinte is empty %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2>{{ project.displayname }}</h2>
|
||||
<div class="synthese">
|
||||
Commandé = {{ project.proposed|number_format(2, '.', ' ') }}<br>
|
||||
Consommé = {{ project.validate|number_format(2, '.', ' ') }}<br>
|
||||
<b>RESTE = {{ (project.proposed - project.validate)|number_format(2, '.', ' ') }}</b>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<h3>RAPPORT</h3>
|
||||
<div class="small">
|
||||
|
||||
{% for month in project.months %}
|
||||
<h3 class="month">{{ month.monthlabel }}</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<th class="intervenant">Intervenant</th>
|
||||
{% for day in month.days %}
|
||||
<th class="day" style="background-color: {{ day.daycolor }}">
|
||||
{{ day.daylabel }}<br>
|
||||
{{ day.daynumber }}
|
||||
</th>
|
||||
{% endfor %}
|
||||
<th class="total">Total</th>
|
||||
</thead>
|
||||
|
||||
{% for user in month.users %}
|
||||
<tr>
|
||||
<td class="intervenant">{{ user.displayname }}</td>
|
||||
|
||||
{% for day in user.days %}
|
||||
<td class="day" style="background-color: {{ day.daycolor }}">
|
||||
{% if day.duration > 0 %}
|
||||
{{ day.duration }}
|
||||
{% endif %}
|
||||
{% if day.astreinte > 0 %}
|
||||
<div class="astreinte">A</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
<td class="total">{{user.total}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% if month.total > 0 %}
|
||||
<br>
|
||||
<table class="recaptask small">
|
||||
{% for task in month.tasks %}
|
||||
<tr>
|
||||
<td>{{ task.displayname }}</td>
|
||||
<td class="text-right">{{ task.duration|number_format(2, '.', ' ') }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% if month.totala > 0 %}
|
||||
<tr>
|
||||
<td>Astreinte</td>
|
||||
<td class="text-right">{{ month.totala|number_format(2, '.', ' ') }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td style="min-width:200px">TOTAL</td>
|
||||
<td class="text-right" style="min-width:100px">{{ (month.total + month.totala)|number_format(2, '.', ' ') }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<h4>CUMUL HEBDOMADAIRE</h4>
|
||||
<table>
|
||||
{% for year, weeks in project.weeks %}
|
||||
<thead>
|
||||
<th class="text-center day">
|
||||
{{ year}}
|
||||
</th>
|
||||
{% for week in weeks %}
|
||||
<th class="text-center">
|
||||
S{{ week.weeknumber}}
|
||||
</th>
|
||||
{% endfor %}
|
||||
</thead>
|
||||
<tr class="text-center">
|
||||
<td class="text-center">
|
||||
|
||||
</td>
|
||||
{% for week in weeks %}
|
||||
<td class="text-center">
|
||||
{{ week.cumul}}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% if not project.offers is empty %}
|
||||
<h4>COMMANDES</h4>
|
||||
{% set count=(project.offers|length)-8 %}
|
||||
{% set totbefore10=0 %}
|
||||
{% set decoproposed=project.proposed %}
|
||||
{% set decovalidate=project.validate %}
|
||||
<table class="recapoffer small">
|
||||
<thead>
|
||||
<td width="200px">Libellé</td>
|
||||
<td width="200px">Référence</td>
|
||||
<td width="100px" class="text-center">Commandé</td>
|
||||
<td width="100px" class="text-center">Consommé</td>
|
||||
<td width="100px" class="text-center">Reste</td>
|
||||
</thead>
|
||||
{% set tot=0 %}
|
||||
{% for offer in project.offers %}
|
||||
{% if loop.index<count %}
|
||||
{% set totbefore10=totbefore10+offer.quantity %}
|
||||
{% if loop.index+1==count %}
|
||||
<tr>
|
||||
<td colspan="2">Précédente</td>
|
||||
<td class="text-right">{{ totbefore10|number_format(2, '.', ' ') }}</td>
|
||||
|
||||
<td class="text-right">
|
||||
{% if decovalidate >= totbefore10 %}
|
||||
{{ totbefore10|number_format(2, '.', ' ') }}
|
||||
{% set todel=totbefore10 %}
|
||||
{% else %}
|
||||
{% if decovalidate >= 0 %}
|
||||
{{ decovalidate|number_format(2, '.', ' ') }}
|
||||
{% set todel=decovalidate %}
|
||||
{% else %}
|
||||
0.00
|
||||
{% set todel=0 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% set decovalidate=decovalidate-totbefore10 %}
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
{{ (totbefore10-todel)|number_format(2, '.', ' ') }}
|
||||
{% set decoproposed=decoproposed-totbefore10 %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if not loop.last %}
|
||||
<tr>
|
||||
<td>{{ offer.name }}</td>
|
||||
<td>{{ offer.ref }}</td>
|
||||
<td class="text-right">{{ offer.quantity|number_format(2, '.', ' ') }}</td>
|
||||
|
||||
<td class="text-right">
|
||||
{% if decovalidate >= offer.quantity %}
|
||||
{{ offer.quantity|number_format(2, '.', ' ') }}
|
||||
{% set todel=offer.quantity %}
|
||||
{% else %}
|
||||
{% if decovalidate >= 0 %}
|
||||
{{ decovalidate|number_format(2, '.', ' ') }}
|
||||
{% set todel=decovalidate %}
|
||||
{% else %}
|
||||
0.00
|
||||
{% set todel=0 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% set decovalidate=decovalidate-offer.quantity %}
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
{{ (offer.quantity-todel)|number_format(2, '.', ' ') }}
|
||||
{% set decoproposed=decoproposed-totbefore10 %}
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>{{ offer.name }}</td>
|
||||
<td>{{ offer.ref }}</td>
|
||||
<td class="text-right">{{ offer.quantity|number_format(2, '.', ' ') }}</td>
|
||||
|
||||
<td class="text-right">
|
||||
{% if decovalidate >= 0 %}
|
||||
{{ decovalidate|number_format(2, '.', ' ') }}
|
||||
{% set todel=decovalidate %}
|
||||
{% else %}
|
||||
0.00
|
||||
{% set todel=0 %}
|
||||
{% endif %}
|
||||
{% set decovalidate=decovalidate-offer.quantity %}
|
||||
</td>
|
||||
|
||||
<td class="text-right">
|
||||
{{ (offer.quantity-todel)|number_format(2, '.', ' ') }}
|
||||
{% set decoproposed=decoproposed-totbefore10 %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<tfoot>
|
||||
<td colspan="2">TOTAL</td>
|
||||
<td class="text-right">{{ project.proposed|number_format(2, '.', ' ') }}</td>
|
||||
<td class="text-right">{{ project.validate|number_format(2, '.', ' ') }}</td>
|
||||
<td class="text-right">{{ (project.proposed - project.validate)|number_format(2, '.', ' ') }}</td>
|
||||
</tfoot>
|
||||
</table>
|
||||
{% endif %}
|
||||
<h4>CONSOMMATION PASSEE</h4>
|
||||
{% if project.hors!=0 %}
|
||||
Consommation précédente totale = {{ project.hors }}<br>
|
||||
{% endif %}
|
||||
|
||||
<table>
|
||||
{% for year in project.before %}
|
||||
<thead>
|
||||
<th class="text-center day">
|
||||
Date
|
||||
</th>
|
||||
{% for month in year %}
|
||||
<th class="text-center">
|
||||
{{ month.monthlabel }}
|
||||
</th>
|
||||
{% endfor %}
|
||||
</thead>
|
||||
<tr class="text-center">
|
||||
<td class="text-center">
|
||||
Consommé
|
||||
</td>
|
||||
{% for month in year %}
|
||||
<td class="text-center">
|
||||
{{ month.duration }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% if not project.beforeastreinte is empty %}
|
||||
<h4>ASTREINTES PASSEES</h4>
|
||||
<table>
|
||||
{% for year in project.beforeastreinte %}
|
||||
<thead>
|
||||
<th class="text-center day">
|
||||
Date
|
||||
</th>
|
||||
{% for month in year %}
|
||||
<th class="text-center">
|
||||
{{ month.monthlabel }}
|
||||
</th>
|
||||
{% endfor %}
|
||||
</thead>
|
||||
<tr class=" text-center">
|
||||
<td class="text-center">
|
||||
Consommé
|
||||
</td>
|
||||
{% for month in year %}
|
||||
<td class="text-center">
|
||||
{{ month.duration }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="new-page"> </div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<br>
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
{% endblock %}
|
144
templates/Report/synthese.html.twig
Normal file
144
templates/Report/synthese.html.twig
Normal file
@@ -0,0 +1,144 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
.homecard {
|
||||
margin: 20px 20px 0px 0px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
table {
|
||||
|
||||
}
|
||||
|
||||
th,td {
|
||||
border: 1px solid #37474F;
|
||||
color: #ffffff;
|
||||
background-color:#37474F;
|
||||
text-align:center;
|
||||
width: 70px;
|
||||
}
|
||||
td {
|
||||
background-color:#e8ecf1;
|
||||
cursor: help;
|
||||
height: 44px;
|
||||
vertical-align: top;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 9px;
|
||||
color: #37474F;
|
||||
}
|
||||
|
||||
.allday {
|
||||
font-size: 12px;
|
||||
float:left;
|
||||
width:100%;
|
||||
height: 18px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.am, .ap {
|
||||
font-size: 12px;
|
||||
float:left;
|
||||
width:50%;
|
||||
height: 18px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.astreinte {
|
||||
font-size: 11px;
|
||||
float:left;
|
||||
width:100%;
|
||||
height:12px;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
{% if fgprint is defined and fgprint %}<h1>Synthèse</h1>{%endif%}
|
||||
{% for user in users %}
|
||||
{% set nbday=1 %}
|
||||
|
||||
<div class="card homecard" style="width:380px;">
|
||||
<div class="card-header">
|
||||
<img src="\{{appAlias}}\uploads\avatar\{{user.user.avatar}}" class='avatar no-print'>
|
||||
{{ user.user.displayname }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table>
|
||||
<thead>
|
||||
<th>S</th>
|
||||
<th>L</th>
|
||||
<th>M</th>
|
||||
<th>M</th>
|
||||
<th>J</th>
|
||||
<th>V</th>
|
||||
<th>S</th>
|
||||
<th>D</th>
|
||||
</thead>
|
||||
|
||||
{% for event in user.events %}
|
||||
{% if nbday==1 %}
|
||||
<tr>
|
||||
<td class="date" style="vertical-align:middle">{{event.date|date("W")}}</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<div class="date">{{ event.date | date("d/m") }}</div>
|
||||
<div class="d-flex flex-wrap">
|
||||
{% set haveam=false %}
|
||||
{% for detail in event.events %}
|
||||
{% if detail.allday %}
|
||||
<div class='allday' style='background-color:{{ detail.colorday }};' title='{{ detail.descriptionday }}'>1</div>
|
||||
{% else %}
|
||||
{%if detail.am %}
|
||||
{% set haveam=true %}
|
||||
<div class='am' style='background-color:{{ detail.coloram }};' title='{{ detail.descriptionam }}'>0.5</div>
|
||||
{% endif %}
|
||||
|
||||
{%if detail.ap %}
|
||||
{% if not haveam %}<div class='am'></div>{%endif%}
|
||||
<div class='ap ml-auto' style='background-color:{{ detail.colorap }};' title='{{ detail.descriptionap }}'>0.5</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if event.astreinte %}
|
||||
<div class='astreinte' style='background-color:{{ event.colorastreinte }};' title='{{ event.descriptionastreinte }}'>*</div>
|
||||
{% else %}
|
||||
<div class='astreinte'></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{% set nbday=nbday+1 %}
|
||||
{% if nbday==8 %}
|
||||
</tr>
|
||||
{% set nbday=1 %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if (loop.index % 2) == 0 %} <div class="new-page"> </div> {% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
function myprint() {
|
||||
document.location.href="{{path(app.request.attributes.get('_route'),{fgprint:true})}}";
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
maxheight=0;
|
||||
$( ".card" ).each(function( index ) {
|
||||
if($(this).height()>maxheight)
|
||||
maxheight=$(this).height();
|
||||
});
|
||||
$( ".card" ).height(maxheight);
|
||||
});
|
||||
|
||||
{% endblock %}
|
71
templates/Service/edit.html.twig
Executable file
71
templates/Service/edit.html.twig
Executable file
@@ -0,0 +1,71 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
SERVICE
|
||||
{% elseif mode=="update" %}
|
||||
Modification SERVICE
|
||||
{% elseif mode=="submit" %}
|
||||
Création SERVICE
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_service') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_service_delete',{'id':service.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.name) }}
|
||||
{% if form.dolibarrcode is defined %} {{ form_row(form.dolibarrcode) }} {% endif %}
|
||||
{{ form_row(form.description) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#service_name").focus();
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
{% endblock %}
|
72
templates/Service/list.html.twig
Normal file
72
templates/Service/list.html.twig
Normal file
@@ -0,0 +1,72 @@
|
||||
{% 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">
|
||||
SERVICES
|
||||
</h1>
|
||||
|
||||
<p><a class="btn btn-success" href={{ path('app_service_submit') }}>Ajouter</a></p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Services
|
||||
</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>Nom</th>
|
||||
{% if doliActive %}<th>Code Dolibarr</th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for service in services %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_service_update",{id:service.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{service.name}}</td>
|
||||
{% if doliActive %}<td>{{service.dolibarrcode}}</td>{% endif %}
|
||||
</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 %}
|
161
templates/Stat/view.html.twig
Normal file
161
templates/Stat/view.html.twig
Normal file
@@ -0,0 +1,161 @@
|
||||
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
STATISTIQUES
|
||||
</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 mb-4">
|
||||
<div class="card homecard" style="width: 100%; height: 520px;">
|
||||
<div class="card-header">
|
||||
CADOLES
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="chart-c" style="height: 250px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card homecard" style="width: 100%; height: 520px;">
|
||||
<div class="card-header">
|
||||
DEV
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="chart-1" style="height: 250px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card homecard" style="width: 100%; height: 520px;">
|
||||
<div class="card-header">
|
||||
CSS
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="chart-3" style="height: 250px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
|
||||
graphCadoles();
|
||||
graphDEV();
|
||||
graphCSS();
|
||||
});
|
||||
|
||||
function graphCadoles() {
|
||||
|
||||
new Morris.Line({
|
||||
element: 'chart-c',
|
||||
xkey: 'month',
|
||||
ymax: 350,
|
||||
ykeys: [
|
||||
'Total',
|
||||
{% for nature in tbnatures %}
|
||||
'{{ nature.name }}',
|
||||
{% endfor %}
|
||||
],
|
||||
data: [
|
||||
{% for month in tbmonths %}
|
||||
{ month: '{{ month.name }}',
|
||||
{% for nature in month.natures %}
|
||||
{% if loop.first %}
|
||||
'Total': {{ nature.totalmonth }},
|
||||
{% endif %}
|
||||
|
||||
'{{ nature.name }}': {{ nature.totalnature }},
|
||||
{% endfor %}
|
||||
},
|
||||
{% endfor %}
|
||||
],
|
||||
labels: [
|
||||
'Total',
|
||||
{% for nature in tbnatures %}
|
||||
'{{ nature.name }}',
|
||||
{% endfor %}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function graphDEV() {
|
||||
|
||||
new Morris.Line({
|
||||
element: 'chart-1',
|
||||
xkey: 'month',
|
||||
ymax: 160,
|
||||
ykeys: [
|
||||
'Total',
|
||||
{% for nature in tbnatures %}
|
||||
'{{ nature.name }}',
|
||||
{% endfor %}
|
||||
],
|
||||
data: [
|
||||
{% for month in tbmonths %}
|
||||
{ month: '{{ month.name }}',
|
||||
{% for nature in month.services[1].natures %}
|
||||
{% if loop.first %}
|
||||
'Total': {{ nature.totalservice }},
|
||||
{% endif %}
|
||||
|
||||
'{{ nature.name }}': {{ nature.totalnature }},
|
||||
{% endfor %}
|
||||
},
|
||||
{% endfor %}
|
||||
],
|
||||
labels: [
|
||||
'Total',
|
||||
{% for nature in tbnatures %}
|
||||
'{{ nature.name }}',
|
||||
{% endfor %}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
function graphCSS() {
|
||||
new Morris.Line({
|
||||
element: 'chart-3',
|
||||
xkey: 'month',
|
||||
ymax: 160,
|
||||
ykeys: [
|
||||
'Total',
|
||||
{% for nature in tbnatures %}
|
||||
'{{ nature.name }}',
|
||||
{% endfor %}
|
||||
],
|
||||
data: [
|
||||
{% for month in tbmonths %}
|
||||
{ month: '{{ month.name }}',
|
||||
{% for nature in month.services[3].natures %}
|
||||
{% if loop.first %}
|
||||
'Total': {{ nature.totalservice }},
|
||||
{% endif %}
|
||||
'{{ nature.name }}': {{ nature.totalnature }},
|
||||
{% endfor %}
|
||||
},
|
||||
{% endfor %}
|
||||
],
|
||||
labels: [
|
||||
'Total',
|
||||
{% for nature in tbnatures %}
|
||||
'{{ nature.name }}',
|
||||
{% endfor %}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localexternalscript %}
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script>
|
||||
{% endblock %}
|
||||
|
83
templates/Task/edit.html.twig
Executable file
83
templates/Task/edit.html.twig
Executable file
@@ -0,0 +1,83 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
TACHE
|
||||
{% elseif mode=="update" %}
|
||||
Modification TACHE
|
||||
{% elseif mode=="submit" %}
|
||||
Création TACHE
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_task') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_task_delete',{'id':task.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.name) }}
|
||||
{{ form_row(form.project) }}
|
||||
{{ form_row(form.nature) }}
|
||||
{{ form_row(form.active) }}
|
||||
{{ form_row(form.quantity) }}
|
||||
{{ form_row(form.color) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#task_name").focus();
|
||||
|
||||
$("#task_color").spectrum(
|
||||
{
|
||||
type: "text",
|
||||
showAlpha: false
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
|
||||
{% endblock %}
|
176
templates/Task/list.html.twig
Normal file
176
templates/Task/list.html.twig
Normal file
@@ -0,0 +1,176 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
|
||||
{% 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">
|
||||
TACHES {% if app.session.get('viewservice') %}PAR ACTVITE{%else%}PAR DOMAINE{%endif%}
|
||||
</h1>
|
||||
|
||||
<a class="btn btn-success" href={{ path('app_task_submit') }}>Ajouter</a>
|
||||
|
||||
<div class="custom-control custom-switch float-right">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactive" {% if app.session.get('activeproject') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactive">Projet Actif</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-switch float-right" style="margin-right:20px">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactivetask" {% if app.session.get('activetask') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactivetask">Tâche Active</label>
|
||||
</div>
|
||||
|
||||
<div class="custom-control custom-switch float-right mr-3">
|
||||
<input type="checkbox" class="custom-control-input" id="switchservice" {% if app.session.get('viewservice') %} checked {% endif %}>
|
||||
{% if app.session.get('viewservice') %}
|
||||
<label class="custom-control-label" for="switchservice">Vue par Activité</label>
|
||||
{% else %}
|
||||
<label class="custom-control-label" for="switchservice">Vue par Domaine</label>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
|
||||
{% if app.session.get('viewservice') %}
|
||||
{% set loop01s=services %}
|
||||
{% else %}
|
||||
{% set loop01s=domaines %}
|
||||
{% endif %}
|
||||
|
||||
{%for loop01 in loop01s %}
|
||||
{% if not loop01.projects is empty %}
|
||||
{% set havetask=false %}
|
||||
{% set haveproject=false %}
|
||||
|
||||
{% for project in loop01.projects %}
|
||||
{% if app.session.get('activeproject')==project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==project.id) %}
|
||||
{% if not project.tasks is empty %}
|
||||
{% set havetask=true %}
|
||||
{% endif %}
|
||||
|
||||
{% set haveproject=true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if haveproject and havetask %}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> {{ loop01.name }}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-sort no-print">Action</th>
|
||||
<th width="150px">Client</th>
|
||||
<th width="100px">Nature</th>
|
||||
<th width="100px">Projet</th>
|
||||
<th>Tâche</th>
|
||||
<th>Actif</th>
|
||||
<th width="100px" class="text-center no-string">Estimation</th>
|
||||
<th width="100px" class="text-center no-string">Validé</th>
|
||||
<th width="100px" class="text-center no-string">Planifié</th>
|
||||
<th width="100px" class="text-center no-string">Reste</th>
|
||||
<th width="70px" class="text-center no-sort">Couleur</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for project in loop01.projects %}
|
||||
{% if app.session.get('activeproject')==project.active and (app.session.get('idproject')=="all" or app.session.get('idproject')==project.id) %}
|
||||
{% for task in project.tasks %}
|
||||
{% if app.session.get('activetask')==task.active %}
|
||||
{% set totvalidate=task.validate %}
|
||||
{% set totplanified=task.validate %}
|
||||
{% for event in task.events %}
|
||||
{% set totplanified=totplanified+event.duration %}
|
||||
{% if event.validate %}
|
||||
{% set totvalidate=totvalidate+event.duration %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% for penalty in task.penaltys %}
|
||||
{% set totplanified=totplanified+penalty.duration %}
|
||||
{% if penalty.validate %}
|
||||
{% set totvalidate=totvalidate+penalty.duration %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_task_update",{id:task.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td>{{task.project.customer.name}}</td>
|
||||
<td>{{task.nature.name}}</td>
|
||||
<td>{{task.project.name}}</td>
|
||||
<td>{{task.name}}</td>
|
||||
<td>{{task.active ? "actif":"non-actif"}}</td>
|
||||
<td class="text-right">{{task.quantity|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{(totvalidate*-1)|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{((totplanified-totvalidate)*-1)|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-right">{{(task.quantity-totplanified)|number_format(2, '.', ' ')}}</td>
|
||||
<td class="text-center" style="background-color:{{task.color}}; color:#ffffff">{{task.color}}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
{% if not fgprint is defined or not fgprint %}
|
||||
$('.table ').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 %}
|
||||
});
|
||||
|
||||
$('#switchactive').change(function() {
|
||||
window.location="{{ path('app_task_activeproject' )}}";
|
||||
});
|
||||
|
||||
$('#switchactivetask').change(function() {
|
||||
window.location="{{ path('app_task_activetask' )}}";
|
||||
});
|
||||
|
||||
$('#switchservice').change(function() {
|
||||
window.location="{{ path('app_task_viewservice' )}}";
|
||||
});
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
{% endblock %}
|
112
templates/Timer/edit.html.twig
Normal file
112
templates/Timer/edit.html.twig
Normal file
@@ -0,0 +1,112 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
td {
|
||||
padding:5px !important;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if mode=="update" %}
|
||||
Modification TIMER
|
||||
{% elseif mode=="submit" %}
|
||||
Création TIMER
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
<a class="btn btn-secondary" href={{ path('app_timer') }}>Annuler</a>
|
||||
|
||||
{% if mode=="update" %}
|
||||
|
||||
<a href="{{ path('app_timer_delete',{'id':timer.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.task) }}
|
||||
{{ form_row(form.description) }}
|
||||
{{ form_row(form.activepenalty) }}
|
||||
{{ form_row(form.additionalhour) }}
|
||||
{{ form_row(form.start) }}
|
||||
{{ form_row(form.end) }}
|
||||
{{ form_row(form.duration) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$("#timer_task").addClass("select2entity");
|
||||
/*
|
||||
* Pads this string with another string on the left until the resulting string
|
||||
* has specified length. If the padding string has more than one character, the
|
||||
* resulting string may be longer than desired (the padding string is not
|
||||
* truncated and it is only prepended as a whole). Bad API, I know, but it's
|
||||
* good enough for me.
|
||||
*/
|
||||
String.prototype.pad = function(length, padding) {
|
||||
var result = this;
|
||||
while (result.length < length) {
|
||||
result = padding + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* Some time constants. */
|
||||
var MILISECONDS_IN_SECOND = 1000;
|
||||
var MILISECONDS_IN_MINUTE = 60 * MILISECONDS_IN_SECOND;
|
||||
var MINUTES_IN_HOUR = 60;
|
||||
|
||||
/* Formats the time in the H:MM format. */
|
||||
function formatTime(time) {
|
||||
var timeInMinutes = time / MILISECONDS_IN_MINUTE;
|
||||
var hours = Math.floor(timeInMinutes / MINUTES_IN_HOUR);
|
||||
var minutes = Math.floor(timeInMinutes - hours * MINUTES_IN_HOUR);
|
||||
return String(hours).pad(2, "0") + ":" + String(minutes).pad(2, "0");
|
||||
}
|
||||
|
||||
$("#timer_start_time,#timer_end_time").on('input',function(){
|
||||
console.log($("#timer_start_date").val() +"T"+$("#timer_start_time").val()+":00Z")
|
||||
console.log($("#timer_end_date").val()+"T"+$("#timer_end_time").val()+":00Z")
|
||||
var start = Date.parse($("#timer_start_date").val() +"T"+$("#timer_start_time").val()+":00Z");
|
||||
var end = Date.parse($("#timer_end_date").val()+"T"+$("#timer_end_time").val()+":00Z");
|
||||
var diff = end - start;
|
||||
$("#timer_duration").val(formatTime(diff))
|
||||
})
|
||||
|
||||
{% endblock %}
|
||||
|
186
templates/Timer/list.cal.html.twig
Normal file
186
templates/Timer/list.cal.html.twig
Normal file
@@ -0,0 +1,186 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block head_style %}
|
||||
{{ encore_entry_link_tags('app') }}
|
||||
{{ encore_entry_link_tags('fullcalendar') }}
|
||||
{% endblock head_style %}
|
||||
|
||||
{% block localstyle %}
|
||||
.fc-header-toolbar h2 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.fc-day-grid-event {
|
||||
padding:0px;
|
||||
border-radius:0px;
|
||||
border: none;
|
||||
}
|
||||
.fc-content {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.fc-title {
|
||||
font-weight: bolder;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.eventAvatar {
|
||||
width: 20px;
|
||||
margin: 0px 5px 0px 0px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.eventInfo{
|
||||
margin: -5px 5px 0px 0px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.eventUser{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.eventEstimate {
|
||||
margin: -3px 10px;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="fullcalendar" style="width:100%; margin-top:10px;"></div>
|
||||
|
||||
|
||||
{{ encore_entry_script_tags('fullcalendar') }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
{% block localjavascript %}
|
||||
|
||||
$(document).ready(function() {
|
||||
$("#modalsubmit #user").select2({
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
|
||||
$("#modalsubmit #task").select2({
|
||||
placeholder: "Selectionnez un projet",
|
||||
allowClear: true,
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
|
||||
$("#modalupdate #user").select2({
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
|
||||
$("#modalupdate #task").select2({
|
||||
placeholder: "Selectionnez un projet",
|
||||
theme: 'bootstrap4',
|
||||
language: "fr"
|
||||
});
|
||||
});
|
||||
|
||||
// Rendu d'un évenement
|
||||
function eventRender(info) {
|
||||
console.log(info.event.extendedProps);
|
||||
// Récupération des divers élements du rendu event
|
||||
var content=$(info.el).children('.fc-content');
|
||||
var title=$(content).children('.fc-title');
|
||||
|
||||
// Ajouter l'avatar
|
||||
content.prepend("<img src="+info.event.extendedProps.avatar+" class='eventAvatar'>");
|
||||
content.append("<span class='eventUser float-left small'>"+info.event.extendedProps.username+"</span>");
|
||||
var eventInfo=$(content).children('.eventUser');
|
||||
|
||||
// Ajout container
|
||||
content.append("<span class='eventInfo float-right'></span>");
|
||||
var eventInfo=$(content).children('.eventInfo');
|
||||
|
||||
// Ajouter le verrou si event non editable
|
||||
if(info.event.extendedProps.locked) {
|
||||
eventInfo.append("<i class='fa fa-lock float-right'></i>");
|
||||
}
|
||||
|
||||
// Ajout estimation
|
||||
eventInfo.append("<span class='eventEstimate float-right small'>"+info.event.extendedProps.estimate+"</span>");
|
||||
|
||||
// Description
|
||||
content.attr("title",info.event.extendedProps.fulldescription);
|
||||
}
|
||||
|
||||
// Formulaire Création d'un évelement
|
||||
var allDay;
|
||||
function eventSelect(selectionInfo) {
|
||||
var start=moment(selectionInfo.start);
|
||||
var end=moment(selectionInfo.end);
|
||||
var end=end.subtract(1, 'd');
|
||||
allDay=(start.format("DD/MM/YYYY") != end.format("DD/MM/YYYY"));
|
||||
|
||||
// Controle
|
||||
if(start.month()!=end.month()) {
|
||||
alert("Une tâche ne peut être sur deux mois différents");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(start.week()!=end.week()) {
|
||||
alert("Une tâche ne peut être sur deux semaines différentes");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Valeur par défaut
|
||||
{% if (is_granted('ROLE_ADMIN') or is_granted('ROLE_VALIDATOR') or is_granted('ROLE_MASTER')) and app.session.get('iduser')!="all" %}
|
||||
$('#usersubmit').val({{app.session.get('iduser')}}).trigger("change");
|
||||
{% else %}
|
||||
$('#usersubmit').val({{app.user.id}}).trigger("change");
|
||||
{% endif %}
|
||||
|
||||
// Si jour de fin un samedi ou un dimanche : on est forcement en astreinte
|
||||
if(moment(end).day()==0||moment(end).day()==6) {
|
||||
$("#modalsubmit #astreinte").prop("checked",true);
|
||||
$("#modalsubmit #astreinte").attr("disabled",true);
|
||||
allDay=true;
|
||||
}
|
||||
else {
|
||||
$("#modalsubmit #astreinte").prop('checked', false);
|
||||
$("#modalsubmit #astreinte").attr('disabled', false);
|
||||
}
|
||||
|
||||
$('#modalsubmit #amsubmit').prop("checked",true);
|
||||
$('#modalsubmit #apsubmit').prop("checked",true);
|
||||
$('#modalsubmit #amsubmit').attr("disabled",allDay);
|
||||
$('#modalsubmit #apsubmit').attr("disabled",allDay);
|
||||
|
||||
$('#modalsubmit #start').val(start.format("YYYY-MM-DD"));
|
||||
$('#modalsubmit #end').val(end.format("YYYY-MM-DD"));
|
||||
|
||||
$('#modalsubmit #description').val("");
|
||||
|
||||
$("#modalsubmit .alert").remove();
|
||||
|
||||
// Formulaire de création d'un évènement
|
||||
$('#modalsubmit').modal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// On change astreinte
|
||||
$("#astreinte").change(function() {
|
||||
console.log(allDay)
|
||||
if(this.checked) {
|
||||
$("#amsubmit").prop("disabled",true);
|
||||
$("#apsubmit").prop("disabled",true);
|
||||
|
||||
$('#modalsubmit #amsubmit').prop("checked",true);
|
||||
$('#modalsubmit #apsubmit').prop("checked",true);
|
||||
}
|
||||
else {
|
||||
$("#amsubmit").prop("disabled",allDay);
|
||||
$("#apsubmit").prop("disabled",allDay);
|
||||
|
||||
$('#modalsubmit #amsubmit').prop("checked",true);
|
||||
$('#modalsubmit #apsubmit').prop("checked",true);
|
||||
}
|
||||
});
|
||||
|
||||
{% endblock %}
|
722
templates/Timer/list.html.twig
Normal file
722
templates/Timer/list.html.twig
Normal file
@@ -0,0 +1,722 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
#timer-task {
|
||||
width:300px;
|
||||
}
|
||||
#timer-desc {
|
||||
width:300px;
|
||||
}
|
||||
.select2-results__group {
|
||||
font-size:12px !important;
|
||||
}
|
||||
.select2-results__option{
|
||||
font-size: 14px;
|
||||
padding-left:15px
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
SUIVI HORAIRE
|
||||
</h1>
|
||||
<div id="timer" class="card">
|
||||
|
||||
<div class="card-header">
|
||||
|
||||
<a class="btn btn-success" style="float:right" href={{ path('app_timer_submit') }}>Créer un Timer</a>
|
||||
{% if user %}
|
||||
Lancer un Timer :
|
||||
<select class="select2entity" id="timer-task" name="timer-task">
|
||||
<option></option>
|
||||
{% for project in projects|sort((a, b) => a.displayname <=> b.displayname) %}
|
||||
<optgroup label="{{project.displayname}}">
|
||||
{% for task in project.tasks|sort((a, b) => a.displayname <=> b.displayname) %}
|
||||
<option value="{{task.id}}">{{task.displayname}}</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endfor %}
|
||||
|
||||
</select>
|
||||
<input id="timer-desc" name="timer-desc" placeholder="Description" />
|
||||
<a href='#' title='Add' id='addtimer'>
|
||||
<i class='fas fa-plus-circle'></i>
|
||||
</a>
|
||||
{% else %}
|
||||
Veuillez choisir un Intervenant pour lancer un Timer.
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<table id="task-table" class="table table-striped table-hover" >
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<a class="btn btn-success" href={{ path('app_timer_view') }}>Voir le calendrier</a>
|
||||
<p></p>
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="70px" class="no-sort">Tâche</th>
|
||||
<th width="150px" class="no-sort">Description</th>
|
||||
<th width="150px">Début</th>
|
||||
<th width="100px">Fin</th>
|
||||
<th width="100px">Durée</th>
|
||||
<th width="100px" class="text-center no-string">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for timer in timers %}
|
||||
<tr>
|
||||
<td>{{ timer.task.displayname }}</td>
|
||||
<td>
|
||||
<span class="font-weight-bold">
|
||||
|
||||
{{ timer.activepenalty ? "<i class='fa fa-exclamation' style='color:red;opacity: 0.33;'></i> Astreinte active" : "" }}
|
||||
</span>
|
||||
<span class="font-weight-bold">
|
||||
{{ timer.additionalhour ? "<i class='fa fa-exclamation-triangle' style='color:red;opacity: 0.33;'></i> Heures supplémentaires" : "" }}
|
||||
</span>
|
||||
<p>{{ timer.description }}</p>
|
||||
</td>
|
||||
<td>{{ timer.start|date("d/m/Y H:i") }}</td>
|
||||
<td>{{ timer.end|date("d/m/Y H:i") }}</td>
|
||||
<td>{{ timer.duration|date("H:i") }}</td>
|
||||
<td>
|
||||
<a href="{{path("app_timer_update",{id:timer.id})}}">
|
||||
<i class="fa fa-file"></i>
|
||||
</a>
|
||||
|
||||
<a href="{{ path('app_timer_delete',{'id':timer.id}) }}"
|
||||
data-method="delete"
|
||||
data-confirm="Êtes-vous sûr de vouloir supprimer cet entregistrement ?">
|
||||
<i class="fa fa-trash-alt"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
|
||||
|
||||
/* Creates a new Task object. */
|
||||
function Task(id ,name, description) {
|
||||
this._name = name;
|
||||
this._taskid = id;
|
||||
this._description = description;
|
||||
this._state = Task.State.STOPPED;
|
||||
this._timeSpentInPreviousIterations = 0;
|
||||
this._startDate = 0;
|
||||
this._endDate = 0;
|
||||
this._currentIterationStartTime = 0;
|
||||
this._customTimeSpent = 0;
|
||||
this._onChange = null;
|
||||
}
|
||||
|
||||
/* Possible task states. */
|
||||
Task.State = {
|
||||
STOPPED: "stopped",
|
||||
RUNNING: "running"
|
||||
}
|
||||
|
||||
Task.prototype = {
|
||||
/* Returns the task name. */
|
||||
getName: function() {
|
||||
return this._name;
|
||||
},
|
||||
|
||||
/* Returns the task description. */
|
||||
getDescription: function() {
|
||||
if (this._description == "NaN") {
|
||||
this._description = ""
|
||||
}
|
||||
return this._description;
|
||||
},
|
||||
|
||||
/* Returns the task state. */
|
||||
getState: function() {
|
||||
return this._state;
|
||||
},
|
||||
|
||||
/* Is the task stopped? */
|
||||
isStopped: function() {
|
||||
return this._state == Task.State.STOPPED;
|
||||
},
|
||||
|
||||
/* Is the task running? */
|
||||
isRunning: function() {
|
||||
return this._state == Task.State.RUNNING;
|
||||
},
|
||||
|
||||
/*
|
||||
* Sets the "onChange" event handler. The "onChange" event is fired when the
|
||||
* task is started, stopped, or reset.
|
||||
*/
|
||||
setOnChange: function(onChange) {
|
||||
this._onChange = onChange;
|
||||
},
|
||||
|
||||
/*
|
||||
* Returns the time spent on the task in the current work iteration. Works
|
||||
* correctly only when the task is running.
|
||||
*/
|
||||
_getCurrentIterationTime: function() {
|
||||
return (new Date).getTime() - this._currentIterationStartTime;
|
||||
},
|
||||
|
||||
/*
|
||||
* Returns the total time spent on the task. This includes time spent in
|
||||
* the current work iteration if the task is running.
|
||||
*/
|
||||
getTimeSpent: function() {
|
||||
var result = this._timeSpentInPreviousIterations;
|
||||
if (this._state == Task.State.RUNNING) {
|
||||
result += this._getCurrentIterationTime();
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/* Calls the "onChange" event handler if set. */
|
||||
_callOnChange: function() {
|
||||
if (typeof this._onChange == "function") {
|
||||
this._onChange();
|
||||
}
|
||||
},
|
||||
|
||||
/* Starts a new task work iteration. */
|
||||
start: function() {
|
||||
if (this._state == Task.State.RUNNING) { return };
|
||||
if (this._startDate == 0) {this._startDate = new Date()}
|
||||
this._state = Task.State.RUNNING;
|
||||
this._currentIterationStartTime = (new Date).getTime();
|
||||
this._callOnChange();
|
||||
},
|
||||
|
||||
/* Stops the current task work iteration. */
|
||||
stop: function() {
|
||||
if (this._state == Task.State.STOPPED) { return };
|
||||
|
||||
this._state = Task.State.STOPPED;
|
||||
this._timeSpentInPreviousIterations += this._getCurrentIterationTime();
|
||||
this._currentIterationStartTime = 0;
|
||||
this._endDate = new Date();
|
||||
this._callOnChange();
|
||||
},
|
||||
|
||||
/* Stops the current task work iteration and resets the time data. */
|
||||
reset: function() {
|
||||
this.stop();
|
||||
this._timeSpentInPreviousIterations = 0;
|
||||
this._callOnChange();
|
||||
},
|
||||
save: function(task){
|
||||
console.log(task)
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
taskname: task._name,
|
||||
taskid: task._taskid,
|
||||
description: task._description,
|
||||
start: task._startDate,
|
||||
end: task._endDate,
|
||||
duration: task._timeSpentInPreviousIterations,
|
||||
},
|
||||
url: "{{ path('app_timer_create') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
$("#dataTable_wrapper").append("<div class='alert alert-danger' style='margin: 5px 0px'>"+response.error+"</div>");
|
||||
}else{
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/* Serializes the task into a string. */
|
||||
serialize: function() {
|
||||
/*
|
||||
* Originally, I wanted to use "toSource" and "eval" for serialization and
|
||||
* deserialization, but "toSource" is not supported by WebKit, so I resorted
|
||||
* to ugly hackery...
|
||||
*/
|
||||
return [
|
||||
encodeURIComponent(this._name),
|
||||
this._state,
|
||||
this._timeSpentInPreviousIterations,
|
||||
this._currentIterationStartTime,
|
||||
this._startDate,
|
||||
this._endDate,
|
||||
this._taskid,
|
||||
this._description,
|
||||
].join("&");
|
||||
},
|
||||
|
||||
/* Deserializes the task from a string. */
|
||||
deserialize: function(serialized) {
|
||||
var parts = serialized.split("&");
|
||||
this._name = decodeURIComponent(parts[0]);
|
||||
this._state = parts[1];
|
||||
this._timeSpentInPreviousIterations = parseInt(parts[2]);
|
||||
this._currentIterationStartTime = parseInt(parts[3]);
|
||||
this._startDate = parseInt(parts[4]);
|
||||
this._endDate = parseInt(parts[5]);
|
||||
this._taskid = parseInt(parts[6]);
|
||||
this._description = parseInt(parts[7]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Tasks ===== */
|
||||
|
||||
/* The Tasks class represents a list of tasks. */
|
||||
|
||||
/* Creates a new Tasks object. */
|
||||
function Tasks() {
|
||||
this._tasks = [];
|
||||
|
||||
this._onAdd = null;
|
||||
this._onRemove = null;
|
||||
}
|
||||
|
||||
Tasks.prototype = {
|
||||
/*
|
||||
* Sets the "onAdd" event handler. The "onAdd" event is fired when a task
|
||||
* is added to the list.
|
||||
*/
|
||||
setOnAdd: function(onAdd) {
|
||||
this._onAdd = onAdd;
|
||||
},
|
||||
|
||||
/*
|
||||
* Sets the "onRemove" event handler. The "onRemove" event is fired when a
|
||||
* task is removed from the list.
|
||||
*/
|
||||
setOnRemove: function(onRemove) {
|
||||
this._onRemove = onRemove;
|
||||
},
|
||||
|
||||
/* Returns the length of the task list. */
|
||||
length: function() {
|
||||
return this._tasks.length
|
||||
},
|
||||
|
||||
/*
|
||||
* Returns index-th task in the list, or "undefined" if the index is out of
|
||||
* bounds.
|
||||
*/
|
||||
get: function(index) {
|
||||
return this._tasks[index];
|
||||
},
|
||||
|
||||
/*
|
||||
* Calls the callback function for each task in the list. The function is
|
||||
* called with three parameters - the task, its index and the task list
|
||||
* object. This is modeled after "Array.forEach" in JavaScript 1.6.
|
||||
*/
|
||||
forEach: function(callback) {
|
||||
for (var i = 0; i < this._tasks.length; i++) {
|
||||
callback(this._tasks[i], i, this);
|
||||
}
|
||||
},
|
||||
|
||||
/* Calls the "onAdd" event handler if set. */
|
||||
_callOnAdd: function(task) {
|
||||
if (typeof this._onAdd == "function") {
|
||||
this._onAdd(task);
|
||||
}
|
||||
},
|
||||
|
||||
/* Adds a new task to the end of the list. */
|
||||
add: function(task) {
|
||||
this._tasks.push(task);
|
||||
this._callOnAdd(task);
|
||||
},
|
||||
|
||||
/* Calls the "onRemove" event handler if set. */
|
||||
_callOnRemove: function(index) {
|
||||
if (typeof this._onRemove == "function") {
|
||||
this._onRemove(index);
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Removes index-th task from the list. Does not do anything if the index
|
||||
* is out of bounds.
|
||||
*/
|
||||
remove: function(index) {
|
||||
this._callOnRemove(index);
|
||||
this._tasks.splice(index, 1);
|
||||
},
|
||||
|
||||
|
||||
|
||||
/* Serializes the list of tasks into a string. */
|
||||
serialize: function() {
|
||||
var serializedTasks = [];
|
||||
this.forEach(function(task) {
|
||||
serializedTasks.push(task.serialize());
|
||||
});
|
||||
return serializedTasks.join("|");
|
||||
},
|
||||
|
||||
/* Deserializes the list of tasks from a string. */
|
||||
deserialize: function(serialized) {
|
||||
/*
|
||||
* Repeatedly use "remove" so the "onRemove" event is triggered. Do the same
|
||||
* with the "add" method below.
|
||||
*/
|
||||
while (this._tasks.length > 0) {
|
||||
this.remove(0);
|
||||
}
|
||||
|
||||
var serializedTasks = serialized.split("|");
|
||||
for (var i = 0; i < serializedTasks.length; i++) {
|
||||
var task = new Task(0 ,"", "");
|
||||
task.deserialize(serializedTasks[i]);
|
||||
this.add(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Extensions ===== */
|
||||
|
||||
/*
|
||||
* Pads this string with another string on the left until the resulting string
|
||||
* has specified length. If the padding string has more than one character, the
|
||||
* resulting string may be longer than desired (the padding string is not
|
||||
* truncated and it is only prepended as a whole). Bad API, I know, but it's
|
||||
* good enough for me.
|
||||
*/
|
||||
String.prototype.pad = function(length, padding) {
|
||||
var result = this;
|
||||
while (result.length < length) {
|
||||
result = padding + result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ===== Task List + DOM Storage ===== */
|
||||
|
||||
/* The list of tasks. */
|
||||
var tasks = new Tasks();
|
||||
|
||||
/* The last value of the serialized task list string. */
|
||||
var lastSerializedTasksString;
|
||||
|
||||
/*
|
||||
* The key under which the serialized task list string is stored in the DOM
|
||||
* Storage.
|
||||
*/
|
||||
var TASKS_DOM_STORAGE_KEY = "timerTasks";
|
||||
|
||||
/*
|
||||
* Returns DOM Storage used by the application, or "null" if the browser does
|
||||
* not support DOM Storage.
|
||||
*/
|
||||
function getStorage() {
|
||||
/*
|
||||
* HTML 5 says that the persistent storage is available in the
|
||||
* "window.localStorage" attribute, however Firefox implements older version
|
||||
* of the proposal, which uses "window.globalStorage" indexed by the domain
|
||||
* name. We deal with this situation here as gracefully as possible (i.e.
|
||||
* without concrete browser detection and with forward compatibility).
|
||||
*
|
||||
* For more information, see:
|
||||
*
|
||||
* http://www.whatwg.org/specs/web-apps/current-work/#storage
|
||||
* https://developer.mozilla.org/En/DOM/Storage
|
||||
*/
|
||||
if (window.localStorage !== undefined) {
|
||||
return window.localStorage;
|
||||
} else if (window.globalStorage !== undefined) {
|
||||
return window.globalStorage[location.hostname];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Saves the task list into a DOM Storage. Also updates the value of the
|
||||
* "lastSerializedTasksString" variable.
|
||||
*/
|
||||
function saveTasks() {
|
||||
var serializedTasksString = tasks.serialize();
|
||||
getStorage()[TASKS_DOM_STORAGE_KEY] = serializedTasksString;
|
||||
lastSerializedTasksString = serializedTasksString;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the serialized task list string from the DOM Storage. Returns
|
||||
* "undefined" if the storage does not contain the string (this happens when
|
||||
* running the application for the first time).
|
||||
*/
|
||||
function loadSerializedTasksString() {
|
||||
var storedValue = getStorage()[TASKS_DOM_STORAGE_KEY];
|
||||
/*
|
||||
* The spec says "null" should be returned when the key is not found, but some
|
||||
* browsers return "undefined" instead. Maybe it was in some earlier version
|
||||
* of the spec (I didn't bother to check).
|
||||
*/
|
||||
if (storedValue !== null && storedValue !== undefined && storedValue.length > 0) {
|
||||
/*
|
||||
* The values retrieved from "globalStorage" use one more level of
|
||||
* indirection.
|
||||
*/
|
||||
return (window.localStorage === undefined) ? storedValue.value : storedValue;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads the task list from the DOM Storage. Also updates the value of the
|
||||
* "lastSerializedTasksString" variable.
|
||||
*/
|
||||
function loadTasks() {
|
||||
var serializedTasksString = loadSerializedTasksString();
|
||||
if (serializedTasksString !== undefined) {
|
||||
tasks.deserialize(serializedTasksString);
|
||||
lastSerializedTasksString = serializedTasksString;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Was the task list changed outside of the application? Detects the change
|
||||
* by comparing the current serialized task list string in the DOM Storage
|
||||
* with a kept old value.
|
||||
*/
|
||||
function tasksHaveChangedOutsideApplication() {
|
||||
var serializedTasksString = loadSerializedTasksString();
|
||||
if (serializedTasksString != lastSerializedTasksString) {
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ===== View ===== */
|
||||
|
||||
/* Some time constants. */
|
||||
var MILISECONDS_IN_SECOND = 1000;
|
||||
var MILISECONDS_IN_MINUTE = 60 * MILISECONDS_IN_SECOND;
|
||||
var MINUTES_IN_HOUR = 60;
|
||||
|
||||
/* Formats the time in the H:MM format. */
|
||||
function formatTime(time) {
|
||||
var timeInMinutes = time / MILISECONDS_IN_MINUTE;
|
||||
var hours = Math.floor(timeInMinutes / MINUTES_IN_HOUR);
|
||||
var minutes = Math.floor(timeInMinutes - hours * MINUTES_IN_HOUR);
|
||||
return hours + ":" + String(minutes).pad(2, "0");
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes the URL of the image in the start/stop link according to the task
|
||||
* state.
|
||||
*/
|
||||
function computeStartStopLinkImageUrl(state) {
|
||||
switch (state) {
|
||||
case Task.State.STOPPED:
|
||||
return "fa-play";
|
||||
case Task.State.RUNNING:
|
||||
return "fa-stop";
|
||||
default:
|
||||
throw "Invalid task state."
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds the HTML element of the row in the task table corresponding to the
|
||||
* specified task and index.
|
||||
*/
|
||||
function buildTaskRow(task, index) {
|
||||
var result = $("<tr />");
|
||||
|
||||
var startStopLink = $(
|
||||
"<a href='#' class='start-stop-link' title='Start/stop'>"
|
||||
+ "<i class='fa " + computeStartStopLinkImageUrl(task.getState()) + "'></i>"
|
||||
|
||||
);
|
||||
startStopLink.click(function() {
|
||||
switch (task.getState()) {
|
||||
case Task.State.STOPPED:
|
||||
task.start();
|
||||
break;
|
||||
case Task.State.RUNNING:
|
||||
task.stop();
|
||||
break;
|
||||
default:
|
||||
throw "Invalid task state."
|
||||
}
|
||||
saveTasks();
|
||||
return false;
|
||||
});
|
||||
|
||||
var resetLink = $(
|
||||
"<a href='#' title='Reset'>"
|
||||
+ "<i class='fa fa-undo'></i>"
|
||||
);
|
||||
resetLink.click(function() {
|
||||
task.reset();
|
||||
saveTasks();
|
||||
return false;
|
||||
});
|
||||
|
||||
var deleteLink = $(
|
||||
"<a href='#' title='Delete' class='deletetask'>"
|
||||
+ "<i class='fa fa-trash-alt' class='deletetask'></i>"
|
||||
|
||||
);
|
||||
deleteLink.click(function() {
|
||||
if (confirm("Do you really want to delete task \"" + task.getName() + "\"?")) {
|
||||
tasks.remove(index);
|
||||
saveTasks();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
var saveLink = $(
|
||||
"<a href='#' title='Save' class='savetask'>"
|
||||
+ "<i class='fa fa-download' class='savetask'></i>"
|
||||
);
|
||||
saveLink.click(function() {
|
||||
tasks.remove(index);
|
||||
saveTasks();
|
||||
task.save(task);
|
||||
return false;
|
||||
});
|
||||
result
|
||||
.addClass("state-" + task.getState())
|
||||
.append($("<td class='task-name' />").text(task.getName()))
|
||||
.append($("<td class='task-description' />").text(task.getDescription()))
|
||||
.append($("<td class='task-time' />").text(formatTime(task.getTimeSpent())))
|
||||
.append($("<td class='task-actions' />")
|
||||
.append(startStopLink)
|
||||
.append(" ")
|
||||
.append(resetLink)
|
||||
.append(" ")
|
||||
.append(saveLink)
|
||||
.append(" ")
|
||||
.append(deleteLink)
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Finds row with the specified index in the task table. */
|
||||
function findRowWithIndex(index) {
|
||||
return $("#task-table").find("tr").slice(1).eq(index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates the row in the task table corresponding to a task according to
|
||||
* its state.
|
||||
*/
|
||||
function updateTaskRow(row, task) {
|
||||
if (task.isStopped()) {
|
||||
row.removeClass("state-running");
|
||||
row.addClass("state-stopped");
|
||||
} else if (task.isRunning()) {
|
||||
row.removeClass("state-stopped");
|
||||
row.addClass("state-running");
|
||||
}
|
||||
|
||||
row.find(".task-time").text(formatTime(task.getTimeSpent()))
|
||||
|
||||
row.find(".start-stop-link i").removeClass();
|
||||
row.find(".start-stop-link i").addClass("fa "+computeStartStopLinkImageUrl(task.getState()));
|
||||
}
|
||||
|
||||
/* ===== Initialization ===== */
|
||||
|
||||
/* Initializes event handlers on the task list. */
|
||||
function initializeTasksEventHandlers() {
|
||||
tasks.setOnAdd(function(task) {
|
||||
var row = buildTaskRow(task, tasks.length() - 1);
|
||||
$("#task-table").append(row);
|
||||
task.setOnChange(function() {
|
||||
updateTaskRow(row, task);
|
||||
});
|
||||
});
|
||||
|
||||
tasks.setOnRemove(function(index) {
|
||||
findRowWithIndex(index).remove();
|
||||
if (tasks.length() == 1 ) {
|
||||
$( "#task-table" ).css({"display":"none"});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Initializes GUI event handlers. */
|
||||
function initializeGuiEventHandlers() {
|
||||
$( "#addtimer" ).click(function() {
|
||||
displayTaskAdd();
|
||||
});
|
||||
|
||||
$( "#timer-desc" ).keypress(function( event ) {
|
||||
if ( event.which == 13 ) {
|
||||
event.preventDefault();
|
||||
displayTaskAdd();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
function displayTaskAdd() {
|
||||
$( "#task-table" ).css({"display":"inline"});
|
||||
var taskName = $("#timer-task option:selected").text();
|
||||
var taskId = $("#timer-task option:selected").val();
|
||||
var taskDesc = $("#timer-desc").val();
|
||||
|
||||
var task = new Task(taskId, taskName, taskDesc);
|
||||
tasks.add(task);
|
||||
saveTasks();
|
||||
$("#timer-desc").val("");
|
||||
}
|
||||
/*
|
||||
* Initializes a timer used to update task times and detect changes in the
|
||||
* data stored in the DOM Storage.
|
||||
*/
|
||||
function initializeTimer() {
|
||||
setInterval(function() {
|
||||
tasks.forEach(function(task, index) {
|
||||
updateTaskRow(findRowWithIndex(index), task);
|
||||
});
|
||||
|
||||
if (tasksHaveChangedOutsideApplication()) {
|
||||
loadTasks();
|
||||
}
|
||||
}, 10 * MILISECONDS_IN_SECOND);
|
||||
}
|
||||
|
||||
/* Initializes the application. */
|
||||
$(document).ready(function(){
|
||||
try {
|
||||
if (!getStorage()) {
|
||||
alert("Timer requires a browser with DOM Storage support, such as Firefox 3+ or Safari 4+.");
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
alert("Timer does not work with file: URLs in Firefox.");
|
||||
return;
|
||||
}
|
||||
|
||||
initializeTasksEventHandlers();
|
||||
loadTasks();
|
||||
initializeGuiEventHandlers();
|
||||
initializeTimer();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
171
templates/User/edit.html.twig
Executable file
171
templates/User/edit.html.twig
Executable file
@@ -0,0 +1,171 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block body %}
|
||||
{{ form_start(form) }}
|
||||
<h1 class="page-header">
|
||||
{% if fgprint is defined and fgprint %}
|
||||
UTILISATEUR
|
||||
{% elseif mode=="update" %}
|
||||
Modification UTILISATEUR
|
||||
{% elseif mode=="submit" %}
|
||||
Création UTILISATEUR
|
||||
{% elseif mode=="profil" %}
|
||||
Profil UTILISATEUR
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
{{ form_widget(form.submit) }}
|
||||
|
||||
{% if mode=="profil" %}
|
||||
<a class="btn btn-secondary" href={{ path('app_home') }}>Annuler</a>
|
||||
{% else %}
|
||||
<a class="btn btn-secondary" href={{ path('app_user') }}>Annuler</a>
|
||||
{% endif %}
|
||||
|
||||
{% if mode=="update" %}
|
||||
<a href="{{ path('app_user_delete',{'id':user.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="no-print" style="width:90px; margin:auto;">
|
||||
{% set avatar= "noavatar.png" %}
|
||||
{% if user.avatar %}
|
||||
{% set avatar= user.avatar %}
|
||||
{% endif %}
|
||||
<img id="user_avatar_img" src="/{{ appAlias }}/uploads/avatar/{{ avatar }}" class="avatar big" >
|
||||
{{ form_widget(form.avatar) }}
|
||||
<a class="btn btn-info" style="width:100%; margin-bottom:15px;" onClick="showModal();" title='Ajouter un avatar'>Modifier</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<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.username) }}
|
||||
{% if form.password is defined %}
|
||||
{{ form_row(form.password) }}
|
||||
{%endif%}
|
||||
{{ form_row(form.lastname) }}
|
||||
{{ form_row(form.firstname) }}
|
||||
{{ form_row(form.email) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-pencil-alt fa-fw"></i> Organisation
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
{{ form_row(form.service) }}
|
||||
{{ form_row(form.jobs) }}
|
||||
|
||||
{% if form.roles is defined %}
|
||||
{{ form_row(form.roles) }}
|
||||
{%endif%}
|
||||
</div>
|
||||
</div>
|
||||
<p></p>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fas fa-list-ul"></i> Affectations
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Projet</th>
|
||||
<th>Rôle</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for userproject in user.userprojects %}
|
||||
<tr>
|
||||
<td>{{userproject.project.displayname}}</td>
|
||||
<td>{{userproject.job.name}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
|
||||
<div id="extraLargeModal" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"></h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<iframe id="frameModal" frameborder=0 width="100%" height="700px"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
$("#user_password_first").val("");
|
||||
$("#user_login").focus();
|
||||
});
|
||||
|
||||
$("#user_avatar_img").on('load', function() {
|
||||
|
||||
})
|
||||
$("#user_avatar_img").on('error', function(){
|
||||
console.log("la");
|
||||
var imgSrc = $(this).attr('src');
|
||||
if(imgSrc!="/{{appAlias}}/uploads/avatar/")
|
||||
$(this).attr('src',imgSrc);
|
||||
});
|
||||
|
||||
function showModal() {
|
||||
$("#frameModal").attr("src","{{path("app_crop01")}}");
|
||||
$("#extraLargeModal").modal("show");
|
||||
}
|
||||
|
||||
function myprint() {
|
||||
href=document.location.href;
|
||||
document.location.href=href+"?fgprint=true";
|
||||
}
|
||||
|
||||
{% endblock %}
|
106
templates/User/list.html.twig
Normal file
106
templates/User/list.html.twig
Normal file
@@ -0,0 +1,106 @@
|
||||
{% 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">
|
||||
UTILISATEURS
|
||||
</h1>
|
||||
|
||||
<p><a class="btn btn-success" href={{ path('app_user_submit') }}>Ajouter</a></p>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<i class="fa fa-table fa-fw"></i> Liste des Utilisateurs
|
||||
</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 width="70px" class="no-sort no-print">Avatar</th>
|
||||
<th>Login</th>
|
||||
<th>Prénom</th>
|
||||
<th>Nom</th>
|
||||
<th>Rôles</th>
|
||||
<th>Activité</th>
|
||||
<th>Métiers</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td class="no-print">
|
||||
<a href="{{path("app_user_update",{id:user.id})}}"><i class="fa fa-file"></i></a>
|
||||
</td>
|
||||
<td class="no-print"><img id="user_avatar_img" src="/{{ appAlias }}/uploads/avatar/{{ user.avatar }}" class="avatar" ></td>
|
||||
<td>{{user.username}}</td>
|
||||
<td>{{user.firstname}}</td>
|
||||
<td>{{user.lastname}}</td>
|
||||
<td>
|
||||
{%for role in user.roles %}
|
||||
{%if role=="ROLE_ADMIN" %}
|
||||
Administrateur<br>
|
||||
{%elseif role=="ROLE_VALIDATOR" %}
|
||||
Valideur<br>
|
||||
{%elseif role=="ROLE_MASTER" %}
|
||||
Master<br>
|
||||
{%elseif role=="ROLE_USER" %}
|
||||
Intervenant<br>
|
||||
{%elseif role=="ROLE_VISITOR" %}
|
||||
Invité<br>
|
||||
{%endif%}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% if user.service %}
|
||||
{{ user.service.name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for job in user.jobs %}
|
||||
{{ job.type }} - {{ job.name }}<br>
|
||||
{% endfor %}
|
||||
</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: [[ 2, "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 %}
|
223
templates/Validation/validation.html.twig
Normal file
223
templates/Validation/validation.html.twig
Normal file
@@ -0,0 +1,223 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
.homecard {
|
||||
margin: 20px 20px 0px 0px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
table {
|
||||
|
||||
}
|
||||
|
||||
th,td {
|
||||
border: 1px solid #37474F;
|
||||
color: #ffffff;
|
||||
background-color:#37474F;
|
||||
text-align:center;
|
||||
width: 70px;
|
||||
}
|
||||
td {
|
||||
background-color:#e8ecf1;
|
||||
cursor: help;
|
||||
height: 44px;
|
||||
vertical-align: top;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 9px;
|
||||
color: #37474F;
|
||||
}
|
||||
|
||||
.allday {
|
||||
font-size: 12px;
|
||||
float:left;
|
||||
width:100%;
|
||||
height: 18px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.am, .ap {
|
||||
font-size: 12px;
|
||||
float:left;
|
||||
width:50%;
|
||||
height: 18px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.astreinte {
|
||||
font-size: 11px;
|
||||
float:left;
|
||||
width:100%;
|
||||
height:12px;
|
||||
}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
{% if fgprint is defined and fgprint %}<h1>Validation</h1>{%endif%}
|
||||
{% for user in users %}
|
||||
{% set nbday=1 %}
|
||||
|
||||
<div class="card homecard" style="width:380px;">
|
||||
<div class="card-header">
|
||||
<img src="\{{appAlias}}\uploads\avatar\{{user.user.avatar}}" class='avatar no-print'>
|
||||
{{ user.user.displayname }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table>
|
||||
<thead>
|
||||
<th class="no-print"></th>
|
||||
<th>S</th>
|
||||
<th>L</th>
|
||||
<th>M</th>
|
||||
<th>M</th>
|
||||
<th>J</th>
|
||||
<th>V</th>
|
||||
<th>S</th>
|
||||
<th>D</th>
|
||||
</thead>
|
||||
|
||||
{% set btnvalidate=false %}
|
||||
{% for event in user.events %}
|
||||
{% if nbday==1 %}
|
||||
<tr id="{{user.user.id}}-{{event.date|date("Ymd")}}"}">
|
||||
<td class="no-print" style="vertical-align:middle">
|
||||
{% set first=event.events|first %}
|
||||
{% if first and first.validate %}
|
||||
<i class="fa fa-thumbs-down devalidate-{{user.user.id}}" onClick="devalidate({{user.user.id}},'{{event.date|date("Ymd")}}','{{event.date|date("m/d/Y")}}')" style="cursor:pointer; color:red;"></i>
|
||||
{%else%}
|
||||
<i class="fa fa-thumbs-up validate-{{user.user.id}}" onClick="validate({{user.user.id}},'{{event.date|date("Ymd")}}','{{event.date|date("m/d/Y")}}')" style="cursor:pointer; color:green;{% if btnvalidate %}display:none{% endif %}"></i>
|
||||
{% set btnvalidate=true %}
|
||||
{%endif%}
|
||||
</td>
|
||||
<td class="date" style="vertical-align:middle">{{event.date|date("W")}}</td>
|
||||
{% endif %}
|
||||
|
||||
<td>
|
||||
<div class="date">{{ event.date | date("d/m") }}</div>
|
||||
<div class="d-flex flex-wrap">
|
||||
{% set haveam=false %}
|
||||
{% for detail in event.events %}
|
||||
{% if detail.allday %}
|
||||
<div class='allday' style='background-color:{{ detail.colorday }};' title='{{ detail.descriptionday }}'>1</div>
|
||||
{% else %}
|
||||
{%if detail.am %}
|
||||
{% set haveam=true %}
|
||||
<div class='am' style='background-color:{{ detail.coloram }};' title='{{ detail.descriptionam }}'>0.5</div>
|
||||
{% endif %}
|
||||
|
||||
{%if detail.ap %}
|
||||
{% if not haveam %}<div class='am'></div>{%endif%}
|
||||
<div class='ap' style='background-color:{{ detail.colorap }};' title='{{ detail.descriptionap }}'>0.5</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if event.astreinte %}
|
||||
<div class='astreinte' style='background-color:{{ event.colorastreinte }};' title='{{ event.descriptionastreinte }}'>*</div>
|
||||
{% else %}
|
||||
<div class='astreinte'></div>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
{% set nbday=nbday+1 %}
|
||||
{% if nbday==8 %}
|
||||
</tr>
|
||||
{% set nbday=1 %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% if (loop.index % 2) == 0 %} <div class="new-page"> </div> {% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
resizePanel();
|
||||
});
|
||||
|
||||
$( window ).resize(function() {
|
||||
resizePanel();
|
||||
});
|
||||
|
||||
function printPage(pdf,pdfName,options,lstPage,cpt) {
|
||||
pdf.addHTML($("#content h1"), 10, 10, options, function(){
|
||||
pdf.addHTML(lstPage[cpt], 0, 40, options, function(){
|
||||
cpt=cpt+1;
|
||||
if(cpt>=lstPage.length) {
|
||||
$("#page-wrapper").first("row").css("width","initial");
|
||||
}
|
||||
else {
|
||||
pdf.addPage();
|
||||
printPage(pdf,pdfName,options,lstPage,cpt);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function myprint() {
|
||||
document.location.href="{{path(app.request.attributes.get('_route'),{fgprint:true})}}";
|
||||
}
|
||||
|
||||
function resizePanel() {
|
||||
maxheight=0;
|
||||
$( ".homecard" ).each(function( index ) {
|
||||
if($(this).height()>maxheight)
|
||||
maxheight=$(this).height();
|
||||
});
|
||||
$( ".homecard" ).height(maxheight);
|
||||
}
|
||||
|
||||
|
||||
function validate(iduser,idday,day) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
iduser: iduser,
|
||||
day: day,
|
||||
},
|
||||
url: "{{ path('app_validation_validate') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
alert(response.error);
|
||||
}
|
||||
else {
|
||||
$(".devalidate-"+iduser).remove();
|
||||
html="<i class=\"fa fa-thumbs-down devalidate-"+iduser+"\" onClick=\"devalidate("+iduser+",'"+idday+"','"+day+"')\" style=\"cursor:pointer; color:red;\"></i>";
|
||||
$(".validate-"+iduser).first().replaceWith(html);
|
||||
$(".validate-"+iduser).first().show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function devalidate(iduser,idday,day) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
iduser: iduser,
|
||||
day: day,
|
||||
},
|
||||
url: "{{ path('app_validation_devalidate') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
alert(response.error);
|
||||
}
|
||||
else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
{% endblock %}
|
157
templates/Validation/validationholiday.html.twig
Normal file
157
templates/Validation/validationholiday.html.twig
Normal file
@@ -0,0 +1,157 @@
|
||||
{% 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; }
|
||||
.homecard {width: 100% }
|
||||
{%endif%}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
VALIDATION CONGES
|
||||
</h1>
|
||||
|
||||
<div class="custom-control custom-switch float-right">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactive" {% if app.session.get('activeholiday') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactive">Congès à Valider</label>
|
||||
</div>
|
||||
<div style="height:30px;">
|
||||
{% if not app.session.get('activeholiday') %}
|
||||
On ne peut dévalider des congés que si la semaine de travail n'a pas été validée
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card homecard">
|
||||
<div class="card-header">
|
||||
{% if not app.session.get('activeholiday') %}
|
||||
Congé à Dévalider
|
||||
{% else %}
|
||||
Congé à Valider
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<th class="no-print"></th>
|
||||
<th>Utilisateur</th>
|
||||
<th>Tâche</th>
|
||||
<th>Début</th>
|
||||
<th>Fin</th>
|
||||
<th>Durée</th>
|
||||
</thead>
|
||||
|
||||
{% for user in users %}
|
||||
{% for event in user.holidays %}
|
||||
<tr id="row-{{event.id}}">
|
||||
<td class="no-print" style="vertical-align:middle">
|
||||
{% if event.validateholiday %}
|
||||
<i class="fa fa-thumbs-down validate-{{user.user.id}}" onClick="devalidate({{event.id}})" style="cursor:pointer; color:red;"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-thumbs-up validate-{{user.user.id}}" onClick="validate({{event.id}})" style="cursor:pointer; color:green;"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ user.user.displayname }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.task }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.start|date("d/m/Y H:i") }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.end|date("d/m/Y H:i") }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ event.duration }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
{% if not fgprint is defined or not fgprint %}
|
||||
$('.table ').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";
|
||||
}
|
||||
|
||||
function validate(id) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
id: id,
|
||||
},
|
||||
url: "{{ path('app_validationholiday_validate') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
alert(response.error);
|
||||
}
|
||||
else {
|
||||
$("#row-"+id).remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function devalidate(id) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
id: id,
|
||||
},
|
||||
url: "{{ path('app_validationholiday_devalidate') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
alert(response.error);
|
||||
}
|
||||
else {
|
||||
$("#row-"+id).remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#switchactive').change(function() {
|
||||
window.location="{{ path('app_validationholiday_activeholiday' )}}";
|
||||
});
|
||||
|
||||
{% endblock %}
|
163
templates/Validation/validationtimer.html.twig
Normal file
163
templates/Validation/validationtimer.html.twig
Normal file
@@ -0,0 +1,163 @@
|
||||
{% 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; }
|
||||
.homecard {width: 100% }
|
||||
{%endif%}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1 class="page-header">
|
||||
VALIDATION HORAIRES
|
||||
</h1>
|
||||
|
||||
<div class="custom-control custom-switch float-right">
|
||||
<input type="checkbox" class="custom-control-input" id="switchactive" {% if app.session.get('activetimer') %} checked {% endif %}>
|
||||
<label class="custom-control-label" for="switchactive">Horaires à Valider</label>
|
||||
</div>
|
||||
<div style="height:30px;">
|
||||
|
||||
</div>
|
||||
<div class="card homecard">
|
||||
<div class="card-header">
|
||||
{% if not app.session.get('activetimer') %}
|
||||
Horaires à Dévalider
|
||||
{% else %}
|
||||
Horaires à Valider
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="dataTable_wrapper">
|
||||
<table class="table table-striped table-bordered table-hover small" id="dataTables" style="width:100%">
|
||||
<thead>
|
||||
<th class="no-print"></th>
|
||||
<th width="150px">Utilisateur</th>
|
||||
<th>Tâche</th>
|
||||
<th>Description</th>
|
||||
<th>Début</th>
|
||||
<th>Fin</th>
|
||||
<th>Durée</th>
|
||||
</thead>
|
||||
|
||||
{% for user in users %}
|
||||
{% for timer in user.timers %}
|
||||
<tr id="row-{{timer.id}}">
|
||||
<td class="no-print" style="vertical-align:middle">
|
||||
{% if timer.validate %}
|
||||
<i class="fa fa-thumbs-down validate-{{user.user.id}}" onClick="devalidate({{timer.id}})" style="cursor:pointer; color:red;"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-thumbs-up validate-{{user.user.id}}" onClick="validate({{timer.id}})" style="cursor:pointer; color:green;"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ user.user.displayname }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ timer.taskname }}
|
||||
</td>
|
||||
<td>
|
||||
<span class="font-weight-bold">
|
||||
{{ timer.activepenalty ? "<i class='fa fa-exclamation' style='color:red;opacity: 0.33;'></i> Astreinte active" : "" }}
|
||||
</span>
|
||||
<span class="font-weight-bold">
|
||||
{{ timer.additionalhour ? "<i class='fa fa-exclamation-triangle' style='color:red;opacity: 0.33;'></i> Heures supplémentaires" : "" }}
|
||||
</span>
|
||||
<p>{{ timer.description }}</p>
|
||||
</td>
|
||||
<td>
|
||||
{{ timer.start|date("d/m/Y H:i") }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ timer.end|date("d/m/Y H:i") }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ timer.duration|date("H:i") }}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block localjavascript %}
|
||||
$(document).ready(function() {
|
||||
{% if not fgprint is defined or not fgprint %}
|
||||
$('.table ').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";
|
||||
}
|
||||
|
||||
function validate(id) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
id: id,
|
||||
},
|
||||
url: "{{ path('app_validationtimer_validate') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
alert(response.error);
|
||||
}
|
||||
else {
|
||||
$("#row-"+id).remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function devalidate(id) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
id: id,
|
||||
},
|
||||
url: "{{ path('app_validationtimer_devalidate') }}",
|
||||
success: function (response) {
|
||||
response=JSON.parse(response);
|
||||
if(response.return=="KO") {
|
||||
alert(response.error);
|
||||
}
|
||||
else {
|
||||
$("#row-"+id).remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#switchactive').change(function() {
|
||||
window.location="{{ path('app_validationtimer_activetimer' )}}";
|
||||
});
|
||||
|
||||
{% endblock %}
|
71
templates/Year/edit.html.twig
Executable file
71
templates/Year/edit.html.twig
Executable 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 %}
|
74
templates/Year/list.html.twig
Normal file
74
templates/Year/list.html.twig
Normal 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 %}
|
630
templates/base.html.twig
Normal file
630
templates/base.html.twig
Normal file
@@ -0,0 +1,630 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
{% set color = app.session.get('color') %}
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html"; charset="utf-8" />
|
||||
<title>{% block title %}{{ appName }}{% endblock %}</title>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
|
||||
{% block head_style %}
|
||||
{{ encore_entry_link_tags('app') }}
|
||||
{% endblock head_style %}
|
||||
|
||||
{% block stylesheets %}{% endblock %}
|
||||
|
||||
<link rel="shortcut icon" href="/{{ appAlias }}/images/logo.png" />
|
||||
</head>
|
||||
|
||||
|
||||
<style>
|
||||
/* global */
|
||||
.bg-dark {
|
||||
background-color: #152c3c !important;
|
||||
}
|
||||
|
||||
h1{
|
||||
padding: 40px 0px 9px 0px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.nav a{
|
||||
background: none;
|
||||
color: #CFD8DC;
|
||||
font-size: 14px;
|
||||
padding: 5px 0px 5px 25px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
/* Sidebar Styles */
|
||||
.contentsidebar {
|
||||
margin-left:250px;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
z-index: 1000;
|
||||
position: fixed;
|
||||
left: 250px;
|
||||
width: 250px;
|
||||
height: 100%;
|
||||
margin-left: -250px;
|
||||
overflow-y: auto;
|
||||
background: #152c3c;
|
||||
-webkit-transition: all 0.5s ease;
|
||||
-moz-transition: all 0.5s ease;
|
||||
-o-transition: all 0.5s ease;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
#sidebar header {
|
||||
background-color: #263238;
|
||||
font-size: 20px;
|
||||
line-height: 52px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#sidebar header a {
|
||||
color: #fff;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#sidebar header a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#sidebar .nav{
|
||||
display: block;
|
||||
}
|
||||
|
||||
#sidebar .nav a {
|
||||
padding: 0px 10px 5px 10px;
|
||||
}
|
||||
|
||||
#sidebar .nav .last{
|
||||
border-bottom: 5px solid #455A64;
|
||||
padding-bottom:5px;
|
||||
}
|
||||
|
||||
#sidebar .title {
|
||||
color: #CFD8DC;
|
||||
font-size: 16px;
|
||||
padding: 0px 10px 0px 10px;
|
||||
display: block;
|
||||
text-transform: uppercase;
|
||||
margin-left: 0px !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#sidebar .nav .last{
|
||||
border-bottom: 5px solid #455A64;
|
||||
padding-bottom:5px;
|
||||
}
|
||||
|
||||
#sidebar .nav a:hover{
|
||||
background: none;
|
||||
color: #ECEFF1;
|
||||
}
|
||||
|
||||
#sidebar .nav a .fa{
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#sidebar .nav .select-control {
|
||||
padding: 0px 10px 5px 10px;
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
background-color: #343a40;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
border-radius: 100%;
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.avatar.big{
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 991px) {
|
||||
.contentsidebar {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
position: static;
|
||||
margin:0px -15px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
a.btn {
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
#sidebar {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
{% if useheader is defined and useheader %}
|
||||
#main {
|
||||
padding-top:55px;
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
|
||||
th.dt-center, td.dt-center { text-align: center; }
|
||||
|
||||
|
||||
.new-page {display:none;}
|
||||
{% if fgprint is defined and fgprint %}
|
||||
.no-print {display:none}
|
||||
|
||||
.new-page {
|
||||
clear: both;
|
||||
display: block;
|
||||
border :1px solid transparent;
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
#sidebar,.navbar,.sf-toolbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mycontent{
|
||||
margin:0px;
|
||||
//width:800px;
|
||||
}
|
||||
|
||||
#main{
|
||||
margin:0px;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
.homecard {
|
||||
display:inline-block;
|
||||
float:none;
|
||||
}
|
||||
{% endif %}
|
||||
{% block localstyle %}
|
||||
|
||||
{% endblock %}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
{% if useheader is defined and useheader %}
|
||||
<nav class="navbar navbar-expand-lg navbar-dark fixed-top bg-dark">
|
||||
<a class="navbar-brand" href="{{ path('app_home')}}">
|
||||
<img src="/{{appAlias}}/images/logo.png" style="height:30px;margin-top:-3px;">
|
||||
{{appName}}
|
||||
</a>
|
||||
|
||||
{% if usesidebar is defined and usesidebar %}
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#sidebar" aria-controls="sidebar" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<ul class="nav navbar-top-links navbar-right">
|
||||
{% 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>
|
||||
<a href="{{path("app_user_profil")}}">
|
||||
<img src="/{{appAlias}}/uploads/avatar/{{app.user.avatar}}" class="avatar">
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% set routeignore = ["app_home","app_event","app_customer_submit","app_project_submit","app_offer_submit","app_task_submit","app_service_submit","app_user_submit","app_nature_submit","app_nature_update","app_job_submit","app_breakday_submit","app_breakday_update"] %}
|
||||
{% if app.request.attributes.get('_route') not in routeignore %}
|
||||
<li>
|
||||
<a onClick="myprint()" style="cursor:pointer; color:#fff"><i class="fa fa-print fa-fw"></i></a>
|
||||
</li>
|
||||
{%endif%}
|
||||
|
||||
<li>
|
||||
{% if app.user %}
|
||||
{% if appAuth=="MYSQL" %}
|
||||
<a href="{{path("app_logout")}}"><i class="fa fa-sign-out-alt fa-fw"></i></a>
|
||||
{% elseif appAuth=="CAS" %}
|
||||
<a href="{{path("app_logoutcas")}}"><i class="fa fa-sign-out-alt fa-fw"></i></a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if appAuth=="MYSQL" %}
|
||||
<a href="{{path("app_login")}}"><i class="fa fa-sign-in-alt fa-fw"></i></a>
|
||||
{% elseif appAuth=="CAS" %}
|
||||
<a href="{{path("app_logincas")}}"><i class="fa fa-sign-in-alt fa-fw"></i></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
<main id="main" class="container-fluid">
|
||||
{% set contentsidebar="" %}
|
||||
{% if usesidebar is defined and usesidebar %}
|
||||
{% set contentsidebar="contentsidebar" %}
|
||||
|
||||
<div id="sidebar" class="collapse">
|
||||
<ul style="padding-bottom:70px" class="nav">
|
||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_VALIDATOR') or is_granted('ROLE_MASTER') or is_granted('ROLE_USER') %}
|
||||
<p></p>
|
||||
<li>
|
||||
<label class="control-label" style="padding:0px 10px 5px 10px; color:#fff;">
|
||||
Nombre de Mois
|
||||
</label>
|
||||
<div class="select-control">
|
||||
<select class="form-control select2entity" id="sidemonth" name="sidemonth">
|
||||
{% set selected="" %}
|
||||
{% for i in 1..48 %}
|
||||
{% set selected="" %}
|
||||
{%if i==app.session.get('nbmonth') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{i}}" {{selected}}>{{i}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="control-label" style="padding:0px 10px 5px 10px; color:#fff;">
|
||||
Service
|
||||
</label>
|
||||
<div class="select-control">
|
||||
<select class="form-control select2entity" id="sideservice" name="sideservice">
|
||||
<option value="all" selected>Toutes les services</option>
|
||||
{% for service in app.session.get('services') %}
|
||||
{% set selected="" %}
|
||||
{%if service.id==app.session.get('idservice') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{service.id}}" {{selected}}>{{service.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="control-label" style="padding:0px 10px 5px 10px; color:#fff;">
|
||||
Domaine
|
||||
</label>
|
||||
<div class="select-control">
|
||||
<select class="form-control select2entity" id="sidedomaine" name="sidedomaine">
|
||||
<option value="all" selected>Toutes les domaines</option>
|
||||
{% for domaine in app.session.get('domaines') %}
|
||||
{% set selected="" %}
|
||||
{%if domaine.id==app.session.get('iddomaine') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{domaine.id}}" {{selected}}>{{domaine.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="control-label" style="padding:0px 10px 5px 10px; color:#fff;">
|
||||
Intervenant
|
||||
</label>
|
||||
<div class="select-control">
|
||||
<select class="form-control select2entity" id="sideuser" name="sideuser">
|
||||
<option value="all" selected>Tout le monde</option>
|
||||
|
||||
{% for user in app.session.get('users') %}
|
||||
{% set selected="" %}
|
||||
{%if user.id==app.session.get('iduser') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{user.id}}" {{selected}}>{{user.displayname}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="control-label" style="padding:0px 10px 5px 10px; color:#fff;">
|
||||
Projet
|
||||
</label>
|
||||
<div class="select-control">
|
||||
<select class="form-control select2entity" id="sideproject" name="sideproject">
|
||||
<option value="all" selected>Tous les projets</option>
|
||||
{% for project in app.session.get('projects')|sort((a, b) => a.displayname <=> b.displayname) %}
|
||||
{% set selected="" %}
|
||||
{%if project.id==app.session.get('idproject') %}
|
||||
{% set selected="selected" %}
|
||||
{% endif %}
|
||||
<option value="{{project.id}}" {{selected}}>{{project.displayname}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
|
||||
<li class="last"></li>
|
||||
|
||||
<li class="title">Planning</li>
|
||||
<li>
|
||||
<a href="{{path("app_synthese")}}">
|
||||
<i class="fa fa-id-card"></i>Synthese
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_planning")}}">
|
||||
<i class="fa fa-tachometer-alt"></i>Planning
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_report")}}">
|
||||
<i class="fa fa-pen-square"></i>Rapport
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_event")}}">
|
||||
<i class="fa fa-calendar-alt"></i>Calendrier
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_timer")}}">
|
||||
<i class="fa fa-stopwatch"></i>Suivi Horaire
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_holiday")}}">
|
||||
<i class="fa fa-umbrella-beach"></i>Mes Congés
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_stat_view")}}">
|
||||
<i class="fas fa-chart-line"></i>Statistiques
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="last">
|
||||
<a href="{{path("app_export_view")}}">
|
||||
<i class="fa fa-file-download"></i>Exports
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_VALIDATOR') %}
|
||||
<li class="title">Validations</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_validation")}}">
|
||||
<i class="fa fa-user-check"></i>Validation Calendrier
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_validationholiday")}}">
|
||||
<i class="fa fa-user-tag"></i>Validation Congés
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="last">
|
||||
<a href="{{path("app_validationtimer")}}">
|
||||
<i class="fa fa-user-clock"></i>Validation Horaires
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_MASTER') %}
|
||||
<li class="title">Projets</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_customer")}}">
|
||||
<i class="fa fa-user"></i>Clients
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_project")}}">
|
||||
<i class="fa fa-suitcase"></i>Projets
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_offer")}}">
|
||||
<i class="fa fa-euro-sign"></i>Commandes
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_task")}}">
|
||||
<i class="fa fa-tasks"></i>Tâches
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="last">
|
||||
<a href="{{path("app_budget_last")}}">
|
||||
<i class="fa fa-money-bill-alt"></i>Budgets
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<li class="title">Organisation</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_service")}}">
|
||||
<i class="fa fa-building"></i>Service
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_domaine")}}">
|
||||
<i class="fas fa-money-bill-alt"></i> Domaines
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_user")}}">
|
||||
<i class="fa fa-users"></i>Utilisateurs
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_nature")}}">
|
||||
<i class="fa fa-folder"></i>Natures
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_job")}}">
|
||||
<i class="fa fa-clipboard-list"></i>Métiers
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="{{path("app_year")}}">
|
||||
<i class="fa fa-calendar-alt"></i>Exercices Comptable
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="last">
|
||||
<a href="{{path("app_breakday")}}">
|
||||
<i class="fa fa-gifts"></i>Jours Fériés
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% if appCron %}
|
||||
<li class="title">Outils</li>
|
||||
<li>
|
||||
<a href="{{path("app_cron")}}">
|
||||
<i class="fa fa-cogs"></i>Jobs
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="last">
|
||||
<a href="{{path("app_cron_log")}}">
|
||||
<i class="fa fa-list-alt"></i>Logs / Dump
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{%endif%}
|
||||
|
||||
|
||||
<div id="mycontent" class="content {{contentsidebar}}">
|
||||
{% block body %}
|
||||
|
||||
{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
|
||||
{{ encore_entry_script_tags('app') }}
|
||||
|
||||
{% block localexternalscript %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var doit = true;
|
||||
|
||||
$("a[data-method]").on('click',function(){
|
||||
if($(this).data('confirm')){
|
||||
doit = confirm($(this).data('confirm'));
|
||||
if(!doit) return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#sidemonth').on('select2:select', function (e) {
|
||||
var data = e.params.data;
|
||||
console.log(data.id);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
nbmonth: data.id,
|
||||
},
|
||||
url: "{{ path('app_home_selectmonth') }}",
|
||||
success: function (response) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#sideuser').on('select2:select', function (e) {
|
||||
var data = e.params.data;
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
iduser: data.id,
|
||||
},
|
||||
url: "{{ path('app_home_selectuser') }}",
|
||||
success: function (response) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#sideproject').on('select2:select', function (e) {
|
||||
var data = e.params.data;
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
idproject: data.id,
|
||||
},
|
||||
url: "{{ path('app_home_selectproject') }}",
|
||||
success: function (response) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#sideservice').on('select2:select', function (e) {
|
||||
var data = e.params.data;
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
idservice: data.id,
|
||||
},
|
||||
url: "{{ path('app_home_selectservice') }}",
|
||||
success: function (response) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#sidedomaine').on('select2:select', function (e) {
|
||||
var data = e.params.data;
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {
|
||||
iddomaine: data.id,
|
||||
},
|
||||
url: "{{ path('app_home_selectdomaine') }}",
|
||||
success: function (response) {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
{% block localjavascript %}
|
||||
|
||||
{% endblock %}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user