dolibarr 19.0.4
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2013 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2012 Marcos García <marcosgdf@gmail.com>
6 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
7 * Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
29// Load Dolibarr environment
30require '../../main.inc.php';
31require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
32require_once DOL_DOCUMENT_ROOT.'/commande/class/commandestats.class.php';
33require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
38
41
42$mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer';
43
44$usercanreadcustumerstatistic = $user->hasRight('commande', 'lire');
45$usercanreadsupplierstatistic = $user->hasRight('fournisseur', 'commande', 'lire');
46if (getDolGlobalInt('MAIN_NEED_EXPORT_PERMISSION_TO_READ_STATISTICS')) {
47 $usercanreadcustumerstatistic = $user->hasRight('commande', 'commande', 'export');
48 $usercanreadsupplierstatistic = $user->hasRight('fournisseur', 'commande', 'export');
49}
50if ($mode == 'customer' && !$usercanreadcustumerstatistic) {
52}
53if ($mode == 'supplier' && !$usercanreadsupplierstatistic) {
55}
56
57if ($mode == 'supplier') {
58 $object_status = GETPOST('object_status', 'array:int');
59 $object_status = implode(',', $object_status);
60} else {
61 $object_status = GETPOST('object_status', 'intcomma');
62}
63
64
65$typent_id = GETPOST('typent_id', 'int');
66$categ_id = GETPOST('categ_id', 'categ_id');
67
68$userid = GETPOST('userid', 'int');
69$socid = GETPOST('socid', 'int');
70// Security check
71if ($user->socid > 0) {
72 $action = '';
73 $socid = $user->socid;
74}
75
76$nowyear = dol_print_date(dol_now('gmt'), "%Y", 'gmt');
77$year = GETPOST('year') > 0 ? GETPOST('year') : $nowyear;
78$startyear = $year - (!getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS') ? 2 : max(1, min(10, getDolGlobalString('MAIN_STATS_GRAPHS_SHOW_N_YEARS'))));
79$endyear = $year;
80
81// Load translation files required by the page
82$langs->loadLangs(array('orders', 'companies', 'other', 'suppliers'));
83
84
85/*
86 * View
87 */
88
89$form = new Form($db);
90$formorder = new FormOrder($db);
91$formcompany = new FormCompany($db);
92$formother = new FormOther($db);
93
94$picto = 'order';
95$title = $langs->trans("OrdersStatistics");
96$dir = $conf->commande->dir_temp;
97
98if ($mode == 'supplier') {
99 $picto = 'supplier_order';
100 $title = $langs->trans("OrdersStatisticsSuppliers");
101 $dir = $conf->fournisseur->commande->dir_temp;
102}
103
104llxHeader('', $title);
105
106print load_fiche_titre($title, '', $picto);
107
108dol_mkdir($dir);
109
110$stats = new CommandeStats($db, $socid, $mode, ($userid > 0 ? $userid : 0), ($typent_id > 0 ? $typent_id : 0), ($categ_id > 0 ? $categ_id : 0));
111if ($mode == 'customer') {
112 if ($object_status != '' && $object_status >= -1) {
113 $stats->where .= ' AND c.fk_statut IN ('.$db->sanitize($object_status).')';
114 }
115}
116if ($mode == 'supplier') {
117 if ($object_status != '' && $object_status >= 0) {
118 $stats->where .= ' AND c.fk_statut IN ('.$db->sanitize($object_status).')';
119 }
120}
121
122
123// Build graphic number of object
124$data = $stats->getNbByMonthWithPrevYear($endyear, $startyear);
125
126//var_dump($data);
127// $data = array(array('Lib',val1,val2,val3),...)
128
129
130if (!$user->hasRight('societe', 'client', 'voir') || $user->socid) {
131 $filenamenb = $dir.'/ordersnbinyear-'.$user->id.'-'.$year.'.png';
132 if ($mode == 'customer') {
133 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersnbinyear-'.$user->id.'-'.$year.'.png';
134 }
135 if ($mode == 'supplier') {
136 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersnbinyear-'.$user->id.'-'.$year.'.png';
137 }
138} else {
139 $filenamenb = $dir.'/ordersnbinyear-'.$year.'.png';
140 if ($mode == 'customer') {
141 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersnbinyear-'.$year.'.png';
142 }
143 if ($mode == 'supplier') {
144 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersnbinyear-'.$year.'.png';
145 }
146}
147
148$px1 = new DolGraph();
149$mesg = $px1->isGraphKo();
150if (!$mesg) {
151 $px1->SetData($data);
152 $i = $startyear;
153 $legend = array();
154 while ($i <= $endyear) {
155 $legend[] = $i;
156 $i++;
157 }
158 $px1->SetLegend($legend);
159 $px1->SetMaxValue($px1->GetCeilMaxValue());
160 $px1->SetMinValue(min(0, $px1->GetFloorMinValue()));
161 $px1->SetWidth($WIDTH);
162 $px1->SetHeight($HEIGHT);
163 $px1->SetYLabel($langs->trans("NbOfOrder"));
164 $px1->SetShading(3);
165 $px1->SetHorizTickIncrement(1);
166 $px1->mode = 'depth';
167 $px1->SetTitle($langs->trans("NumberOfOrdersByMonth"));
168
169 $px1->draw($filenamenb, $fileurlnb);
170}
171
172// Build graphic amount of object
173$data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear);
174//var_dump($data);
175// $data = array(array('Lib',val1,val2,val3),...)
176
177if (!$user->hasRight('societe', 'client', 'voir') || $user->socid) {
178 $filenameamount = $dir.'/ordersamountinyear-'.$user->id.'-'.$year.'.png';
179 if ($mode == 'customer') {
180 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersamountinyear-'.$user->id.'-'.$year.'.png';
181 }
182 if ($mode == 'supplier') {
183 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersamountinyear-'.$user->id.'-'.$year.'.png';
184 }
185} else {
186 $filenameamount = $dir.'/ordersamountinyear-'.$year.'.png';
187 if ($mode == 'customer') {
188 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersamountinyear-'.$year.'.png';
189 }
190 if ($mode == 'supplier') {
191 $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersamountinyear-'.$year.'.png';
192 }
193}
194
195$px2 = new DolGraph();
196$mesg = $px2->isGraphKo();
197if (!$mesg) {
198 $px2->SetData($data);
199 $i = $startyear;
200 $legend = array();
201 while ($i <= $endyear) {
202 $legend[] = $i;
203 $i++;
204 }
205 $px2->SetLegend($legend);
206 $px2->SetMaxValue($px2->GetCeilMaxValue());
207 $px2->SetMinValue(min(0, $px2->GetFloorMinValue()));
208 $px2->SetWidth($WIDTH);
209 $px2->SetHeight($HEIGHT);
210 $px2->SetYLabel($langs->trans("AmountOfOrders"));
211 $px2->SetShading(3);
212 $px2->SetHorizTickIncrement(1);
213 $px2->mode = 'depth';
214 $px2->SetTitle($langs->trans("AmountOfOrdersByMonthHT"));
215
216 $px2->draw($filenameamount, $fileurlamount);
217}
218
219
220$data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear);
221
222if (!$user->hasRight('societe', 'client', 'voir') || $user->socid) {
223 $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png';
224 if ($mode == 'customer') {
225 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png';
226 }
227 if ($mode == 'supplier') {
228 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$user->id.'-'.$year.'.png';
229 }
230} else {
231 $filename_avg = $dir.'/ordersaverage-'.$year.'.png';
232 if ($mode == 'customer') {
233 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$year.'.png';
234 }
235 if ($mode == 'supplier') {
236 $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstatssupplier&file=ordersaverage-'.$year.'.png';
237 }
238}
239
240$px3 = new DolGraph();
241$mesg = $px3->isGraphKo();
242if (!$mesg) {
243 $px3->SetData($data);
244 $i = $startyear;
245 $legend = array();
246 while ($i <= $endyear) {
247 $legend[] = $i;
248 $i++;
249 }
250 $px3->SetLegend($legend);
251 $px3->SetYLabel($langs->trans("AmountAverage"));
252 $px3->SetMaxValue($px3->GetCeilMaxValue());
253 $px3->SetMinValue($px3->GetFloorMinValue());
254 $px3->SetWidth($WIDTH);
255 $px3->SetHeight($HEIGHT);
256 $px3->SetShading(3);
257 $px3->SetHorizTickIncrement(1);
258 $px3->mode = 'depth';
259 $px3->SetTitle($langs->trans("AmountAverage"));
260
261 $px3->draw($filename_avg, $fileurl_avg);
262}
263
264
265
266// Show array
267$data = $stats->getAllByYear();
268$arrayyears = array();
269foreach ($data as $val) {
270 if (!empty($val['year'])) {
271 $arrayyears[$val['year']] = $val['year'];
272 }
273}
274if (!count($arrayyears)) {
275 $arrayyears[$nowyear] = $nowyear;
276}
277
278$h = 0;
279$head = array();
280$head[$h][0] = DOL_URL_ROOT.'/commande/stats/index.php?mode='.$mode;
281$head[$h][1] = $langs->trans("ByMonthYear");
282$head[$h][2] = 'byyear';
283$h++;
284
285if ($mode == 'customer') {
286 $type = 'order_stats';
287}
288if ($mode == 'supplier') {
289 $type = 'supplier_order_stats';
290}
291
292complete_head_from_modules($conf, $langs, null, $head, $h, $type);
293
294print dol_get_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1);
295
296
297print '<div class="fichecenter"><div class="fichethirdleft">';
298
299
300// Show filter box
301print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
302print '<input type="hidden" name="token" value="'.newToken().'">';
303print '<input type="hidden" name="mode" value="'.$mode.'">';
304
305print '<table class="noborder centpercent">';
306print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
307// Company
308print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
309$filter = '';
310if ($mode == 'customer') {
311 $filter = '(s.client:IN:1,2,3)';
312}
313if ($mode == 'supplier') {
314 $filter = '(s.fournisseur:=:1)';
315}
316print img_picto('', 'company', 'class="pictofixedwidth"');
317print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300');
318print '</td></tr>';
319// ThirdParty Type
320print '<tr><td>'.$langs->trans("ThirdPartyType").'</td><td>';
321$sortparam_typent = (!getDolGlobalString('SOCIETE_SORT_ON_TYPEENT') ? 'ASC' : $conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label.
322print $form->selectarray("typent_id", $formcompany->typent_array(0), $typent_id, 1, 0, 0, '', 0, 0, 0, $sortparam_typent, '', 1);
323if ($user->admin) {
324 print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
325}
326print '</td></tr>';
327// Category
328if ($mode == 'customer') {
329 $cat_type = Categorie::TYPE_CUSTOMER;
330 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Customer"));
331}
332if ($mode == 'supplier') {
333 $cat_type = Categorie::TYPE_SUPPLIER;
334 $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Supplier"));
335}
336print '<tr><td>'.$cat_label.'</td><td>';
337print img_picto('', 'category', 'class="pictofixedwidth"');
338print $formother->select_categories($cat_type, $categ_id, 'categ_id', 0, 1, 'widthcentpercentminusx maxwidth300');
339print '</td></tr>';
340// User
341print '<tr><td>'.$langs->trans("CreatedBy").'</td><td>';
342print img_picto('', 'user', 'class="pictofixedwidth"');
343print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
344// Status
345print '<tr><td>'.$langs->trans("Status").'</td><td>';
346if ($mode == 'customer') {
347 $liststatus = array(
348 Commande::STATUS_DRAFT => $langs->trans("StatusOrderDraft"),
349 Commande::STATUS_VALIDATED => $langs->trans("StatusOrderValidated"),
350 Commande::STATUS_SHIPMENTONPROCESS => $langs->trans("StatusOrderSent"),
351 Commande::STATUS_CLOSED => $langs->trans("StatusOrderDelivered"),
352 Commande::STATUS_CANCELED => $langs->trans("StatusOrderCanceled")
353 );
354 print $form->selectarray('object_status', $liststatus, GETPOST('object_status', 'intcomma'), -4);
355}
356if ($mode == 'supplier') {
357 $formorder->selectSupplierOrderStatus((strstr($object_status, ',') ? -1 : $object_status), 0, 'object_status');
358}
359print '</td></tr>';
360// Year
361print '<tr><td class="left">'.$langs->trans("Year").'</td><td class="left">';
362if (!in_array($year, $arrayyears)) {
363 $arrayyears[$year] = $year;
364}
365if (!in_array($nowyear, $arrayyears)) {
366 $arrayyears[$nowyear] = $nowyear;
367}
368arsort($arrayyears);
369print $form->selectarray('year', $arrayyears, $year, 0, 0, 0, '', 0, 0, 0, '', 'width75');
370print '</td></tr>';
371print '<tr><td align="center" colspan="2"><input type="submit" class="button small" name="submit" value="'.$langs->trans("Refresh").'"></td></tr>';
372print '</table>';
373print '</form>';
374print '<br><br>';
375
376
377print '<div class="div-table-responsive-no-min">';
378print '<table class="noborder centpercent">';
379print '<tr class="liste_titre" height="24">';
380print '<td class="center">'.$langs->trans("Year").'</td>';
381print '<td class="right">'.$langs->trans("NbOfOrders").'</td>';
382print '<td class="right">%</td>';
383print '<td class="right">'.$langs->trans("AmountTotal").'</td>';
384print '<td class="right">%</td>';
385print '<td class="right">'.$langs->trans("AmountAverage").'</td>';
386print '<td class="right">%</td>';
387print '</tr>';
388
389$oldyear = 0;
390foreach ($data as $val) {
391 $year = $val['year'];
392 while (!empty($year) && $oldyear > $year + 1) { // If we have empty year
393 $oldyear--;
394
395 print '<tr class="oddeven" height="24">';
396 print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$oldyear.'&amp;mode='.$mode.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$oldyear.'</a></td>';
397 print '<td class="right">0</td>';
398 print '<td class="right"></td>';
399 print '<td class="right">0</td>';
400 print '<td class="right"></td>';
401 print '<td class="right">0</td>';
402 print '<td class="right"></td>';
403 print '</tr>';
404 }
405
406
407 print '<tr class="oddeven" height="24">';
408 print '<td align="center"><a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&amp;mode='.$mode.($socid > 0 ? '&socid='.$socid : '').($userid > 0 ? '&userid='.$userid : '').'">'.$year.'</a></td>';
409 print '<td class="right">'.$val['nb'].'</td>';
410 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>';
411 print '<td class="right">'.price(price2num($val['total'], 'MT'), 1).'</td>';
412 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>';
413 print '<td class="right">'.price(price2num($val['avg'], 'MT'), 1).'</td>';
414 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>';
415 print '</tr>';
416 $oldyear = $year;
417}
418
419print '</table>';
420print '</div>';
421
422
423print '</div><div class="fichetwothirdright">';
424
425
426// Show graphs
427print '<table class="border centpercent"><tr class="pair nohover"><td align="center">';
428if ($mesg) {
429 print $mesg;
430} else {
431 print $px1->show();
432 print "<br>\n";
433 print $px2->show();
434 print "<br>\n";
435 print $px3->show();
436}
437print '</td></tr></table>';
438
439
440print '</div></div>';
441print '<div class="clearboth"></div>';
442
443print dol_get_fiche_end();
444
445// End of page
446llxFooter();
447$db->close();
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
const STATUS_SHIPMENTONPROCESS
Shipment on process.
const STATUS_CLOSED
Closed (Sent, billed or not)
const STATUS_CANCELED
Canceled status.
const STATUS_DRAFT
Draft status.
const STATUS_VALIDATED
Validated status.
Class to manage order statistics (customer and supplier)
Class to build graphs.
static getDefaultGraphSizeForStats($direction, $defaultsize='')
getDefaultGraphSizeForStats
Class to build HTML component for third parties management Only common components are here.
Class to manage generation of HTML components Only common components must be here.
Class to manage HTML output components for orders Before adding component here, check they are not in...
Classe permettant la generation de composants html autre Only common components are here.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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 dolibarr global constant string value.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.