2007-05-31 20:55:47 +02:00
< ? php
2012-07-12 19:14:13 +02:00
/* Copyright ( C ) 2003 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2013-07-16 18:42:43 +02:00
* Copyright ( c ) 2008 - 2013 Laurent Destailleur < eldy @ users . sourceforge . net >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2012 Regis Houssin < regis . houssin @ inodbox . com >
2012-08-14 15:43:14 +02:00
* Copyright ( C ) 2012 Marcos García < marcosgdf @ gmail . com >
2024-10-29 17:31:59 +01:00
* Copyright ( C ) 2024 MDW < mdeweerd @ users . noreply . github . com >
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2007-05-31 20:55:47 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2007-05-31 20:55:47 +02:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2007-05-31 20:55:47 +02:00
*/
2008-09-07 23:36:42 +02:00
/**
2012-03-12 15:09:46 +01:00
* \file htdocs / core / class / stats . class . php
* \ingroup core
* \brief Common class to manage statistics reports
2008-09-07 23:36:42 +02:00
*/
2008-11-09 13:54:44 +01:00
/**
2012-03-12 15:09:46 +01:00
* Parent class of statistics class
2008-11-09 13:54:44 +01:00
*/
2011-08-28 16:58:29 +02:00
abstract class Stats
2007-05-31 20:55:47 +02:00
{
2024-08-27 04:51:41 +02:00
/**
* @ var DoliDB
*/
2020-10-31 14:32:18 +01:00
protected $db ;
2024-08-27 04:51:41 +02:00
/**
* @ var array < string , int > Dates of cache file read by methods
*/
protected $lastfetchdate = array ();
2024-10-29 17:31:59 +01:00
/**
2024-10-29 22:44:47 +01:00
* @ var string Suffix to add to name of cache file ( to avoid file name conflicts )
2024-10-29 17:31:59 +01:00
*/
2024-10-29 22:44:47 +01:00
public $cachefilesuffix = '' ;
2011-09-20 19:19:46 +02:00
2023-08-06 12:26:27 +02:00
/**
* @ var string To store the FROM part of the main table of the SQL request
*/
public $from ;
2023-08-25 18:10:50 +02:00
/**
* @ var string To store the WHERE part of the main table of the SQL request
*/
public $where ;
2023-08-06 12:26:27 +02:00
/**
* @ var string To store the FROM part of the line table of the SQL request
*/
public $from_line ;
/**
* @ var string To store the field of the date
*/
public $field_date ;
/**
* @ var string To store the field for total HT
*/
public $field ;
/**
* @ var string To store the FROM part of the line table of the SQL request
*/
public $field_line ;
2023-08-25 18:10:50 +02:00
/**
* @ var string error message
*/
public $error ;
/**
* @ var int year
*/
public $year ;
/**
* @ var int month
*/
public $month ;
2023-08-06 12:26:27 +02:00
2022-06-15 11:10:31 +02:00
/**
2024-03-20 19:53:22 +01:00
* @ param int $year number
* @ param int $format 0 = Label of abscissa is a translated text , 1 = Label of abscissa is month number , 2 = Label of abscissa is first letter of month
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int } > Array of nb each month
2022-06-15 11:10:31 +02:00
*/
2023-12-04 12:04:36 +01:00
abstract protected function getNbByMonth ( $year , $format = 0 );
2022-06-15 11:10:31 +02:00
2008-09-07 23:36:42 +02:00
/**
2013-06-28 19:19:18 +02:00
* Return nb of elements by month for several years
2011-09-20 19:19:46 +02:00
*
2024-03-20 19:53:22 +01:00
* @ param int $endyear Start year
* @ param int $startyear End year
* @ param int $cachedelay Delay we accept for cache file ( 0 = No read , no save of cache , - 1 = No read but save )
* @ param int $format 0 = Label of abscissa is a translated text , 1 = Label of abscissa is month number , 2 = Label of abscissa is first letter of month
* @ param int $startmonth month of the fiscal year start min 1 max 12 ; if 1 = january
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int } > Array of values
2008-09-07 23:36:42 +02:00
*/
2019-08-03 06:04:42 +02:00
public function getNbByMonthWithPrevYear ( $endyear , $startyear , $cachedelay = 0 , $format = 0 , $startmonth = 1 )
2008-09-07 23:36:42 +02:00
{
2020-03-12 12:45:44 +01:00
global $conf , $user , $langs ;
2013-06-29 02:23:23 +02:00
2021-02-23 22:03:23 +01:00
if ( $startyear > $endyear ) {
2023-01-06 19:34:45 +01:00
return array ();
2021-02-23 22:03:23 +01:00
}
2011-05-25 20:16:58 +02:00
2024-03-20 19:53:22 +01:00
$data = array (); // This is the return value
$datay = array (); // This is a work value
2013-06-29 02:23:23 +02:00
// Search into cache
2021-02-23 22:03:23 +01:00
if ( ! empty ( $cachedelay )) {
2020-10-31 14:32:18 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
}
2010-06-08 01:52:43 +02:00
2020-03-12 12:45:44 +01:00
$newpathofdestfile = $conf -> user -> dir_temp . '/' . get_class ( $this ) . '_' . __FUNCTION__ . '_' . ( empty ( $this -> cachefilesuffix ) ? '' : $this -> cachefilesuffix . '_' ) . $langs -> defaultlang . '_entity.' . $conf -> entity . '_user' . $user -> id . '.cache' ;
$newmask = '0644' ;
2013-07-01 12:00:42 +02:00
$nowgmt = dol_now ();
2020-03-12 12:45:44 +01:00
$foundintocache = 0 ;
2024-10-29 22:44:47 +01:00
$filedate = - 1 ;
2021-02-23 22:03:23 +01:00
if ( $cachedelay > 0 ) {
2020-03-12 12:45:44 +01:00
$filedate = dol_filemtime ( $newpathofdestfile );
2021-02-23 22:03:23 +01:00
if ( $filedate >= ( $nowgmt - $cachedelay )) {
2020-03-12 12:45:44 +01:00
$foundintocache = 1 ;
2013-07-01 12:00:42 +02:00
2020-03-12 12:45:44 +01:00
$this -> lastfetchdate [ get_class ( $this ) . '_' . __FUNCTION__ ] = $filedate ;
2020-05-21 15:05:19 +02:00
} else {
2013-08-05 17:19:49 +02:00
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. " );
2013-07-01 12:00:42 +02:00
}
}
// Load file into $data
2021-02-23 22:03:23 +01:00
if ( $foundintocache ) { // Cache file found and is not too old
2013-08-05 17:19:49 +02:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ . " read data from cache file " . $newpathofdestfile . " " . $filedate . " . " );
2014-07-30 15:47:19 +02:00
$data = json_decode ( file_get_contents ( $newpathofdestfile ), true );
2024-03-20 20:05:35 +01:00
'@phan-var-force array<int<0,11>,array{0:int<1,12>,1:int}> $data' ;
2020-05-21 15:05:19 +02:00
} else {
2020-03-12 12:45:44 +01:00
$year = $startyear ;
2019-08-03 06:04:42 +02:00
$sm = $startmonth - 1 ;
2021-02-23 22:03:23 +01:00
if ( $sm != 0 ) {
2024-08-07 02:53:45 +02:00
$year -= 1 ;
2021-02-23 22:03:23 +01:00
}
while ( $year <= $endyear ) {
2022-06-15 11:10:31 +02:00
$datay [ $year ] = $this -> getNbByMonth ( $year , $format );
2008-09-07 23:36:42 +02:00
$year ++ ;
}
2013-06-29 02:23:23 +02:00
2021-02-23 22:03:23 +01:00
for ( $i = 0 ; $i < 12 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$data [ $i ][] = $datay [ $endyear ][( $i + $sm ) % 12 ][ 0 ];
$year = $startyear ;
2021-02-23 22:03:23 +01:00
while ( $year <= $endyear ) {
2022-10-10 20:14:51 +02:00
// floor(($i + $sm) / 12)) is 0 if we are after the month start $sm and same year, become 1 when we reach january of next year
2024-03-20 19:53:22 +01:00
$data [ $i ][] = $datay [ $year - ( 1 - ( int ) floor (( $i + $sm ) / 12 )) + ( $sm == 0 ? 1 : 0 )][( $i + $sm ) % 12 ][ 1 ];
2013-06-28 19:19:18 +02:00
$year ++ ;
}
}
2008-09-07 23:36:42 +02:00
}
2010-06-08 01:52:43 +02:00
2024-03-20 19:53:22 +01:00
2013-06-28 19:19:18 +02:00
// Save cache file
2021-02-23 22:03:23 +01:00
if ( empty ( $foundintocache ) && ( $cachedelay > 0 || $cachedelay == - 1 )) {
2013-08-05 17:19:49 +02:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ . " save cache file " . $newpathofdestfile . " onto disk. " );
2021-02-23 22:03:23 +01:00
if ( ! dol_is_dir ( $conf -> user -> dir_temp )) {
dol_mkdir ( $conf -> user -> dir_temp );
}
2024-03-27 13:33:22 +01:00
$fp = @ fopen ( $newpathofdestfile , 'w' );
2024-03-26 18:31:59 +01:00
if ( $fp ) {
fwrite ( $fp , json_encode ( $data ));
fclose ( $fp );
} else {
2024-03-27 13:33:22 +01:00
dol_syslog ( " Failed to save cache file " . $newpathofdestfile , LOG_ERR );
2024-03-26 18:31:59 +01:00
}
2023-02-17 19:30:50 +01:00
dolChmod ( $newpathofdestfile );
2013-07-01 12:00:42 +02:00
2020-03-12 12:45:44 +01:00
$this -> lastfetchdate [ get_class ( $this ) . '_' . __FUNCTION__ ] = $nowgmt ;
2013-06-28 19:19:18 +02:00
}
2013-06-29 02:23:23 +02:00
2008-09-07 23:36:42 +02:00
return $data ;
}
2022-06-15 14:00:24 +02:00
/**
2024-03-20 19:53:22 +01:00
* @ param int $year year number
* @ param int $format 0 = Label of abscissa is a translated text , 1 = Label of abscissa is month number , 2 = Label of abscissa is first letter of month
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of values by month
2022-06-15 14:00:24 +02:00
*/
2023-12-04 12:04:36 +01:00
abstract protected function getAmountByMonth ( $year , $format = 0 );
2022-06-15 14:00:24 +02:00
2008-09-07 23:36:42 +02:00
/**
2015-07-09 12:29:01 +02:00
* Return amount of elements by month for several years .
2024-01-13 19:48:20 +01:00
* Criteria used to build request are defined into the constructor of parent class into xxx / class / xxxstats . class . php
2015-07-09 12:29:01 +02:00
* The caller of class can add more filters into sql request by adding criteris into the $stats -> where property just after
* calling constructor .
2008-09-07 23:36:42 +02:00
*
2012-02-21 00:18:48 +01:00
* @ param int $endyear Start year
* @ param int $startyear End year
2013-06-29 02:23:23 +02:00
* @ param int $cachedelay Delay we accept for cache file ( 0 = No read , no save of cache , - 1 = No read but save )
2020-10-31 14:32:18 +01:00
* @ param int $format 0 = Label of abscissa is a translated text , 1 = Label of abscissa is month number , 2 = Label of abscissa is first letter of month
2019-08-03 06:04:42 +02:00
* @ param int $startmonth month of the fiscal year start min 1 max 12 ; if 1 = january
2024-03-20 20:05:35 +01:00
* @ return array < int < 0 , 11 > , array < string | int | float >> Array of values
2008-09-07 23:36:42 +02:00
*/
2019-08-03 06:04:42 +02:00
public function getAmountByMonthWithPrevYear ( $endyear , $startyear , $cachedelay = 0 , $format = 0 , $startmonth = 1 )
2008-09-07 23:36:42 +02:00
{
2020-03-12 12:45:44 +01:00
global $conf , $user , $langs ;
2013-06-29 02:23:23 +02:00
2021-02-23 22:03:23 +01:00
if ( $startyear > $endyear ) {
2023-01-06 19:34:45 +01:00
return array ();
2021-02-23 22:03:23 +01:00
}
2020-10-31 14:32:18 +01:00
$datay = array ();
2024-03-20 20:05:35 +01:00
$data = array (); // Return value
2020-10-31 14:32:18 +01:00
// Search into cache
2021-02-23 22:03:23 +01:00
if ( ! empty ( $cachedelay )) {
2020-10-31 14:32:18 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
}
$newpathofdestfile = $conf -> user -> dir_temp . '/' . get_class ( $this ) . '_' . __FUNCTION__ . '_' . ( empty ( $this -> cachefilesuffix ) ? '' : $this -> cachefilesuffix . '_' ) . $langs -> defaultlang . '_entity.' . $conf -> entity . '_user' . $user -> id . '.cache' ;
$newmask = '0644' ;
$nowgmt = dol_now ();
$foundintocache = 0 ;
2024-10-29 22:44:47 +01:00
$filedate = - 1 ;
2021-02-23 22:03:23 +01:00
if ( $cachedelay > 0 ) {
2020-10-31 14:32:18 +01:00
$filedate = dol_filemtime ( $newpathofdestfile );
2021-02-23 22:03:23 +01:00
if ( $filedate >= ( $nowgmt - $cachedelay )) {
2020-10-31 14:32:18 +01:00
$foundintocache = 1 ;
$this -> lastfetchdate [ get_class ( $this ) . '_' . __FUNCTION__ ] = $filedate ;
} else {
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. " );
}
}
// Load file into $data
2021-02-23 22:03:23 +01:00
if ( $foundintocache ) { // Cache file found and is not too old
2020-10-31 14:32:18 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ . " read data from cache file " . $newpathofdestfile . " " . $filedate . " . " );
$data = json_decode ( file_get_contents ( $newpathofdestfile ), true );
} else {
2020-03-12 12:45:44 +01:00
$year = $startyear ;
2019-08-03 06:04:42 +02:00
$sm = $startmonth - 1 ;
2021-02-23 22:03:23 +01:00
if ( $sm != 0 ) {
2024-08-07 02:53:45 +02:00
$year -= 1 ;
2021-02-23 22:03:23 +01:00
}
while ( $year <= $endyear ) {
2017-12-08 16:15:41 +01:00
$datay [ $year ] = $this -> getAmountByMonth ( $year , $format );
2008-09-07 23:36:42 +02:00
$year ++ ;
}
2013-06-29 02:23:23 +02:00
2013-07-26 18:40:43 +02:00
// $data = array('xval'=>array(0=>xlabel,1=>yval1,2=>yval2...),...)
2021-02-23 22:03:23 +01:00
for ( $i = 0 ; $i < 12 ; $i ++ ) {
2020-03-28 13:38:25 +01:00
$data [ $i ][] = isset ( $datay [ $endyear ][( $i + $sm ) % 12 ][ 'label' ]) ? $datay [ $endyear ][( $i + $sm ) % 12 ][ 'label' ] : $datay [ $endyear ][( $i + $sm ) % 12 ][ 0 ]; // set label
2020-03-12 12:45:44 +01:00
$year = $startyear ;
2021-02-23 22:03:23 +01:00
while ( $year <= $endyear ) {
2022-10-10 20:14:51 +02:00
// floor(($i + $sm) / 12)) is 0 if we are after the month start $sm and same year, become 1 when we reach january of next year
2024-10-29 22:44:47 +01:00
$data [ $i ][] = $datay [ $year - ( 1 - ( int ) floor (( $i + $sm ) / 12 )) + ( $sm == 0 ? 1 : 0 )][( $i + $sm ) % 12 ][ 1 ]; // set yval for x=i
2013-06-29 02:23:23 +02:00
$year ++ ;
}
}
}
2013-07-01 12:00:42 +02:00
// Save cache file
2021-02-23 22:03:23 +01:00
if ( empty ( $foundintocache ) && ( $cachedelay > 0 || $cachedelay == - 1 )) {
2013-08-05 17:19:49 +02:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ . " save cache file " . $newpathofdestfile . " onto disk. " );
2021-02-23 22:03:23 +01:00
if ( ! dol_is_dir ( $conf -> user -> dir_temp )) {
dol_mkdir ( $conf -> user -> dir_temp );
}
2024-03-27 13:33:22 +01:00
$fp = @ fopen ( $newpathofdestfile , 'w' );
2021-02-23 22:03:23 +01:00
if ( $fp ) {
2015-04-03 15:25:24 +02:00
fwrite ( $fp , json_encode ( $data ));
fclose ( $fp );
2021-02-23 22:03:23 +01:00
} else {
2024-03-27 13:33:22 +01:00
dol_syslog ( " Failed to save cache file " . $newpathofdestfile , LOG_ERR );
2021-02-23 22:03:23 +01:00
}
2024-03-27 13:33:22 +01:00
dolChmod ( $newpathofdestfile );
2020-03-12 12:45:44 +01:00
$this -> lastfetchdate [ get_class ( $this ) . '_' . __FUNCTION__ ] = $nowgmt ;
2008-09-07 23:36:42 +02:00
}
return $data ;
}
2022-06-15 12:25:00 +02:00
/**
2024-03-20 20:05:35 +01:00
* @ param int $year year number
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of values
2022-06-15 12:25:00 +02:00
*/
2023-12-04 12:04:36 +01:00
abstract protected function getAverageByMonth ( $year );
2022-06-15 12:25:00 +02:00
2012-08-14 15:43:14 +02:00
/**
2024-03-20 20:05:35 +01:00
* Return average of entity by month for several years
2012-08-14 15:43:14 +02:00
*
2024-03-20 19:53:22 +01:00
* @ param int $endyear Start year
* @ param int $startyear End year
2024-03-20 20:05:35 +01:00
* @ return array < array < int | float >> Array of values
2012-08-14 15:43:14 +02:00
*/
2020-10-31 14:32:18 +01:00
public function getAverageByMonthWithPrevYear ( $endyear , $startyear )
{
2021-02-23 22:03:23 +01:00
if ( $startyear > $endyear ) {
2023-01-06 19:34:45 +01:00
return array ();
2021-02-23 22:03:23 +01:00
}
2012-08-14 15:43:14 +02:00
2020-10-31 14:32:18 +01:00
$datay = array ();
2024-03-20 20:05:35 +01:00
$data = array ();
2012-08-14 15:43:14 +02:00
2020-03-12 12:45:44 +01:00
$year = $startyear ;
2021-02-23 22:03:23 +01:00
while ( $year <= $endyear ) {
2012-08-14 15:43:14 +02:00
$datay [ $year ] = $this -> getAverageByMonth ( $year );
$year ++ ;
}
2021-02-23 22:03:23 +01:00
for ( $i = 0 ; $i < 12 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$data [ $i ][] = $datay [ $endyear ][ $i ][ 0 ];
$year = $startyear ;
2021-02-23 22:03:23 +01:00
while ( $year <= $endyear ) {
2020-03-12 12:45:44 +01:00
$data [ $i ][] = $datay [ $year ][ $i ][ 1 ];
2012-08-14 15:43:14 +02:00
$year ++ ;
}
}
return $data ;
}
2013-08-05 17:19:49 +02:00
/**
2024-03-20 19:53:22 +01:00
* Return count , and sum of products
2013-08-05 17:19:49 +02:00
*
2024-03-20 19:53:22 +01:00
* @ param int $year Year
* @ param int $cachedelay Delay we accept for cache file ( 0 = No read , no save of cache , - 1 = No read but save )
* @ param int $limit Limit
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of values
2013-08-05 17:19:49 +02:00
*/
2020-10-31 14:32:18 +01:00
public function getAllByProductEntry ( $year , $cachedelay = 0 , $limit = 10 )
{
global $conf , $user , $langs ;
$data = array ();
2024-03-20 19:53:22 +01:00
// Search in cache
2021-02-23 22:03:23 +01:00
if ( ! empty ( $cachedelay )) {
2020-10-31 14:32:18 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
}
$newpathofdestfile = $conf -> user -> dir_temp . '/' . get_class ( $this ) . '_' . __FUNCTION__ . '_' . ( empty ( $this -> cachefilesuffix ) ? '' : $this -> cachefilesuffix . '_' ) . $langs -> defaultlang . '_entity.' . $conf -> entity . '_user' . $user -> id . '.cache' ;
$newmask = '0644' ;
$nowgmt = dol_now ();
$foundintocache = 0 ;
2024-10-29 22:44:47 +01:00
$filedate = - 1 ;
2021-02-23 22:03:23 +01:00
if ( $cachedelay > 0 ) {
2020-10-31 14:32:18 +01:00
$filedate = dol_filemtime ( $newpathofdestfile );
2021-02-23 22:03:23 +01:00
if ( $filedate >= ( $nowgmt - $cachedelay )) {
2020-10-31 14:32:18 +01:00
$foundintocache = 1 ;
$this -> lastfetchdate [ get_class ( $this ) . '_' . __FUNCTION__ ] = $filedate ;
} else {
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. " );
}
}
// Load file into $data
2021-02-23 22:03:23 +01:00
if ( $foundintocache ) { // Cache file found and is not too old
2020-10-31 14:32:18 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ . " read data from cache file " . $newpathofdestfile . " " . $filedate . " . " );
$data = json_decode ( file_get_contents ( $newpathofdestfile ), true );
2024-03-20 20:05:35 +01:00
'@phan-var-force array<int<0,11>,array{0:int<1,12>,1:int|float}> $data' ; // Phan can't decode json_decode's return value
2020-10-31 14:32:18 +01:00
} else {
2020-03-06 12:45:02 +01:00
$data = $this -> getAllByProduct ( $year , $limit );
2013-08-05 17:19:49 +02:00
}
2008-09-07 23:36:42 +02:00
2013-08-05 17:19:49 +02:00
// Save cache file
2021-02-23 22:03:23 +01:00
if ( empty ( $foundintocache ) && ( $cachedelay > 0 || $cachedelay == - 1 )) {
2013-08-05 17:19:49 +02:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ . " save cache file " . $newpathofdestfile . " onto disk. " );
2021-02-23 22:03:23 +01:00
if ( ! dol_is_dir ( $conf -> user -> dir_temp )) {
dol_mkdir ( $conf -> user -> dir_temp );
}
2024-03-27 13:33:22 +01:00
$fp = @ fopen ( $newpathofdestfile , 'w' );
2021-02-23 22:03:23 +01:00
if ( $fp ) {
2015-04-03 15:25:24 +02:00
fwrite ( $fp , json_encode ( $data ));
fclose ( $fp );
2024-03-27 13:33:22 +01:00
} else {
dol_syslog ( " Failed to save cache file " . $newpathofdestfile , LOG_ERR );
2015-04-03 15:25:24 +02:00
}
2024-03-27 13:33:22 +01:00
dolChmod ( $newpathofdestfile );
2020-03-12 12:45:44 +01:00
$this -> lastfetchdate [ get_class ( $this ) . '_' . __FUNCTION__ ] = $nowgmt ;
2013-08-05 17:19:49 +02:00
}
return $data ;
2015-04-03 15:25:24 +02:00
}
2013-08-05 17:19:49 +02:00
// Here we have low level of shared code called by XxxStats.class.php
2015-04-03 15:25:24 +02:00
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
2011-05-25 20:16:58 +02:00
* Return nb of elements by year
2011-09-20 19:19:46 +02:00
*
2012-02-21 00:18:48 +01:00
* @ param string $sql SQL request
2024-09-12 21:16:42 +02:00
* @ return array < array { 0 : int , 1 : int } > Array of nb each year
2008-09-07 23:36:42 +02:00
*/
2020-10-31 14:32:18 +01:00
protected function _getNbByYear ( $sql )
{
// phpcs:enable
2008-09-07 23:36:42 +02:00
$result = array ();
2010-06-08 01:52:43 +02:00
2022-12-28 16:40:03 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ , LOG_DEBUG );
2020-03-12 12:45:44 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2008-09-07 23:36:42 +02:00
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
2008-09-07 23:36:42 +02:00
$row = $this -> db -> fetch_row ( $resql );
$result [ $i ] = $row ;
$i ++ ;
}
$this -> db -> free ( $resql );
2020-05-21 15:05:19 +02:00
} else {
2009-02-20 23:53:15 +01:00
dol_print_error ( $this -> db );
2008-09-07 23:36:42 +02:00
}
return $result ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2008-09-08 09:32:03 +02:00
/**
2011-12-28 13:25:05 +01:00
* Return nb of elements , total amount and avg amount each year
2011-09-20 19:19:46 +02:00
*
2012-02-21 00:18:48 +01:00
* @ param string $sql SQL request
2024-10-14 01:59:44 +02:00
* @ return array < array { year : string , nb : string , nb_diff : float , total ? : float , avg ? : float , weighted ? : float , total_diff ? : float , avg_diff ? : float , avg_weighted ? : float } > Array with nb , total amount , average for each year
2008-09-08 09:32:03 +02:00
*/
2019-02-26 22:42:19 +01:00
protected function _getAllByYear ( $sql )
2008-09-08 09:32:03 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2008-09-08 09:32:03 +02:00
$result = array ();
2010-06-08 01:52:43 +02:00
2022-12-28 16:40:03 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ , LOG_DEBUG );
2020-03-12 12:45:44 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2008-09-08 09:32:03 +02:00
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
2008-09-08 09:32:03 +02:00
$row = $this -> db -> fetch_object ( $resql );
$result [ $i ][ 'year' ] = $row -> year ;
$result [ $i ][ 'nb' ] = $row -> nb ;
2021-02-23 22:03:23 +01:00
if ( $i > 0 && $row -> nb > 0 ) {
$result [ $i - 1 ][ 'nb_diff' ] = ( $result [ $i - 1 ][ 'nb' ] - $row -> nb ) / $row -> nb * 100 ;
}
2023-07-12 15:02:34 +02:00
// For some $sql only
if ( property_exists ( $row , 'total' )) {
$result [ $i ][ 'total' ] = $row -> total ;
if ( $i > 0 && $row -> total > 0 ) {
$result [ $i - 1 ][ 'total_diff' ] = ( $result [ $i - 1 ][ 'total' ] - $row -> total ) / $row -> total * 100 ;
}
2021-02-23 22:03:23 +01:00
}
2023-07-12 15:02:34 +02:00
// For some $sql only
if ( property_exists ( $row , 'total' )) {
$result [ $i ][ 'avg' ] = $row -> avg ;
if ( $i > 0 && $row -> avg > 0 ) {
$result [ $i - 1 ][ 'avg_diff' ] = ( $result [ $i - 1 ][ 'avg' ] - $row -> avg ) / $row -> avg * 100 ;
}
2021-02-23 22:03:23 +01:00
}
2016-07-08 10:59:13 +02:00
// For some $sql only
2023-07-12 15:02:34 +02:00
if ( property_exists ( $row , 'weighted' )) {
2020-10-31 14:32:18 +01:00
$result [ $i ][ 'weighted' ] = $row -> weighted ;
2021-02-23 22:03:23 +01:00
if ( $i > 0 && $row -> weighted > 0 ) {
$result [ $i - 1 ][ 'avg_weighted' ] = ( $result [ $i - 1 ][ 'weighted' ] - $row -> weighted ) / $row -> weighted * 100 ;
}
2016-07-08 10:59:13 +02:00
}
2008-09-08 09:32:03 +02:00
$i ++ ;
}
$this -> db -> free ( $resql );
2020-05-21 15:05:19 +02:00
} else {
2009-02-20 23:53:15 +01:00
dol_print_error ( $this -> db );
2008-09-08 09:32:03 +02:00
}
return $result ;
2010-06-08 01:52:43 +02:00
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2008-09-07 23:36:42 +02:00
/**
2024-03-20 19:53:22 +01:00
* Renvoie le nombre de documents par mois pour une annee donnee
* Return number of documents per month for a given year
2011-09-20 19:19:46 +02:00
*
2024-08-15 16:57:02 +02:00
* @ param int $year Year
* @ param string $sql SQL
* @ param int < 0 , 2 > $format 0 = Label of abscissa is a translated text , 1 = Label of abscissa is month number , 2 = Label of abscissa is first letter of month
2024-03-20 19:53:22 +01:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int } > Array of nb each month
2020-10-31 14:32:18 +01:00
*/
protected function _getNbByMonth ( $year , $sql , $format = 0 )
{
// phpcs:enable
2017-12-08 16:15:41 +01:00
global $langs ;
2020-03-12 12:45:44 +01:00
$result = array ();
$res = array ();
2008-09-07 23:36:42 +02:00
2022-12-28 16:40:03 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ , LOG_DEBUG );
2020-03-12 12:45:44 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2008-09-07 23:36:42 +02:00
$num = $this -> db -> num_rows ( $resql );
2021-03-01 20:37:16 +01:00
$i = 0 ;
$j = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
2008-09-07 23:36:42 +02:00
$row = $this -> db -> fetch_row ( $resql );
$j = $row [ 0 ] * 1 ;
$result [ $j ] = $row [ 1 ];
$i ++ ;
}
$this -> db -> free ( $resql );
2020-05-21 15:05:19 +02:00
} else {
2009-02-20 23:53:15 +01:00
dol_print_error ( $this -> db );
2008-11-17 00:43:10 +01:00
}
2010-06-08 01:52:43 +02:00
2021-02-23 22:03:23 +01:00
for ( $i = 1 ; $i < 13 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$res [ $i ] = ( isset ( $result [ $i ]) ? $result [ $i ] : 0 );
2008-09-07 23:36:42 +02:00
}
$data = array ();
2021-02-23 22:03:23 +01:00
for ( $i = 1 ; $i < 13 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$month = 'unknown' ;
2021-02-23 22:03:23 +01:00
if ( $format == 0 ) {
$month = $langs -> transnoentitiesnoconv ( 'MonthShort' . sprintf ( " %02d " , $i ));
} elseif ( $format == 1 ) {
$month = $i ;
} elseif ( $format == 2 ) {
$month = $langs -> transnoentitiesnoconv ( 'MonthVeryShort' . sprintf ( " %02d " , $i ));
}
2017-12-08 16:15:41 +01:00
//$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
//$month=dol_substr($month,0,3);
2020-03-12 12:45:44 +01:00
$data [ $i - 1 ] = array ( $month , $res [ $i ]);
2008-09-07 23:36:42 +02:00
}
return $data ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2008-09-07 23:36:42 +02:00
/**
2024-03-20 19:53:22 +01:00
* Return the amount per month for a given year
2011-09-20 19:19:46 +02:00
*
2024-08-15 16:57:02 +02:00
* @ param int $year Year
* @ param string $sql SQL
* @ param int < 0 , 2 > $format 0 = Label of abscissa is a translated text , 1 = Label of abscissa is month number , 2 = Label of abscissa is first letter of month
2024-03-20 19:53:22 +01:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of nb each month
2008-09-07 23:36:42 +02:00
*/
2020-10-31 14:32:18 +01:00
protected function _getAmountByMonth ( $year , $sql , $format = 0 )
{
// phpcs:enable
2017-12-08 16:15:41 +01:00
global $langs ;
2020-03-12 12:45:44 +01:00
$result = array ();
$res = array ();
2008-09-07 23:36:42 +02:00
2022-12-28 16:40:03 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ , LOG_DEBUG );
2011-06-21 14:39:09 +02:00
2020-03-12 12:45:44 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2008-09-07 23:36:42 +02:00
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
$row = $this -> db -> fetch_row ( $resql );
$j = $row [ 0 ] * 1 ;
$result [ $j ] = $row [ 1 ];
$i ++ ;
}
$this -> db -> free ( $resql );
} else {
dol_print_error ( $this -> db );
}
for ( $i = 1 ; $i < 13 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$res [ $i ] = ( int ) round (( isset ( $result [ $i ]) ? $result [ $i ] : 0 ));
2008-09-07 23:36:42 +02:00
}
$data = array ();
2021-02-23 22:03:23 +01:00
for ( $i = 1 ; $i < 13 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$month = 'unknown' ;
2021-02-23 22:03:23 +01:00
if ( $format == 0 ) {
$month = $langs -> transnoentitiesnoconv ( 'MonthShort' . sprintf ( " %02d " , $i ));
} elseif ( $format == 1 ) {
$month = $i ;
} elseif ( $format == 2 ) {
$month = $langs -> transnoentitiesnoconv ( 'MonthVeryShort' . sprintf ( " %02d " , $i ));
}
2017-12-08 16:15:41 +01:00
//$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
//$month=dol_substr($month,0,3);
2020-03-12 12:45:44 +01:00
$data [ $i - 1 ] = array ( $month , $res [ $i ]);
2008-09-07 23:36:42 +02:00
}
return $data ;
2020-10-31 14:32:18 +01:00
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
* Return the amount average par month for a given year
*
2024-08-15 16:57:02 +02:00
* @ param int $year Year
* @ param string $sql SQL
* @ param int < 0 , 2 > $format 0 = Label of abscissa is a translated text , 1 = Label of abscissa is month number , 2 = Label of abscissa is first letter of month
2024-03-20 19:53:22 +01:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of average each month
2020-10-31 14:32:18 +01:00
*/
protected function _getAverageByMonth ( $year , $sql , $format = 0 )
{
// phpcs:enable
2017-12-08 16:15:41 +01:00
global $langs ;
2020-03-12 12:45:44 +01:00
$result = array ();
$res = array ();
2008-09-07 23:36:42 +02:00
2022-12-28 16:40:03 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ , LOG_DEBUG );
2020-03-12 12:45:44 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2008-09-07 23:36:42 +02:00
$num = $this -> db -> num_rows ( $resql );
2021-03-01 20:37:16 +01:00
$i = 0 ;
$j = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
$row = $this -> db -> fetch_row ( $resql );
$j = $row [ 0 ] * 1 ;
$result [ $j ] = $row [ 1 ];
$i ++ ;
}
$this -> db -> free ( $resql );
} else {
dol_print_error ( $this -> db );
}
for ( $i = 1 ; $i < 13 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$res [ $i ] = ( isset ( $result [ $i ]) ? $result [ $i ] : 0 );
2008-09-07 23:36:42 +02:00
}
2012-08-14 15:43:14 +02:00
$data = array ();
2021-02-23 22:03:23 +01:00
for ( $i = 1 ; $i < 13 ; $i ++ ) {
2020-03-12 12:45:44 +01:00
$month = 'unknown' ;
2021-02-23 22:03:23 +01:00
if ( $format == 0 ) {
$month = $langs -> transnoentitiesnoconv ( 'MonthShort' . sprintf ( " %02d " , $i ));
} elseif ( $format == 1 ) {
$month = $i ;
} elseif ( $format == 2 ) {
$month = $langs -> transnoentitiesnoconv ( 'MonthVeryShort' . sprintf ( " %02d " , $i ));
}
2017-12-08 16:15:41 +01:00
//$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b"));
//$month=dol_substr($month,0,3);
2020-03-12 12:45:44 +01:00
$data [ $i - 1 ] = array ( $month , $res [ $i ]);
2012-08-14 15:43:14 +02:00
}
return $data ;
2020-10-31 14:32:18 +01:00
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
/**
* Return number or total of product refs
*
* @ param string $sql SQL
* @ param int $limit Limit
2024-03-20 19:53:22 +01:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of total of product refs each month
2020-10-31 14:32:18 +01:00
*/
protected function _getAllByProduct ( $sql , $limit = 10 )
{
// phpcs:enable
2013-08-27 11:54:07 +02:00
global $langs ;
2015-04-03 15:25:24 +02:00
2020-03-12 12:45:44 +01:00
$result = array ();
2013-08-05 17:19:49 +02:00
2022-12-28 16:40:03 +01:00
dol_syslog ( get_class ( $this ) . '::' . __FUNCTION__ , LOG_DEBUG );
2020-03-12 12:45:44 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2013-08-05 17:19:49 +02:00
$num = $this -> db -> num_rows ( $resql );
2021-03-01 20:37:16 +01:00
$i = 0 ;
$other = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
2020-10-31 14:32:18 +01:00
$row = $this -> db -> fetch_row ( $resql );
2021-02-23 22:03:23 +01:00
if ( $i < $limit || $num == $limit ) {
$result [ $i ] = array ( $row [ 0 ], $row [ 1 ]); // Ref of product, nb
} else {
$other += $row [ 1 ];
}
$i ++ ;
2020-10-31 14:32:18 +01:00
}
2021-02-23 22:03:23 +01:00
if ( $num > $limit ) {
$result [ $i ] = array ( $langs -> transnoentitiesnoconv ( " Other " ), $other );
}
$this -> db -> free ( $resql );
} else {
dol_print_error ( $this -> db );
}
2013-08-05 17:19:49 +02:00
return $result ;
2020-10-31 14:32:18 +01:00
}
2021-09-20 19:41:13 +02:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
2021-09-20 19:57:10 +02:00
/**
2021-09-20 19:41:13 +02:00
* Returns the summed amounts per year for a given number of past years ending now
* @ param string $sql SQL
2024-03-20 19:53:22 +01:00
* @ return array < int , array { 0 : int , 1 : int } > Array of sum of amounts
2021-09-20 19:41:13 +02:00
*/
2021-09-20 23:58:38 +02:00
protected function _getAmountByYear ( $sql )
2021-09-20 19:41:13 +02:00
{
$result = array ();
$resql = $this -> db -> query ( $sql );
2021-09-20 19:57:10 +02:00
if ( $resql ) {
2021-09-20 19:41:13 +02:00
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-09-20 19:57:10 +02:00
while ( $i < $num ) {
2021-09-20 19:41:13 +02:00
$row = $this -> db -> fetch_row ( $resql );
$result [] = [
0 => ( int ) $row [ 0 ],
1 => ( int ) $row [ 1 ],
];
$i ++ ;
}
$this -> db -> free ( $resql );
}
return $result ;
}
2024-08-19 02:05:27 +02:00
/**
* Return nb , amount of predefined product for year
*
* @ param int $year Year to scan
* @ param int $limit Limit
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of values
*/
public function getAllByProduct ( $year , $limit = 0 )
{
// Needs to be implemented in child class when used
$msg = get_class ( $this ) . " :: " . __FUNCTION__ . " not implemented " ;
dol_syslog ( $msg , LOG_ERR );
$l = array ( 1 , 0 ); // Dummy result
return array ( $l , $l , $l , $l , $l , $l , $l , $l , $l , $l , $l , $l );
}
2007-05-31 20:55:47 +02:00
}