dolibarr  20.0.0-beta
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
30 require '../../main.inc.php';
31 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/commande/class/commandestats.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
38 
40 $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height');
41 
42 $mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer';
43 
44 $usercanreadcustumerstatistic = $user->hasRight('commande', 'lire');
45 $usercanreadsupplierstatistic = $user->hasRight('fournisseur', 'commande', 'lire');
46 if (getDolGlobalInt('MAIN_NEED_EXPORT_PERMISSION_TO_READ_STATISTICS')) {
47  $usercanreadcustumerstatistic = $user->hasRight('commande', 'commande', 'export');
48  $usercanreadsupplierstatistic = $user->hasRight('fournisseur', 'commande', 'export');
49 }
50 if ($mode == 'customer' && !$usercanreadcustumerstatistic) {
52 }
53 if ($mode == 'supplier' && !$usercanreadsupplierstatistic) {
55 }
56 
57 if ($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 = GETPOSTINT('typent_id');
66 $categ_id = GETPOSTINT('categ_id');
67 
68 $userid = GETPOSTINT('userid');
69 $socid = GETPOSTINT('socid');
70 // Security check
71 if ($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 
98 if ($mode == 'supplier') {
99  $picto = 'supplier_order';
100  $title = $langs->trans("OrdersStatisticsSuppliers");
101  $dir = $conf->fournisseur->commande->dir_temp;
102 }
103 
104 llxHeader('', $title, '', '', 0, 0, '', '', '', 'mod-order page-stats');
105 
106 print load_fiche_titre($title, '', $picto);
107 
108 dol_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));
111 if ($mode == 'customer') {
112  if ($object_status != '' && $object_status >= -1) {
113  $stats->where .= ' AND c.fk_statut IN ('.$db->sanitize($object_status).')';
114  }
115 }
116 if ($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 
130 if (!$user->hasRight('societe', 'client', 'voir')) {
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();
150 if (!$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 
177 if (!$user->hasRight('societe', 'client', 'voir')) {
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();
197 if (!$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 
222 if (!$user->hasRight('societe', 'client', 'voir')) {
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();
242 if (!$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();
269 foreach ($data as $val) {
270  if (!empty($val['year'])) {
271  $arrayyears[$val['year']] = $val['year'];
272  }
273 }
274 if (!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 
285 if ($mode == 'customer') {
286  $type = 'order_stats';
287 }
288 if ($mode == 'supplier') {
289  $type = 'supplier_order_stats';
290 }
291 
292 complete_head_from_modules($conf, $langs, null, $head, $h, $type);
293 
294 print dol_get_fiche_head($head, 'byyear', '', -1);
295 
296 
297 print '<div class="fichecenter"><div class="fichethirdleft">';
298 
299 
300 // Show filter box
301 print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
302 print '<input type="hidden" name="token" value="'.newToken().'">';
303 print '<input type="hidden" name="mode" value="'.$mode.'">';
304 
305 print '<table class="noborder centpercent">';
306 print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
307 // Company
308 print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
309 $filter = '';
310 if ($mode == 'customer') {
311  $filter = '(s.client:IN:1,2,3)';
312 }
313 if ($mode == 'supplier') {
314  $filter = '(s.fournisseur:=:1)';
315 }
316 print img_picto('', 'company', 'class="pictofixedwidth"');
317 print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300');
318 print '</td></tr>';
319 // ThirdParty Type
320 print '<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.
322 print $form->selectarray("typent_id", $formcompany->typent_array(0), $typent_id, 1, 0, 0, '', 0, 0, 0, $sortparam_typent, '', 1);
323 if ($user->admin) {
324  print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
325 }
326 print '</td></tr>';
327 // Category
328 if ($mode == 'customer') {
329  $cat_type = Categorie::TYPE_CUSTOMER;
330  $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Customer"));
331 }
332 if ($mode == 'supplier') {
333  $cat_type = Categorie::TYPE_SUPPLIER;
334  $cat_label = $langs->trans("Category").' '.lcfirst($langs->trans("Supplier"));
335 }
336 print '<tr><td>'.$cat_label.'</td><td>';
337 print img_picto('', 'category', 'class="pictofixedwidth"');
338 print $formother->select_categories($cat_type, $categ_id, 'categ_id', 0, 1, 'widthcentpercentminusx maxwidth300');
339 print '</td></tr>';
340 // User
341 print '<tr><td>'.$langs->trans("CreatedBy").'</td><td>';
342 print img_picto('', 'user', 'class="pictofixedwidth"');
343 print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300');
344 // Status
345 print '<tr><td>'.$langs->trans("Status").'</td><td>';
346 if ($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 }
356 if ($mode == 'supplier') {
357  $formorder->selectSupplierOrderStatus((strstr($object_status, ',') ? -1 : $object_status), 0, 'object_status');
358 }
359 print '</td></tr>';
360 // Year
361 print '<tr><td class="left">'.$langs->trans("Year").'</td><td class="left">';
362 if (!in_array($year, $arrayyears)) {
363  $arrayyears[$year] = $year;
364 }
365 if (!in_array($nowyear, $arrayyears)) {
366  $arrayyears[$nowyear] = $nowyear;
367 }
368 arsort($arrayyears);
369 print $form->selectarray('year', $arrayyears, $year, 0, 0, 0, '', 0, 0, 0, '', 'width75');
370 print '</td></tr>';
371 print '<tr><td align="center" colspan="2"><input type="submit" class="button small" name="submit" value="'.$langs->trans("Refresh").'"></td></tr>';
372 print '</table>';
373 print '</form>';
374 print '<br><br>';
375 
376 
377 print '<div class="div-table-responsive-no-min">';
378 print '<table class="noborder centpercent">';
379 print '<tr class="liste_titre" height="24">';
380 print '<td class="center">'.$langs->trans("Year").'</td>';
381 print '<td class="right">'.$langs->trans("NbOfOrders").'</td>';
382 print '<td class="right">%</td>';
383 print '<td class="right">'.$langs->trans("AmountTotal").'</td>';
384 print '<td class="right">%</td>';
385 print '<td class="right">'.$langs->trans("AmountAverage").'</td>';
386 print '<td class="right">%</td>';
387 print '</tr>';
388 
389 $oldyear = 0;
390 foreach ($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 
419 print '</table>';
420 print '</div>';
421 
422 
423 print '</div><div class="fichetwothirdright">';
424 
425 
426 // Show graphs
427 print '<table class="border centpercent"><tr class="pair nohover"><td align="center">';
428 if ($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 }
437 print '</td></tr></table>';
438 
439 
440 print '</div></div>';
441 print '<div class="clearboth"></div>';
442 
443 print dol_get_fiche_end();
444 
445 // End of page
446 llxFooter();
447 $db->close();
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...
Class permettant la generation de composants html autre Only common components are here.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
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)
llxFooter()
Footer empty.
Definition: index.php:72
if(!defined('NOTOKENRENEWAL')) if(!defined('NOLOGIN')) if(!defined('NOCSRFCHECK')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) if(!defined('NOIPCHECK')) if(!defined('NOBROWSERNOTIF')) llxHeader()
Header empty.
Definition: index.php:64
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.