2011-06-21 14:39:09 +02:00
< ? php
/* Copyright ( C ) 2003 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
* Copyright ( c ) 2005 - 2011 Laurent Destailleur < eldy @ users . sourceforge . net >
2018-10-27 14:43:12 +02:00
* Copyright ( C ) 2005 - 2009 Regis Houssin < regis . houssin @ inodbox . com >
2023-05-14 16:57:44 +02:00
* Copyright ( C ) 2023 Waël Almoman < info @ almoman . com >
2024-03-20 14:10:45 +01:00
* Copyright ( C ) 2024 MDW < mdeweerd @ users . noreply . github . com >
2024-04-18 12:35:59 +02:00
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
2011-06-21 14:39:09 +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
2011-06-21 14:39:09 +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 />.
2011-06-21 14:39:09 +02:00
*/
/**
* \file htdocs / adherents / class / adherentstats . class . php
* \ingroup member
2024-01-12 20:58:09 +01:00
* \brief File for class managing statistics of members
2011-06-21 14:39:09 +02:00
*/
2020-04-10 10:59:32 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/class/stats.class.php' ;
include_once DOL_DOCUMENT_ROOT . '/adherents/class/subscription.class.php' ;
2011-06-21 14:39:09 +02:00
/**
2012-11-15 14:52:19 +01:00
* Class to manage statistics of members
2011-06-21 14:39:09 +02:00
*/
class AdherentStats extends Stats
{
2020-10-31 14:32:18 +01:00
/**
* @ var string Name of table without prefix where object is stored
*/
public $table_element ;
2011-06-21 14:39:09 +02:00
2024-08-10 23:21:46 +02:00
/**
* @ var int
*/
2020-10-31 14:32:18 +01:00
public $memberid ;
2024-08-10 23:21:46 +02:00
/**
* @ var int
*/
2020-10-31 14:32:18 +01:00
public $socid ;
2024-08-10 23:21:46 +02:00
/**
* @ var int
*/
2020-10-31 14:32:18 +01:00
public $userid ;
2011-06-21 14:39:09 +02:00
2024-08-10 23:21:46 +02:00
/**
* @ var string
*/
2020-10-31 14:32:18 +01:00
public $from ;
2024-08-10 23:21:46 +02:00
/**
* @ var string
*/
2020-10-31 14:32:18 +01:00
public $field ;
2024-08-10 23:21:46 +02:00
/**
* @ var string
*/
2020-10-31 14:32:18 +01:00
public $where ;
2011-06-21 14:39:09 +02:00
/**
2011-09-03 02:19:56 +02:00
* Constructor
2011-06-21 14:39:09 +02:00
*
2011-12-28 13:25:05 +01:00
* @ param DoliDB $db Database handler
* @ param int $socid Id third party
2020-10-31 14:32:18 +01:00
* @ param int $userid Id user for filter
2011-06-21 14:39:09 +02:00
*/
2019-02-25 00:56:48 +01:00
public function __construct ( $db , $socid = 0 , $userid = 0 )
2011-06-21 14:39:09 +02:00
{
2011-12-28 13:25:05 +01:00
$this -> db = $db ;
2020-10-31 14:32:18 +01:00
$this -> socid = $socid ;
$this -> userid = $userid ;
2011-06-21 14:39:09 +02:00
2020-04-10 10:59:32 +02:00
$object = new Subscription ( $this -> db );
2011-06-21 14:39:09 +02:00
$this -> from = MAIN_DB_PREFIX . $object -> table_element . " as p " ;
2020-04-10 10:59:32 +02:00
$this -> from .= " , " . MAIN_DB_PREFIX . " adherent as m " ;
2011-06-21 14:39:09 +02:00
2020-04-10 10:59:32 +02:00
$this -> field = 'subscription' ;
2011-06-21 14:39:09 +02:00
2020-09-14 02:38:12 +02:00
$this -> where .= " m.statut != -1 " ;
2020-04-10 10:59:32 +02:00
$this -> where .= " AND p.fk_adherent = m.rowid AND m.entity IN ( " . getEntity ( 'adherent' ) . " ) " ;
2020-05-21 09:12:18 +02:00
if ( $this -> memberid ) {
2021-03-30 17:53:25 +02:00
$this -> where .= " AND m.rowid = " . (( int ) $this -> memberid );
2011-06-21 14:39:09 +02:00
}
2022-01-03 18:15:19 +01:00
//if ($this->userid > 0) $this->where .= " AND fk_user_author = ".((int) $this->userid);
2011-06-21 14:39:09 +02:00
}
/**
2016-09-24 06:48:40 +02:00
* Return the number of proposition by month for a given year
2011-12-28 13:25:05 +01:00
*
2024-09-12 21:16:42 +02:00
* @ param int $year Year
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-09-12 21:16:42 +02:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int } > Array of nb each month
2011-06-21 14:39:09 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getNbByMonth ( $year , $format = 0 )
2011-06-21 14:39:09 +02:00
{
$sql = " SELECT date_format(p.dateadh,'%m') as dm, count(*) " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . $this -> from ;
2021-06-20 17:25:58 +02:00
$sql .= " WHERE " . dolSqlDateFilter ( 'p.dateadh' , 0 , 0 , ( int ) $year , 1 );
2020-04-10 10:59:32 +02:00
$sql .= " AND " . $this -> where ;
$sql .= " GROUP BY dm " ;
2020-10-31 14:32:18 +01:00
$sql .= $this -> db -> order ( 'dm' , 'DESC' );
2011-06-21 14:39:09 +02:00
2017-12-08 16:15:41 +01:00
return $this -> _getNbByMonth ( $year , $sql , $format );
2011-06-21 14:39:09 +02:00
}
/**
2016-09-24 06:48:40 +02:00
* Return the number of subscriptions by year
2011-06-21 14:39:09 +02:00
*
2024-09-12 21:16:42 +02:00
* @ return array < array { 0 : int , 1 : int } > Array of nb each year
2011-06-21 14:39:09 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getNbByYear ()
2011-06-21 14:39:09 +02:00
{
$sql = " SELECT date_format(p.dateadh,'%Y') as dm, count(*) " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . $this -> from ;
$sql .= " WHERE " . $this -> where ;
$sql .= " GROUP BY dm " ;
2020-10-31 14:32:18 +01:00
$sql .= $this -> db -> order ( 'dm' , 'DESC' );
2011-06-21 14:39:09 +02:00
return $this -> _getNbByYear ( $sql );
}
2011-12-28 13:25:05 +01:00
2011-06-21 14:39:09 +02:00
/**
2017-12-08 16:15:41 +01:00
* Return the number of subscriptions by month for a given year
2011-06-21 14:39:09 +02:00
*
2020-10-31 14:32:18 +01:00
* @ param int $year Year
* @ 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-09-12 21:16:42 +02:00
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of values by month
2011-06-21 14:39:09 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getAmountByMonth ( $year , $format = 0 )
2011-06-21 14:39:09 +02:00
{
$sql = " SELECT date_format(p.dateadh,'%m') as dm, sum(p. " . $this -> field . " ) " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . $this -> from ;
2021-06-20 17:25:58 +02:00
$sql .= " WHERE " . dolSqlDateFilter ( 'p.dateadh' , 0 , 0 , ( int ) $year , 1 );
2020-04-10 10:59:32 +02:00
$sql .= " AND " . $this -> where ;
$sql .= " GROUP BY dm " ;
2020-10-31 14:32:18 +01:00
$sql .= $this -> db -> order ( 'dm' , 'DESC' );
2011-06-21 14:39:09 +02:00
2017-12-08 16:15:41 +01:00
return $this -> _getAmountByMonth ( $year , $sql , $format );
2011-06-21 14:39:09 +02:00
}
2011-12-28 13:25:05 +01:00
2011-06-21 14:39:09 +02:00
/**
2011-12-28 13:25:05 +01:00
* Return average amount each month
2011-06-21 14:39:09 +02:00
*
2024-09-12 21:16:42 +02:00
* @ param int $year Year
* @ return array < int < 0 , 11 > , array { 0 : int < 1 , 12 > , 1 : int | float } > Array of average each month
2011-06-21 14:39:09 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getAverageByMonth ( $year )
2011-06-21 14:39:09 +02:00
{
$sql = " SELECT date_format(p.dateadh,'%m') as dm, avg(p. " . $this -> field . " ) " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . $this -> from ;
2021-06-20 17:25:58 +02:00
$sql .= " WHERE " . dolSqlDateFilter ( 'p.dateadh' , 0 , 0 , ( int ) $year , 1 );
2020-04-10 10:59:32 +02:00
$sql .= " AND " . $this -> where ;
$sql .= " GROUP BY dm " ;
2020-10-31 14:32:18 +01:00
$sql .= $this -> db -> order ( 'dm' , 'DESC' );
2011-06-21 14:39:09 +02:00
return $this -> _getAverageByMonth ( $year , $sql );
}
/**
2011-12-28 13:25:05 +01:00
* Return nb , total and average
*
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
2011-06-21 14:39:09 +02:00
*/
2019-02-25 00:56:48 +01:00
public function getAllByYear ()
2011-06-21 14:39:09 +02:00
{
$sql = " SELECT date_format(p.dateadh,'%Y') as year, count(*) as nb, sum( " . $this -> field . " ) as total, avg( " . $this -> field . " ) as avg " ;
2020-04-10 10:59:32 +02:00
$sql .= " FROM " . $this -> from ;
$sql .= " WHERE " . $this -> where ;
$sql .= " GROUP BY year " ;
2020-10-31 14:32:18 +01:00
$sql .= $this -> db -> order ( 'year' , 'DESC' );
2011-06-21 14:39:09 +02:00
return $this -> _getAllByYear ( $sql );
}
2022-12-20 18:38:01 +01:00
2023-05-14 15:59:23 +02:00
/**
* Return count of member by status group by adh type , total and average
*
2024-03-20 14:10:45 +01:00
* @ param int $numberYears Number of years to scan ( 0 = all )
2024-04-18 12:35:59 +02:00
* @ return array < int | string , array { label : string , members_draft : int , members_pending : int , members_uptodate : int , members_expired : int , members_excluded : int , members_resiliated : int , all ? : float | int , total_adhtype : float | int } > Array with total of draft , pending , uptodate , expired , resiliated for each member type
2023-05-14 15:59:23 +02:00
*/
2023-05-17 00:02:48 +02:00
public function countMembersByTypeAndStatus ( $numberYears = 0 )
2023-05-14 15:59:23 +02:00
{
global $user ;
$now = dol_now ();
2024-03-20 14:10:45 +01:00
$endYear = ( int ) date ( 'Y' );
2023-05-14 15:59:23 +02:00
$startYear = $endYear - $numberYears ;
$sql = " SELECT t.rowid as fk_adherent_type, t.libelle as label " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_DRAFT , " 'members_draft' " , 'NULL' ) . " ) as members_draft " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_VALIDATED . " AND (d.datefin IS NULL AND t.subscription = '1') " , " 'members_pending' " , 'NULL' ) . " ) as members_pending " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_VALIDATED . " AND (d.datefin >= ' " . $this -> db -> idate ( $now ) . " ' OR t.subscription = 0) " , " 'members_uptodate' " , 'NULL' ) . " ) as members_uptodate " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_VALIDATED . " AND (d.datefin < ' " . $this -> db -> idate ( $now ) . " ' AND t.subscription = 1) " , " 'members_expired' " , 'NULL' ) . " ) as members_expired " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_EXCLUDED , " 'members_excluded' " , 'NULL' ) . " ) as members_excluded " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_RESILIATED , " 'members_resiliated' " , 'NULL' ) . " ) as members_resiliated " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " adherent_type as t " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " adherent as d ON t.rowid = d.fk_adherent_type AND d.entity IN ( " . getEntity ( 'adherent' ) . " ) " ;
2023-05-17 00:02:48 +02:00
if ( $numberYears ) {
$sql .= " AND d.datefin > ' " . $this -> db -> idate ( dol_get_first_day ( $startYear )) . " ' " ;
}
2023-05-14 15:59:23 +02:00
$sql .= " WHERE t.entity IN ( " . getEntity ( 'member_type' ) . " ) " ;
$sql .= " AND t.statut = 1 " ;
2023-08-15 12:55:47 +02:00
$sql .= " GROUP BY t.rowid, t.libelle " ;
2022-12-20 18:38:01 +01:00
2023-05-14 15:59:23 +02:00
dol_syslog ( " box_members_by_type::select nb of members per type " , LOG_DEBUG );
$result = $this -> db -> query ( $sql );
2023-06-26 15:34:09 +02:00
$MembersCountArray = array ();
2023-05-14 15:59:23 +02:00
if ( $result ) {
$num = $this -> db -> num_rows ( $result );
$i = 0 ;
$totalstatus = array (
'members_draft' => 0 ,
'members_pending' => 0 ,
'members_uptodate' => 0 ,
'members_expired' => 0 ,
'members_excluded' => 0 ,
'members_resiliated' => 0
);
while ( $i < $num ) {
$objp = $this -> db -> fetch_object ( $result );
$MembersCountArray [ $objp -> fk_adherent_type ] = array (
'label' => $objp -> label ,
'members_draft' => ( int ) $objp -> members_draft ,
'members_pending' => ( int ) $objp -> members_pending ,
'members_uptodate' => ( int ) $objp -> members_uptodate ,
'members_expired' => ( int ) $objp -> members_expired ,
'members_excluded' => ( int ) $objp -> members_excluded ,
'members_resiliated' => ( int ) $objp -> members_resiliated
);
$totalrow = 0 ;
2024-03-20 14:10:45 +01:00
foreach ( $MembersCountArray [ $objp -> fk_adherent_type ] as $key => $nb ) {
2023-12-26 22:32:46 +01:00
if ( $key != 'label' ) {
2023-05-14 15:59:23 +02:00
$totalrow += $nb ;
$totalstatus [ $key ] += $nb ;
}
}
$MembersCountArray [ $objp -> fk_adherent_type ][ 'total_adhtype' ] = $totalrow ;
$i ++ ;
}
$this -> db -> free ( $result );
$MembersCountArray [ 'total' ] = $totalstatus ;
$MembersCountArray [ 'total' ][ 'all' ] = array_sum ( $totalstatus );
}
2023-06-26 15:34:09 +02:00
2023-05-14 15:59:23 +02:00
return $MembersCountArray ;
}
2023-05-17 00:02:48 +02:00
/**
* Return count of member by status group by adh type , total and average
*
2024-03-20 14:10:45 +01:00
* @ param int $numberYears Number of years to scan ( 0 = all )
* @ return array < string , array { label : string , members_draft : int , members_pending : 0 , members_uptodate : int , members_expired : int , members_excluded : int , members_resiliated : int , all ? : float | int , total_adhtag : float | int } > Array with total of draft , pending , uptodate , expired , resiliated for each member tag
2023-05-17 00:02:48 +02:00
*/
public function countMembersByTagAndStatus ( $numberYears = 0 )
{
global $user ;
$now = dol_now ();
2024-03-20 14:10:45 +01:00
$endYear = ( int ) date ( 'Y' );
2023-05-17 00:02:48 +02:00
$startYear = $endYear - $numberYears ;
2024-03-20 14:10:45 +01:00
$MembersCountArray = [];
2023-05-17 00:02:48 +02:00
$sql = " SELECT c.rowid as fk_categorie, c.label as label " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_DRAFT , " 'members_draft' " , 'NULL' ) . " ) as members_draft " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_VALIDATED . " AND (d.datefin IS NULL AND t.subscription = '1') " , " 'members_pending' " , 'NULL' ) . " ) as members_pending " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_VALIDATED . " AND (d.datefin >= ' " . $this -> db -> idate ( $now ) . " ' OR t.subscription = 0) " , " 'members_uptodate' " , 'NULL' ) . " ) as members_uptodate " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_VALIDATED . " AND (d.datefin < ' " . $this -> db -> idate ( $now ) . " ' AND t.subscription = 1) " , " 'members_expired' " , 'NULL' ) . " ) as members_expired " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_EXCLUDED , " 'members_excluded' " , 'NULL' ) . " ) as members_excluded " ;
$sql .= " , COUNT( " . $this -> db -> ifsql ( " d.statut = " . Adherent :: STATUS_RESILIATED , " 'members_resiliated' " , 'NULL' ) . " ) as members_resiliated " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " categorie as c " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " categorie_member as ct ON c.rowid = ct.fk_categorie " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " adherent as d ON d.rowid = ct.fk_member " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " adherent_type as t ON t.rowid = d.fk_adherent_type " ;
$sql .= " WHERE c.entity IN ( " . getEntity ( 'member_type' ) . " ) " ;
$sql .= " AND d.entity IN ( " . getEntity ( 'adherent' ) . " ) " ;
$sql .= " AND t.entity IN ( " . getEntity ( 'adherent' ) . " ) " ;
if ( $numberYears ) {
$sql .= " AND d.datefin > ' " . $this -> db -> idate ( dol_get_first_day ( $startYear )) . " ' " ;
}
$sql .= " AND c.fk_parent = 0 " ;
2023-08-15 12:55:47 +02:00
$sql .= " GROUP BY c.rowid, c.label " ;
$sql .= " ORDER BY label ASC " ;
2023-05-17 00:02:48 +02:00
2023-10-26 12:48:40 +02:00
dol_syslog ( " box_members_by_tag::select nb of members per tag " , LOG_DEBUG );
2023-05-17 00:02:48 +02:00
$result = $this -> db -> query ( $sql );
if ( $result ) {
$num = $this -> db -> num_rows ( $result );
$i = 0 ;
$totalstatus = array (
'members_draft' => 0 ,
'members_pending' => 0 ,
'members_uptodate' => 0 ,
'members_expired' => 0 ,
'members_excluded' => 0 ,
'members_resiliated' => 0
);
while ( $i < $num ) {
$objp = $this -> db -> fetch_object ( $result );
$MembersCountArray [ $objp -> fk_categorie ] = array (
'label' => $objp -> label ,
'members_draft' => ( int ) $objp -> members_draft ,
'members_pending' => ( int ) $objp -> members_pending ,
'members_uptodate' => ( int ) $objp -> members_uptodate ,
'members_expired' => ( int ) $objp -> members_expired ,
'members_excluded' => ( int ) $objp -> members_excluded ,
'members_resiliated' => ( int ) $objp -> members_resiliated
);
$totalrow = 0 ;
2024-03-20 14:10:45 +01:00
foreach ( $MembersCountArray [ $objp -> fk_categorie ] as $key => $nb ) {
2023-12-26 22:32:46 +01:00
if ( $key != 'label' ) {
2023-05-17 00:02:48 +02:00
$totalrow += $nb ;
$totalstatus [ $key ] += $nb ;
}
}
2023-05-21 18:18:12 +02:00
$MembersCountArray [ $objp -> fk_categorie ][ 'total_adhtag' ] = $totalrow ;
2023-05-17 00:02:48 +02:00
$i ++ ;
}
$this -> db -> free ( $result );
$MembersCountArray [ 'total' ] = $totalstatus ;
$MembersCountArray [ 'total' ][ 'all' ] = array_sum ( $totalstatus );
}
2024-04-18 12:35:59 +02:00
2023-05-17 00:02:48 +02:00
return $MembersCountArray ;
}
2011-06-21 14:39:09 +02:00
}