dolibarr  7.0.0-beta
stats.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (c) 2008-2013 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2012 Regis Houssin <regis.houssin@capnetworks.com>
5  * Copyright (C) 2012 Marcos GarcĂ­a <marcosgdf@gmail.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 <http://www.gnu.org/licenses/>.
19  */
20 
30 abstract class Stats
31 {
32  protected $db;
33  var $_lastfetchdate=array(); // Dates of cache file read by methods
34  var $cachefilesuffix=''; // Suffix to add to name of cache file (to avoid file name conflicts)
35 
45  function getNbByMonthWithPrevYear($endyear, $startyear, $cachedelay=0, $format=0)
46  {
47  global $conf,$user,$langs;
48 
49  if ($startyear > $endyear) return -1;
50 
51  $datay=array();
52 
53  // Search into cache
54  if (! empty($cachedelay))
55  {
56  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
57  include_once DOL_DOCUMENT_ROOT.'/core/lib/json.lib.php';
58  }
59 
60  $newpathofdestfile=$conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix)?'':$this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
61  $newmask='0644';
62 
63  $nowgmt = dol_now();
64 
65  $foundintocache=0;
66  if ($cachedelay > 0)
67  {
68  $filedate=dol_filemtime($newpathofdestfile);
69  if ($filedate >= ($nowgmt - $cachedelay))
70  {
71  $foundintocache=1;
72 
73  $this->_lastfetchdate[get_class($this).'_'.__FUNCTION__]=$filedate;
74  }
75  else
76  {
77  dol_syslog(get_class($this).'::'.__FUNCTION__." cache file ".$newpathofdestfile." is not found or older than now - cachedelay (".$nowgmt." - ".$cachedelay.") so we can't use it.");
78  }
79  }
80  // Load file into $data
81  if ($foundintocache) // Cache file found and is not too old
82  {
83  dol_syslog(get_class($this).'::'.__FUNCTION__." read data from cache file ".$newpathofdestfile." ".$filedate.".");
84  $data = json_decode(file_get_contents($newpathofdestfile), true);
85  }
86  else
87  {
88  $year=$startyear;
89  while ($year <= $endyear)
90  {
91  $datay[$year] = $this->getNbByMonth($year, $format);
92  $year++;
93  }
94 
95  $data = array();
96 
97  for ($i = 0 ; $i < 12 ; $i++)
98  {
99  $data[$i][]=$datay[$endyear][$i][0];
100  $year=$startyear;
101  while($year <= $endyear)
102  {
103  $data[$i][]=$datay[$year][$i][1];
104  $year++;
105  }
106  }
107  }
108 
109  // Save cache file
110  if (empty($foundintocache) && ($cachedelay > 0 || $cachedelay == -1))
111  {
112  dol_syslog(get_class($this).'::'.__FUNCTION__." save cache file ".$newpathofdestfile." onto disk.");
113  if (! dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
114  $fp = fopen($newpathofdestfile, 'w');
115  fwrite($fp, json_encode($data));
116  fclose($fp);
117  if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
118  @chmod($newpathofdestfile, octdec($newmask));
119 
120  $this->_lastfetchdate[get_class($this).'_'.__FUNCTION__]=$nowgmt;
121  }
122 
123  // return array(array('Month',val1,val2,val3),...)
124  return $data;
125  }
126 
139  function getAmountByMonthWithPrevYear($endyear, $startyear, $cachedelay=0, $format=0)
140  {
141  global $conf,$user,$langs;
142 
143  if ($startyear > $endyear) return -1;
144 
145  $datay=array();
146 
147  // Search into cache
148  if (! empty($cachedelay))
149  {
150  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
151  include_once DOL_DOCUMENT_ROOT.'/core/lib/json.lib.php';
152  }
153 
154  $newpathofdestfile=$conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix)?'':$this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
155  $newmask='0644';
156 
157  $nowgmt = dol_now();
158 
159  $foundintocache=0;
160  if ($cachedelay > 0)
161  {
162  $filedate=dol_filemtime($newpathofdestfile);
163  if ($filedate >= ($nowgmt - $cachedelay))
164  {
165  $foundintocache=1;
166 
167  $this->_lastfetchdate[get_class($this).'_'.__FUNCTION__]=$filedate;
168  }
169  else
170  {
171  dol_syslog(get_class($this).'::'.__FUNCTION__." cache file ".$newpathofdestfile." is not found or older than now - cachedelay (".$nowgmt." - ".$cachedelay.") so we can't use it.");
172  }
173  }
174 
175  // Load file into $data
176  if ($foundintocache) // Cache file found and is not too old
177  {
178  dol_syslog(get_class($this).'::'.__FUNCTION__." read data from cache file ".$newpathofdestfile." ".$filedate.".");
179  $data = json_decode(file_get_contents($newpathofdestfile), true);
180  }
181  else
182  {
183  $year=$startyear;
184  while($year <= $endyear)
185  {
186  $datay[$year] = $this->getAmountByMonth($year, $format);
187  $year++;
188  }
189 
190  $data = array();
191  // $data = array('xval'=>array(0=>xlabel,1=>yval1,2=>yval2...),...)
192  for ($i = 0 ; $i < 12 ; $i++)
193  {
194  $data[$i][]=$datay[$endyear][$i][0]; // set label
195  $year=$startyear;
196  while($year <= $endyear)
197  {
198  $data[$i][]=$datay[$year][$i][1]; // set yval for x=i
199  $year++;
200  }
201  }
202  }
203 
204  // Save cache file
205  if (empty($foundintocache) && ($cachedelay > 0 || $cachedelay == -1))
206  {
207  dol_syslog(get_class($this).'::'.__FUNCTION__." save cache file ".$newpathofdestfile." onto disk.");
208  if (! dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
209  $fp = fopen($newpathofdestfile, 'w');
210  if ($fp)
211  {
212  fwrite($fp, json_encode($data));
213  fclose($fp);
214  if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
215  @chmod($newpathofdestfile, octdec($newmask));
216  }
217  else dol_syslog("Failed to write cache file", LOG_ERR);
218  $this->_lastfetchdate[get_class($this).'_'.__FUNCTION__]=$nowgmt;
219  }
220 
221  return $data;
222  }
223 
231  function getAverageByMonthWithPrevYear($endyear,$startyear)
232  {
233  if ($startyear > $endyear) return -1;
234 
235  $datay=array();
236 
237  $year=$startyear;
238  while($year <= $endyear)
239  {
240  $datay[$year] = $this->getAverageByMonth($year);
241  $year++;
242  }
243 
244  $data = array();
245 
246  for ($i = 0 ; $i < 12 ; $i++)
247  {
248  $data[$i][]=$datay[$endyear][$i][0];
249  $year=$startyear;
250  while($year <= $endyear)
251  {
252  $data[$i][]=$datay[$year][$i][1];
253  $year++;
254  }
255  }
256 
257  return $data;
258  }
259 
267  function getAllByProductEntry($year,$cachedelay=0)
268  {
269  global $conf,$user,$langs;
270 
271  $datay=array();
272 
273  // Search into cache
274  if (! empty($cachedelay))
275  {
276  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
277  include_once DOL_DOCUMENT_ROOT.'/core/lib/json.lib.php';
278  }
279 
280  $newpathofdestfile=$conf->user->dir_temp.'/'.get_class($this).'_'.__FUNCTION__.'_'.(empty($this->cachefilesuffix)?'':$this->cachefilesuffix.'_').$langs->defaultlang.'_entity.'.$conf->entity.'_user'.$user->id.'.cache';
281  $newmask='0644';
282 
283  $nowgmt = dol_now();
284 
285  $foundintocache=0;
286  if ($cachedelay > 0)
287  {
288  $filedate=dol_filemtime($newpathofdestfile);
289  if ($filedate >= ($nowgmt - $cachedelay))
290  {
291  $foundintocache=1;
292 
293  $this->_lastfetchdate[get_class($this).'_'.__FUNCTION__]=$filedate;
294  }
295  else
296  {
297  dol_syslog(get_class($this).'::'.__FUNCTION__." cache file ".$newpathofdestfile." is not found or older than now - cachedelay (".$nowgmt." - ".$cachedelay.") so we can't use it.");
298  }
299  }
300 
301  // Load file into $data
302  if ($foundintocache) // Cache file found and is not too old
303  {
304  dol_syslog(get_class($this).'::'.__FUNCTION__." read data from cache file ".$newpathofdestfile." ".$filedate.".");
305  $data = json_decode(file_get_contents($newpathofdestfile), true);
306  }
307  else
308  {
309  $data=$this->getAllByProduct($year);
310  // $data[$i][]=$datay[$year][$i][1]; // set yval for x=i
311  }
312 
313  // Save cache file
314  if (empty($foundintocache) && ($cachedelay > 0 || $cachedelay == -1))
315  {
316  dol_syslog(get_class($this).'::'.__FUNCTION__." save cache file ".$newpathofdestfile." onto disk.");
317  if (! dol_is_dir($conf->user->dir_temp)) dol_mkdir($conf->user->dir_temp);
318  $fp = fopen($newpathofdestfile, 'w');
319  if ($fp)
320  {
321  fwrite($fp, json_encode($data));
322  fclose($fp);
323  if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK;
324  @chmod($newpathofdestfile, octdec($newmask));
325  }
326  $this->_lastfetchdate[get_class($this).'_'.__FUNCTION__]=$nowgmt;
327  }
328 
329  return $data;
330  }
331 
332 
333  // Here we have low level of shared code called by XxxStats.class.php
334 
335 
342  function _getNbByYear($sql)
343  {
344  $result = array();
345 
346  dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
347  $resql=$this->db->query($sql);
348  if ($resql)
349  {
350  $num = $this->db->num_rows($resql);
351  $i = 0;
352  while ($i < $num)
353  {
354  $row = $this->db->fetch_row($resql);
355  $result[$i] = $row;
356  $i++;
357  }
358  $this->db->free($resql);
359  }
360  else {
361  dol_print_error($this->db);
362  }
363  return $result;
364  }
365 
372  function _getAllByYear($sql)
373  {
374  $result = array();
375 
376  dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
377  $resql=$this->db->query($sql);
378  if ($resql)
379  {
380  $num = $this->db->num_rows($resql);
381  $i = 0;
382  while ($i < $num)
383  {
384  $row = $this->db->fetch_object($resql);
385  $result[$i]['year'] = $row->year;
386  $result[$i]['nb'] = $row->nb;
387  if($i>0 && $row->nb) $result[$i-1]['nb_diff'] = ($result[$i-1]['nb'] - $row->nb) / $row->nb * 100;
388  $result[$i]['total'] = $row->total;
389  if($i>0 && $row->total) $result[$i-1]['total_diff'] = ($result[$i-1]['total'] - $row->total) / $row->total * 100;
390  $result[$i]['avg'] = $row->avg;
391  if($i>0 && $row->avg) $result[$i-1]['avg_diff'] = ($result[$i-1]['avg'] - $row->avg) / $row->avg * 100;
392  // For some $sql only
393  if (isset($row->weighted))
394  {
395  $result[$i]['weighted'] = $row->weighted;
396  if($i>0 && $row->weighted) $result[$i-1]['avg_weighted'] = ($result[$i-1]['weighted'] - $row->weighted) / $row->weighted * 100;
397  }
398  $i++;
399  }
400  $this->db->free($resql);
401  }
402  else {
403  dol_print_error($this->db);
404  }
405  return $result;
406  }
407 
416  function _getNbByMonth($year, $sql, $format=0)
417  {
418  global $langs;
419 
420  $result=array();
421  $res=array();
422 
423  dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
424  $resql=$this->db->query($sql);
425  if ($resql)
426  {
427  $num = $this->db->num_rows($resql);
428  $i = 0; $j = 0;
429  while ($i < $num)
430  {
431  $row = $this->db->fetch_row($resql);
432  $j = $row[0] * 1;
433  $result[$j] = $row[1];
434  $i++;
435  }
436  $this->db->free($resql);
437  }
438  else
439  {
440  dol_print_error($this->db);
441  }
442 
443  for ($i = 1 ; $i < 13 ; $i++)
444  {
445  $res[$i] = (isset($result[$i])?$result[$i]:0);
446  }
447 
448  $data = array();
449 
450  for ($i = 1 ; $i < 13 ; $i++)
451  {
452  $month='unknown';
453  if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
454  elseif ($format == 1) $month=$i;
455  elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
456  //$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
457  //$month=dol_substr($month,0,3);
458  $data[$i-1] = array($month, $res[$i]);
459  }
460 
461  return $data;
462  }
463 
464 
473  function _getAmountByMonth($year, $sql, $format=0)
474  {
475  global $langs;
476 
477  $result=array();
478  $res=array();
479 
480  dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
481 
482  $resql=$this->db->query($sql);
483  if ($resql)
484  {
485  $num = $this->db->num_rows($resql);
486  $i = 0;
487  while ($i < $num)
488  {
489  $row = $this->db->fetch_row($resql);
490  $j = $row[0] * 1;
491  $result[$j] = $row[1];
492  $i++;
493  }
494  $this->db->free($resql);
495  }
496  else dol_print_error($this->db);
497 
498  for ($i = 1 ; $i < 13 ; $i++)
499  {
500  $res[$i] = (int) round((isset($result[$i])?$result[$i]:0));
501  }
502 
503  $data = array();
504 
505  for ($i = 1 ; $i < 13 ; $i++)
506  {
507  $month='unknown';
508  if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
509  elseif ($format == 1) $month=$i;
510  elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
511  //$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
512  //$month=dol_substr($month,0,3);
513  $data[$i-1] = array($month, $res[$i]);
514  }
515 
516  return $data;
517  }
518 
527  function _getAverageByMonth($year, $sql, $format=0)
528  {
529  global $langs;
530 
531  $result=array();
532  $res=array();
533 
534  dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
535  $resql=$this->db->query($sql);
536  if ($resql)
537  {
538  $num = $this->db->num_rows($resql);
539  $i = 0; $j = 0;
540  while ($i < $num)
541  {
542  $row = $this->db->fetch_row($resql);
543  $j = $row[0] * 1;
544  $result[$j] = $row[1];
545  $i++;
546  }
547  $this->db->free($resql);
548  }
549  else dol_print_error($this->db);
550 
551  for ($i = 1 ; $i < 13 ; $i++)
552  {
553  $res[$i] = (isset($result[$i])?$result[$i]:0);
554  }
555 
556  $data = array();
557 
558  for ($i = 1 ; $i < 13 ; $i++)
559  {
560  $month='unknown';
561  if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i));
562  elseif ($format == 1) $month=$i;
563  elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i));
564  //$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
565  //$month=dol_substr($month,0,3);
566  $data[$i-1] = array($month, $res[$i]);
567  }
568 
569  return $data;
570  }
571 
572 
580  function _getAllByProduct($sql, $limit=10)
581  {
582  global $langs;
583 
584  $result=array();
585  $res=array();
586 
587  dol_syslog(get_class($this).'::'.__FUNCTION__."", LOG_DEBUG);
588  $resql=$this->db->query($sql);
589  if ($resql)
590  {
591  $num = $this->db->num_rows($resql);
592  $i = 0; $other=0;
593  while ($i < $num)
594  {
595  $row = $this->db->fetch_row($resql);
596  if ($i < $limit || $num == $limit) $result[$i] = array($row[0],$row[1]); // Ref of product, nb
597  else $other += $row[1];
598  $i++;
599  }
600  if ($num > $limit) $result[$i] = array($langs->transnoentitiesnoconv("Other"),$other);
601  $this->db->free($resql);
602  }
603  else dol_print_error($this->db);
604 
605  return $result;
606  }
607 }
608 
Parent class of statistics class.
Definition: stats.class.php:30
getNbByMonthWithPrevYear($endyear, $startyear, $cachedelay=0, $format=0)
Return nb of elements by month for several years.
Definition: stats.class.php:45
if(GETPOST('cancel','alpha')) if(!GETPOST('confirmmassaction','alpha')&&$massaction!= 'presend'&&$massaction!= 'confirm_presend')
Draft customers invoices.
Definition: list.php:147
getAllByProductEntry($year, $cachedelay=0)
Return count, and sum of products.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
dol_is_dir($folder)
Test if filename is a directory.
Definition: files.lib.php:414
_getNbByMonth($year, $sql, $format=0)
Renvoie le nombre de proposition par mois pour une annee donnee.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
_getAllByProduct($sql, $limit=10)
Return number or total of product refs.
dol_now($mode='gmt')
Return date for now.
_getAllByYear($sql)
Return nb of elements, total amount and avg amount each year.
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:528
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->societe->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1013
_getAmountByMonth($year, $sql, $format=0)
Renvoie le nombre d'element par mois pour une annee donnee.
getAverageByMonthWithPrevYear($endyear, $startyear)
Return average of entity by month for several years.
_getNbByYear($sql)
Return nb of elements by year.
getAmountByMonthWithPrevYear($endyear, $startyear, $cachedelay=0, $format=0)
Return amount of elements by month for several years.
_getAverageByMonth($year, $sql, $format=0)
Renvoie le montant moyen par mois pour une annee donnee.