2017-06-02 19:28:22 +02:00
< ? php
2024-06-29 18:57:43 +02:00
/* Copyright ( C ) 2014 - 2015 Florian HENRY < florian . henry @ open - concept . pro >
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2025-02-10 21:20:09 +01:00
* Copyright ( C ) 2024 - 2025 MDW < mdeweerd @ users . noreply . github . com >
2017-06-02 19:28:22 +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
* the Free Software Foundation ; either version 3 of the License , or
* ( 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 />.
2017-06-02 19:28:22 +02:00
*/
2022-12-21 21:15:00 +01:00
2020-04-10 10:59:32 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php' ;
include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2017-06-02 19:28:22 +02:00
/**
* Class to manage statistics on project tasks
*/
class TaskStats extends Stats
{
2024-11-06 23:57:45 +01:00
/**
* @ var Project
*/
2024-06-29 18:57:43 +02:00
private $project ; // @phpstan-ignore-line
/**
* @ var int ID of User
*/
2017-06-02 19:28:22 +02:00
public $userid ;
2024-06-29 18:57:43 +02:00
/**
* @ var int ID of Societe
*/
2017-06-02 19:28:22 +02:00
public $socid ;
2023-08-25 18:10:50 +02:00
/**
* @ var int priority
*/
public $priority ;
2017-06-02 19:28:22 +02:00
2020-10-31 14:32:18 +01:00
/**
* Constructor of the class
*
2024-01-13 15:50:02 +01:00
* @ param DoliDB $db Database handler
2020-10-31 14:32:18 +01:00
*/
2019-02-24 23:32:09 +01:00
public function __construct ( $db )
2017-06-02 19:28:22 +02:00
{
$this -> db = $db ;
}
/**
* Return all tasks grouped by status .
*
* @ param int $limit Limit results
2024-11-06 23:57:45 +01:00
* @ return array < int , array { 0 : int | string , 1 : int } >| int <- 1 , - 1 > Array with value or - 1 if error
2017-06-02 19:28:22 +02:00
* @ throws Exception
*/
2019-02-24 23:32:09 +01:00
public function getAllTaskByStatus ( $limit = 5 )
2017-06-02 19:28:22 +02:00
{
2023-07-01 12:49:54 +02:00
global $user , $langs ;
2017-06-02 19:28:22 +02:00
$sql = " SELECT " ;
$sql .= " COUNT(t.rowid), t.priority " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . " projet_task as t INNER JOIN " . MAIN_DB_PREFIX . " projet as p ON p.rowid = t.fk_projet " ;
2024-01-09 13:08:22 +01:00
if ( ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . " societe_commerciaux as sc ON sc.fk_soc = p.fk_soc AND sc.fk_user = " . (( int ) $user -> id );
2021-02-26 18:49:22 +01:00
}
2017-06-02 19:28:22 +02:00
$sql .= $this -> buildWhere ();
//$sql .= " AND t.fk_statut <> 0"; // We want historic also, so all task not draft
$sql .= " GROUP BY t.priority " ;
2020-04-10 10:59:32 +02:00
$result = array ();
2017-06-02 19:28:22 +02:00
2022-12-28 16:40:03 +01:00
dol_syslog ( get_class ( $this ) . '::' . __METHOD__ , LOG_DEBUG );
2017-06-02 19:28:22 +02:00
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
$other = 0 ;
2020-04-10 10:59:32 +02:00
while ( $i < $num ) {
2017-06-02 19:28:22 +02:00
$row = $this -> db -> fetch_row ( $resql );
2021-02-26 18:49:22 +01:00
if ( $i < $limit || $num == $limit ) {
2017-06-02 19:28:22 +02:00
$result [ $i ] = array (
$row [ 1 ],
$row [ 0 ]
);
2021-02-26 18:49:22 +01:00
} else {
$other += $row [ 1 ];
}
2017-06-02 19:28:22 +02:00
$i ++ ;
}
2021-02-26 18:49:22 +01:00
if ( $num > $limit ) {
2020-04-10 10:59:32 +02:00
$result [ $i ] = array (
2017-06-02 19:28:22 +02:00
$langs -> transnoentitiesnoconv ( " Other " ),
$other
);
2021-02-26 18:49:22 +01:00
}
2017-06-02 19:28:22 +02:00
$this -> db -> free ( $resql );
} else {
2020-04-10 10:59:32 +02:00
$this -> error = " Error " . $this -> db -> lasterror ();
dol_syslog ( get_class ( $this ) . '::' . __METHOD__ . ' ' . $this -> error , LOG_ERR );
2017-06-02 19:28:22 +02:00
return - 1 ;
}
return $result ;
}
/**
* Return count , and sum of products
*
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 of values
2017-06-02 19:28:22 +02:00
*/
2019-02-24 23:32:09 +01:00
public function getAllByYear ()
2017-06-02 19:28:22 +02:00
{
2023-07-01 12:49:54 +02:00
global $user ;
2017-06-02 19:28:22 +02:00
$sql = " SELECT date_format(t.datec,'%Y') as year, COUNT(t.rowid) as nb " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . " projet_task as t INNER JOIN " . MAIN_DB_PREFIX . " projet as p ON p.rowid = t.fk_projet " ;
2024-01-09 13:08:22 +01:00
if ( ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . " societe_commerciaux as sc ON sc.fk_soc = p.fk_soc AND sc.fk_user = " . (( int ) $user -> id );
2021-02-26 18:49:22 +01:00
}
2020-04-10 10:59:32 +02:00
$sql .= $this -> buildWhere ();
$sql .= " GROUP BY year " ;
$sql .= $this -> db -> order ( 'year' , 'DESC' );
2017-06-02 19:28:22 +02:00
return $this -> _getAllByYear ( $sql );
}
/**
* Build the where part
*
* @ return string
*/
public function buildWhere ()
{
$sqlwhere_str = '' ;
$sqlwhere = array ();
2020-04-10 10:59:32 +02:00
$sqlwhere [] = ' t.entity IN (' . getEntity ( 'project' ) . ')' ;
2017-06-02 19:28:22 +02:00
2021-02-26 18:49:22 +01:00
if ( ! empty ( $this -> userid )) {
2021-08-28 03:09:18 +02:00
$sqlwhere [] = ' t.fk_user_resp = ' . (( int ) $this -> userid );
2021-02-26 18:49:22 +01:00
}
2024-01-12 17:55:52 +01:00
// Forced filter on socid is similar to forced filter on project. TODO Use project assignment to allow to not use filter on project
2021-02-26 18:49:22 +01:00
if ( ! empty ( $this -> socid )) {
2021-08-28 03:09:18 +02:00
$sqlwhere [] = ' p.fk_soc = ' . (( int ) $this -> socid ); // Link on thirdparty is on project, not on task
2021-02-26 18:49:22 +01:00
}
2023-07-01 12:49:54 +02:00
if ( ! empty ( $this -> year ) && empty ( $this -> month )) {
$sqlwhere [] = " t.datec BETWEEN ' " . $this -> db -> idate ( dol_get_first_day ( $this -> year , 1 )) . " ' AND ' " . $this -> db -> idate ( dol_get_last_day ( $this -> year , 12 )) . " ' " ;
2021-02-26 18:49:22 +01:00
}
2023-07-01 12:49:54 +02:00
if ( ! empty ( $this -> year ) && ! empty ( $this -> month )) {
$sqlwhere [] = " t.datec BETWEEN ' " . $this -> db -> idate ( dol_get_first_day ( $this -> year , $this -> month )) . " ' AND ' " . $this -> db -> idate ( dol_get_last_day ( $this -> year , $this -> month )) . " ' " ;
2021-02-26 18:49:22 +01:00
}
2021-03-22 11:30:18 +01:00
if ( ! empty ( $this -> priority )) {
2025-02-10 21:20:09 +01:00
$sqlwhere [] = " t.priority IN ( " . $this -> db -> sanitize (( string ) $this -> priority , 1 ) . " ) " ;
2021-02-26 18:49:22 +01:00
}
2017-06-02 19:28:22 +02:00
if ( count ( $sqlwhere ) > 0 ) {
2020-04-10 10:59:32 +02:00
$sqlwhere_str = ' WHERE ' . implode ( ' AND ' , $sqlwhere );
2017-06-02 19:28:22 +02:00
}
return $sqlwhere_str ;
}
/**
* Return Task number by month for a year
*
2017-12-08 16:15:41 +01:00
* @ param int $year Year to scan
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
2024-10-14 01:59:44 +02:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int } > Array with number by month
2017-06-02 19:28:22 +02:00
*/
2019-02-24 23:32:09 +01:00
public function getNbByMonth ( $year , $format = 0 )
2017-06-02 19:28:22 +02:00
{
global $user ;
2023-07-01 12:49:54 +02:00
$this -> year = $year ;
2017-06-02 19:28:22 +02:00
$sql = " SELECT date_format(t.datec,'%m') as dm, COUNT(t.rowid) as nb " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . " projet_task as t INNER JOIN " . MAIN_DB_PREFIX . " projet as p ON p.rowid = t.fk_projet " ;
2024-01-09 13:08:22 +01:00
if ( ! $user -> hasRight ( 'societe' , 'client' , 'voir' )) {
2021-08-24 15:15:38 +02:00
$sql .= " INNER JOIN " . MAIN_DB_PREFIX . " societe_commerciaux as sc ON sc.fk_soc=p.fk_soc AND sc.fk_user= " . (( int ) $user -> id );
2021-02-26 18:49:22 +01:00
}
2017-06-02 19:28:22 +02:00
$sql .= $this -> buildWhere ();
$sql .= " GROUP BY dm " ;
$sql .= $this -> db -> order ( 'dm' , 'DESC' );
2017-12-08 16:15:41 +01:00
$res = $this -> _getNbByMonth ( $year , $sql , $format );
2017-06-02 19:28:22 +02:00
// var_dump($res);print '<br>';
return $res ;
}
2022-11-19 15:34:24 +01:00
2022-12-14 10:31:11 +01:00
/**
2022-11-19 15:34:24 +01:00
* Return the Task amount by month for a year
*
* @ param int $year Year to scan
* @ 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
2024-10-14 01:59:44 +02:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of values
2022-11-19 15:34:24 +01:00
*/
public function getAmountByMonth ( $year , $format = 0 )
{
// Return an empty array at the moment because task has no amount
return array ();
}
2022-12-14 10:31:11 +01:00
/**
2022-11-19 15:34:24 +01:00
* Return average of entity by month
* @ param int $year year number
2024-11-06 23:57:45 +01:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of average each month
2022-11-19 15:34:24 +01:00
*/
protected function getAverageByMonth ( $year )
{
$sql = " SELECT date_format(datef,'%m') as dm, AVG(f. " . $this -> field . " ) " ;
$sql .= " FROM " . $this -> from ;
$sql .= " WHERE f.datef BETWEEN ' " . $this -> db -> idate ( dol_get_first_day ( $year )) . " ' AND ' " . $this -> db -> idate ( dol_get_last_day ( $year )) . " ' " ;
$sql .= " AND " . $this -> where ;
$sql .= " GROUP BY dm " ;
$sql .= $this -> db -> order ( 'dm' , 'DESC' );
return $this -> _getAverageByMonth ( $year , $sql );
}
2017-06-02 19:28:22 +02:00
}