dolibarr 25.0.0-alpha
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
4 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// Load Dolibarr environment
28require '../../main.inc.php';
36require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
37require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinterstats.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
39
42
43$mode = 'customer';
44if (!$user->hasRight('ficheinter', 'lire')) {
46}
47
48$userid = GETPOSTINT('userid');
49$socid = GETPOSTINT('socid');
50// Security check
51if ($user->socid > 0) {
52 $action = '';
53 $socid = $user->socid;
54}
55
56$nowyear = dol_print_date(dol_now('gmt'), "%Y", 'gmt');
57$year = GETPOST('year') > 0 ? GETPOSTINT('year') : $nowyear;
58$startyear = $year - (!getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? 2 : max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))));
59$endyear = $year;
60
61$object_status = GETPOST('object_status', 'intcomma');
62
63// Load translation files required by the page
64$langs->loadLangs(array('interventions', 'companies', 'other', 'suppliers'));
65
66
67/*
68 * View
69 */
70
71$form = new Form($db);
72$objectstatic = new Fichinter($db);
73
74$picto = 'intervention';
75$title = $langs->trans("Interventions");
76$dir = $conf->ficheinter->dir_temp;
77
78llxHeader('', $title, '', '', 0, 0, '', '', '', 'mod-fichinter page-stats');
79
80$page = 0;
81$param = '';
82$sortfield = '';
83$sortorder = '';
84$massactionbutton = '';
85$num = 0;
86$nbtotalofrecords = $langs->trans("Statistics");
87$limit = 0;
88
89$urlnew = DOL_URL_ROOT.'/fichinter/card.php?action=create';
90if (!empty($socid)) {
91 $urlnew .= '&socid='.$socid;
92}
93
94$newcardbutton = '';
95$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/fichinter/list.php?mode=common', '', 1, array('morecss' => 'reposition'));
96$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', DOL_URL_ROOT.'/fichinter/list.php?mode=kanban', '', 1, array('morecss' => 'reposition'));
97$newcardbutton .= dolGetButtonTitle($langs->trans('Statistics'), '', 'fa fa-chart-bar imgforviewmode', DOL_URL_ROOT.'/fichinter/stats/index.php', '', 2, array('morecss' => 'reposition'));
98$newcardbutton .= dolGetButtonTitleSeparator();
99$newcardbutton .= dolGetButtonTitle($langs->trans('NewIntervention'), '', 'fa fa-plus-circle', $urlnew, '', $user->hasRight('ficheinter', 'creer'));
100
101print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $picto, 0, $newcardbutton, '', $limit, 0, 0, 1);
102
103dol_mkdir($dir);
104
105$stats = new FichinterStats($db, $socid, $mode, ($userid > 0 ? $userid : 0));
106if ($object_status != '' && $object_status > -1) {
107 $stats->where .= ' AND c.fk_statut IN ('.$db->sanitize($db->escape($object_status)).')';
108}
109
110// Build graphic number of object
111$data = $stats->getNbByMonthWithPrevYear($endyear, $startyear);
112// $data = array(array('Lib',val1,val2,val3),...)
113
114
115if (!$user->hasRight('societe', 'client', 'voir')) {
116 $filenamenb = $dir.'/interventionsnbinyear-'.$user->id.'-'.$year.'.png';
117 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsnbinyear-'.$user->id.'-'.$year.'.png';
118} else {
119 $filenamenb = $dir.'/interventionsnbinyear-'.$year.'.png';
120 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsnbinyear-'.$year.'.png';
121}
122
123$px1 = new DolGraph();
124$mesg = $px1->isGraphKo();
125if (!$mesg) {
126 $px1->SetData($data);
127 $i = $startyear;
128 $legend = array();
129 while ($i <= $endyear) {
130 $legend[] = $i;
131 $i++;
132 }
133 $px1->SetLegend($legend);
134 $px1->SetMaxValue($px1->GetCeilMaxValue());
135 $px1->SetMinValue(min(0, $px1->GetFloorMinValue()));
136 $px1->SetWidth($WIDTH);
137 $px1->SetHeight($HEIGHT);
138 $px1->SetYLabel($langs->trans("NbOfIntervention"));
139 $px1->SetShading(3);
140 $px1->SetHorizTickIncrement(1);
141 $px1->mode = 'depth';
142 $px1->SetTitle($langs->trans("NumberOfInterventionsByMonth"));
143
144 $px1->draw($filenamenb, $fileurlnb);
145}
146
147// Build graphic amount of object
148$data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear);
149// $data = array(array('Lib',val1,val2,val3),...)
150
151if (!$user->hasRight('societe', 'client', 'voir')) {
152 $filenameamount = $dir.'/interventionsamountinyear-'.$user->id.'-'.$year.'.png';
153 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsamountinyear-'.$user->id.'-'.$year.'.png';
154} else {
155 $filenameamount = $dir.'/interventionsamountinyear-'.$year.'.png';
156 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsamountinyear-'.$year.'.png';
157}
158
159$px2 = new DolGraph();
160$mesg = $px2->isGraphKo();
161if (!$mesg) {
162 $px2->SetData($data);
163 $i = $startyear;
164 $legend = array();
165 while ($i <= $endyear) {
166 $legend[] = $i;
167 $i++;
168 }
169 $px2->SetLegend($legend);
170 $px2->SetMaxValue($px2->GetCeilMaxValue());
171 $px2->SetMinValue(min(0, $px2->GetFloorMinValue()));
172 $px2->SetWidth($WIDTH);
173 $px2->SetHeight($HEIGHT);
174 $px2->SetYLabel($langs->trans("AmountOfinterventions"));
175 $px2->SetShading(3);
176 $px2->SetHorizTickIncrement(1);
177 $px2->mode = 'depth';
178 $px2->SetTitle($langs->trans("AmountOfinterventionsByMonthHT"));
179
180 $px2->draw($filenameamount, $fileurlamount);
181}
182
183
184$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear);
185
186if (!$user->hasRight('societe', 'client', 'voir')) {
187 $filename_avg = $dir.'/interventionsaverage-'.$user->id.'-'.$year.'.png';
188 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsaverage-'.$user->id.'-'.$year.'.png';
189} else {
190 $filename_avg = $dir.'/interventionsaverage-'.$year.'.png';
191 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsaverage-'.$year.'.png';
192}
193
194$px3 = new DolGraph();
195$mesg = $px3->isGraphKo();
196if (!$mesg) {
197 $px3->SetData($data);
198 $i = $startyear;
199 $legend = array();
200 while ($i <= $endyear) {
201 $legend[] = $i;
202 $i++;
203 }
204 $px3->SetLegend($legend);
205 $px3->SetYLabel($langs->trans("AmountAverage"));
206 $px3->SetMaxValue($px3->GetCeilMaxValue());
207 $px3->SetMinValue((int) $px3->GetFloorMinValue());
208 $px3->SetWidth($WIDTH);
209 $px3->SetHeight($HEIGHT);
210 $px3->SetShading(3);
211 $px3->SetHorizTickIncrement(1);
212 $px3->mode = 'depth';
213 $px3->SetTitle($langs->trans("AmountAverage"));
214
215 $px3->draw($filename_avg, $fileurl_avg);
216}
217
218
219
220// Show array
221$data = $stats->getAllByYear();
222$arrayyears = array();
223foreach ($data as $val) {
224 if (!empty($val['year'])) {
225 $arrayyears[$val['year']] = $val['year'];
226 }
227}
228if (!count($arrayyears)) {
229 $arrayyears[$nowyear] = $nowyear;
230}
231
232$h = 0;
233$head = array();
234$head[$h][0] = DOL_URL_ROOT.'/fichinter/stats/index.php';
235$head[$h][1] = $langs->trans("ByMonthYear");
236$head[$h][2] = 'byyear';
237$h++;
238
239$type = 'fichinter_stats';
240
241complete_head_from_modules($conf, $langs, null, $head, $h, $type);
242
243print dol_get_fiche_head($head, 'byyear', '', -1);
244
245
246print '<div class="fichecenter"><div class="fichethirdleft">';
247
248
249// Show filter box
250print '<form name="stats" method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
251print '<input type="hidden" name="token" value="'.newToken().'">';
252print '<input type="hidden" name="mode" value="'.$mode.'">';
253
254print '<table class="noborder centpercent">';
255print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
256// Company
257print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
258$filter = '(s.client:IN:1,2,3)';
259print img_picto('', 'company', 'class="pictofixedwidth"');
260print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
261print '</td></tr>';
262// User
263print '<tr><td class="left">'.$langs->trans("CreatedBy").'</td><td class="left">';
264print img_picto('', 'user', 'class="pictofixedwidth"');
265print $form->select_dolusers($userid, 'userid', 1, null, 0, '', '', '0', 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
266// Status
267print '<tr><td class="left">'.$langs->trans("Status").'</td><td class="left">';
268$tmp = $objectstatic->LibStatut(0); // To force load of $this->labelStatus
269$liststatus = $objectstatic->labelStatus;
270if (!getDolGlobalString('FICHINTER_CLASSIFY_BILLED')) {
271 unset($liststatus[$objectstatic::STATUS_BILLED]); // Option deprecated. In a future, billed must be managed with a dedicated field to 0 or 1
272}
273print $form->selectarray('object_status', $liststatus, $object_status, 1, 0, 0, '', 1);
274print '</td></tr>';
275// Year
276print '<tr><td class="left">'.$langs->trans("Year").'</td><td class="left">';
277if (!in_array($year, $arrayyears)) {
278 $arrayyears[$year] = $year;
279}
280if (!in_array($nowyear, $arrayyears)) {
281 $arrayyears[$nowyear] = $nowyear;
282}
283arsort($arrayyears);
284print img_picto('', 'calendar', 'class="pictofixedwidth"');
285print $form->selectarray('year', $arrayyears, $year, 0, 0, 0, '', 0, 0, 0, '', 'width75');
286print '</td></tr>';
287print '<tr><td class="center" colspan="2"><input type="submit" name="submit" class="button small" value="'.$langs->trans("Refresh").'"></td></tr>';
288print '</table>';
289print '</form>';
290print '<br><br>';
291
292print '<div class="div-table-responsive-no-min">';
293print '<table class="noborder centpercent">';
294print '<tr class="liste_titre" height="24">';
295print '<td class="center">'.$langs->trans("Year").'</td>';
296print '<td class="right">'.$langs->trans("NbOfinterventions").'</td>';
297print '<td class="right">%</td>';
298print '<td class="right">'.$langs->trans("AmountTotal").'</td>';
299print '<td class="right">%</td>';
300print '<td class="right">'.$langs->trans("AmountAverage").'</td>';
301print '<td class="right">%</td>';
302print '</tr>';
303
304$oldyear = 0;
305foreach ($data as $val) {
306 $year = $val['year'];
307 while (!empty($year) && $oldyear > (int) $year + 1) {
308 // If we have empty year
309 $oldyear--;
310
311 print '<tr class="oddeven" height="24">';
312 print '<td class="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$oldyear.'&amp;mode='.$mode.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$oldyear.'</a></td>';
313
314 print '<td class="right">0</td>';
315 print '<td class="right"></td>';
316 print '<td class="right">0</td>';
317 print '<td class="right"></td>';
318 print '<td class="right">0</td>';
319 print '<td class="right"></td>';
320 print '</tr>';
321 }
322
323
324 print '<tr class="oddeven" height="24">';
325 print '<td class="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&amp;mode='.$mode.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$year.'</a></td>';
326 print '<td class="right">'.$val['nb'].'</td>';
327 print '<td class="right opacitylow" style="'.((!isset($val['nb_diff']) || $val['nb_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['nb_diff']) ? round($val['nb_diff']) : "0").'%</td>';
328 print '<td class="right">'.price(price2num($val['total'], 'MT'), 1).'</td>';
329 print '<td class="right opacitylow" style="'.((!isset($val['total_diff']) || $val['total_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['total_diff']) ? round($val['total_diff']) : "0").'%</td>';
330 print '<td class="right">'.price(price2num($val['avg'], 'MT'), 1).'</td>';
331 print '<td class="right opacitylow" style="'.((!isset($val['avg_diff']) || $val['avg_diff'] >= 0) ? 'color: green;' : 'color: red;').'">'.(isset($val['avg_diff']) ? round($val['avg_diff']) : "0").'%</td>';
332 print '</tr>';
333 $oldyear = $year;
334}
335
336print '</table>';
337print '</div>';
338
339
340print '</div><div class="fichetwothirdright">';
341
342
343// Show graphs
344print '<table class="border centpercent"><tr class="pair nohover"><td class="center">';
345if ($mesg) {
346 print $mesg;
347} else {
348 print $px1->show();
349 /*print "<br>\n";
350 print $px2->show();
351 print "<br>\n";
352 print $px3->show();*/
353}
354print '</td></tr></table>';
355
356
357print '</div></div>';
358print '<div class="clearboth"></div>';
359
360print dol_get_fiche_end();
361
362
363llxFooter();
364
365$db->close();
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to build graphs.
static getDefaultGraphSizeForStats($direction, $defaultsize='')
getDefaultGraphSizeForStats
Class to manage intervention statistics.
Class to manage generation of HTML components Only common components must be here.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:519
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:717
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.