2014-08-27 05:03:42 +00:00
< ? php
2025-10-17 00:31:07 +00:00
/* Copyright ( C ) 2013 - 2014 Olivier Geffroy < jeff @ jeffinfo . com >
2026-02-24 16:50:20 +00:00
* Copyright ( C ) 2013 - 2026 Alexandre Spangaro < alexandre @ inovea - conseil . com >
2025-10-17 00:31:07 +00:00
* Copyright ( C ) 2014 Florian Henry < florian . henry @ open - concept . pro >
* Copyright ( C ) 2019 Eric Seigne < eric . seigne @ cap - rel . fr >
2026-02-04 13:49:13 +00:00
* Copyright ( C ) 2021 - 2026 Frédéric France < frederic . france @ free . fr >
2024-09-28 09:14:59 +00:00
* Copyright ( C ) 2024 MDW < mdeweerd @ users . noreply . github . com >
2014-08-27 05:03:42 +00: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 19:55:30 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2014-08-27 05:03:42 +00:00
*/
/**
2016-04-03 13:32:46 +00:00
* \file htdocs / core / lib / accounting . lib . php
2019-06-18 20:38:52 +00:00
* \ingroup Accountancy ( Double entries )
2016-04-03 13:32:46 +00:00
* \brief Library of accountancy functions
2014-08-27 05:03:42 +00:00
*/
2019-06-20 11:39:29 +00:00
2019-06-20 11:59:53 +00:00
/**
* Check if a value is empty with some options
*
2019-06-20 16:24:43 +00:00
* @ author Michael - https :// www . php . net / manual / fr / function . empty . php #90767
2024-08-01 10:59:45 +00:00
* @ param ? mixed $var Value to test
2024-01-18 21:43:17 +00:00
* @ param boolean $allow_false Setting this to true will make the function consider a boolean value of false as NOT empty . This parameter is false by default .
* @ param boolean $allow_ws Setting this to true will make the function consider a string with nothing but white space as NOT empty . This parameter is false by default .
2019-06-20 11:59:53 +00:00
* @ return boolean True of False
*/
2019-06-20 11:39:29 +00:00
function is_empty ( $var , $allow_false = false , $allow_ws = false )
{
2024-08-07 01:05:02 +00:00
if ( is_null ( $var ) || ! isset ( $var ) || ( $allow_ws == false && trim ( $var ) == " " && ! is_bool ( $var )) || ( $allow_false === false && $var === false ) || ( is_array ( $var ) && empty ( $var ))) {
2019-06-20 11:39:29 +00:00
return true ;
2019-06-17 16:28:11 +00:00
}
2019-06-20 11:39:29 +00:00
return false ;
}
2019-06-17 16:28:11 +00:00
2014-08-27 05:03:42 +00:00
/**
2014-08-30 03:44:12 +00:00
* Prepare array with list of tabs
2014-08-27 05:03:42 +00:00
*
2015-02-10 09:25:59 +00:00
* @ param AccountingAccount $object Accounting account
2024-09-22 22:37:30 +00:00
* @ return array < array { 0 : string , 1 : string , 2 : string } > Array of tabs to show
2014-08-27 05:03:42 +00:00
*/
2015-02-10 09:25:59 +00:00
function accounting_prepare_head ( AccountingAccount $object )
2014-08-30 03:44:12 +00:00
{
2014-08-27 05:03:42 +00:00
global $langs , $conf ;
2014-11-15 14:19:37 +00:00
2014-08-27 05:03:42 +00:00
$h = 0 ;
2020-04-10 08:59:32 +00:00
$head = array ();
2014-11-15 14:19:37 +00:00
2025-10-17 00:31:07 +00:00
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/accountancy/admin/card.php' , [ 'id' => $object -> id ]);
2020-09-08 02:58:42 +00:00
$head [ $h ][ 1 ] = $langs -> trans ( " AccountAccounting " );
2014-08-27 05:03:42 +00:00
$head [ $h ][ 2 ] = 'card' ;
2020-04-10 08:59:32 +00:00
$h ++ ;
2014-11-15 14:19:37 +00:00
2014-08-27 05:03:42 +00:00
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
// $this->tabs = array('entity:-tabname); to remove a tab
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'accounting_account' );
2014-11-15 14:19:37 +00:00
2014-08-27 05:03:42 +00:00
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'accounting_account' , 'remove' );
2014-11-15 14:19:37 +00:00
2014-08-27 05:03:42 +00:00
return $head ;
}
2025-10-17 01:46:20 +00:00
/**
* Prepare array with list of tabs for accounting transaction
*
* @ param BookKeeping $object Bookkeeping
* @ param string $mode Mode _tmp if operation are drafted
* @ param string $type Type of list " sub " ( for subsidiary list ) or not
* @ param string $backtopage Back to page ( return on ledger by default )
* @ return array < array { 0 : string , 1 : string , 2 : string } > Array of tabs to show
*/
function accounting_transaction_prepare_head ( BookKeeping $object , $mode = '' , $type = '' , $backtopage = '/accountancy/bookkeeping/listbyaccount.php' )
{
global $langs , $conf ;
$h = 0 ;
$head = array ();
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/accountancy/bookkeeping/card.php' , [ 'piece_num' => $object -> piece_num , 'mode' => $mode , 'type' => $type , 'backtopage' => $backtopage ]);
$head [ $h ][ 1 ] = $langs -> trans ( " Transaction " );
$head [ $h ][ 2 ] = 'transaction' ;
$h ++ ;
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
// $this->tabs = array('entity:-tabname); to remove a tab
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'accounting_transaction' );
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'accounting_transaction' , 'remove' );
return $head ;
}
2026-02-24 16:50:20 +00:00
/**
* Prepare array with list of tabs for accounting transaction template
*
* @ param BookkeepingTemplate $object Bookkeeping template
* @ return array < array { 0 : string , 1 : string , 2 : string } > Array of tabs to show
*/
function accountingTransactionTemplatePrepareHead ( BookkeepingTemplate $object )
{
global $langs , $conf ;
$h = 0 ;
$head = array ();
$head [ $h ][ 0 ] = dolBuildUrl ( DOL_URL_ROOT . '/accountancy/admin/template/card.php' , [ 'id' => $object -> id ]);
$head [ $h ][ 1 ] = $langs -> trans ( " BookkeepingTemplate " );
$head [ $h ][ 2 ] = 'card' ;
$h ++ ;
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'accounting_template_transaction' );
complete_head_from_modules ( $conf , $langs , $object , $head , $h , 'accounting_template_transaction' , 'remove' );
return $head ;
}
2015-12-14 20:38:30 +00:00
/**
* Return accounting account without zero on the right
*
* @ param string $account Accounting account
* @ return string String without zero on the right
*/
function clean_account ( $account )
{
2019-01-27 10:55:16 +00:00
$account = rtrim ( $account , " 0 " );
2017-05-25 03:32:13 +00:00
2015-12-15 19:48:06 +00:00
return $account ;
2015-12-14 20:38:30 +00:00
}
2014-08-27 05:03:42 +00:00
/**
2016-10-14 11:05:01 +00:00
* Return General accounting account with defined length ( used for product and miscellaneous )
2014-08-27 05:03:42 +00:00
*
2014-08-30 04:05:02 +00:00
* @ param string $account General accounting account
2014-11-15 14:19:37 +00:00
* @ return string String with defined length
2014-08-27 05:03:42 +00:00
*/
2014-08-30 03:44:12 +00:00
function length_accountg ( $account )
{
2021-02-23 21:03:23 +00:00
if ( $account < 0 || is_empty ( $account )) {
return '' ;
}
2017-05-25 03:32:13 +00:00
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'ACCOUNTING_MANAGE_ZERO' )) {
2021-02-23 21:03:23 +00:00
return $account ;
}
2017-05-25 03:32:13 +00:00
2021-10-20 10:37:49 +00:00
$g = getDolGlobalInt ( 'ACCOUNTING_LENGTH_GACCOUNT' );
2020-04-10 08:59:32 +00:00
if ( ! is_empty ( $g )) {
2014-08-27 05:03:42 +00:00
// Clean parameters
$i = strlen ( $account );
2014-11-15 14:19:37 +00:00
2016-04-03 13:32:46 +00:00
if ( $i >= 1 ) {
2020-04-10 08:59:32 +00:00
while ( $i < $g ) {
2014-08-27 05:03:42 +00:00
$account .= '0' ;
2020-04-10 08:59:32 +00:00
$i ++ ;
2014-08-27 05:03:42 +00:00
}
2014-11-15 14:19:37 +00:00
2014-08-27 05:03:42 +00:00
return $account ;
} else {
return $account ;
}
} else {
return $account ;
}
}
/**
2016-10-14 11:05:01 +00:00
* Return Auxiliary accounting account of thirdparties with defined length
2014-08-27 05:03:42 +00:00
*
2014-08-30 04:05:02 +00:00
* @ param string $accounta Auxiliary accounting account
2014-11-15 14:19:37 +00:00
* @ return string String with defined length
2014-08-27 05:03:42 +00:00
*/
2014-08-30 03:44:12 +00:00
function length_accounta ( $accounta )
{
2019-04-23 08:24:16 +00:00
global $conf ;
2014-11-15 14:19:37 +00:00
2021-02-23 21:03:23 +00:00
if ( $accounta < 0 || is_empty ( $accounta )) {
return '' ;
}
2017-05-25 03:32:13 +00:00
2023-11-27 10:39:32 +00:00
if ( getDolGlobalString ( 'ACCOUNTING_MANAGE_ZERO' )) {
2021-02-23 21:03:23 +00:00
return $accounta ;
}
2017-05-25 03:32:13 +00:00
2021-10-20 10:37:49 +00:00
$a = getDolGlobalInt ( 'ACCOUNTING_LENGTH_AACCOUNT' );
2020-04-10 08:59:32 +00:00
if ( ! is_empty ( $a )) {
2014-08-27 05:03:42 +00:00
// Clean parameters
$i = strlen ( $accounta );
2014-11-15 14:19:37 +00:00
2016-04-03 13:32:46 +00:00
if ( $i >= 1 ) {
2020-04-10 08:59:32 +00:00
while ( $i < $a ) {
2014-08-27 05:03:42 +00:00
$accounta .= '0' ;
2020-04-10 08:59:32 +00:00
$i ++ ;
2014-08-27 05:03:42 +00:00
}
2014-11-15 14:19:37 +00:00
2014-08-27 05:03:42 +00:00
return $accounta ;
} else {
return $accounta ;
}
} else {
return $accounta ;
}
}
2017-04-29 12:53:29 +00:00
2025-10-14 18:57:01 +00:00
/**
* Check if a general accounting account allows the use of an auxiliary account .
*
* @ param DoliDB $db Database handler
* @ param string $general_account The general account number ( optional if $general_account_id is used )
* @ param string $auxiliary_account The auxiliary account number
* @ param int $general_account_id Optional rowid of the general accounting account
* @ return bool True if the auxiliary account is allowed , false otherwise
*/
function checkGeneralAccountAllowsAuxiliary ( $db , $general_account , $auxiliary_account , $general_account_id = 0 )
{
global $conf ;
if ( empty ( $auxiliary_account )) return true ; // No check needed if no auxiliary account used
2017-04-29 12:53:29 +00:00
2025-10-14 18:57:01 +00:00
// Build SQL to get general account info based on rowid or account number
$sql = " SELECT rowid, account_number, centralized " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " accounting_account " ;
$sql .= " WHERE " ;
if ( $general_account_id > 0 ) {
$sql .= " rowid = " . (( int ) $general_account_id );
} else {
$sql .= " account_number = ' " . $db -> escape ( $general_account ) . " ' " ;
}
$sql .= " AND entity = " . (( int ) $conf -> entity );
$sql .= " AND fk_pcg_version IN (SELECT pcg_version FROM " . MAIN_DB_PREFIX . " accounting_system WHERE rowid = " . (( int ) getDolGlobalInt ( 'CHARTOFACCOUNTS' )) . " ) " ;
$resql = $db -> query ( $sql );
if ( $resql ) {
$obj = $db -> fetch_object ( $resql );
if ( $obj && empty ( $obj -> centralized )) {
// Not a centralized account -> not allowed to use auxiliary
return false ;
}
}
return true ;
}
2017-04-29 12:53:29 +00:00
/**
2019-08-28 08:22:40 +00:00
* Show header of a page used to transfer / dispatch data in accounting
2017-04-29 12:53:29 +00:00
*
* @ param string $nom Name of report
2024-02-09 14:58:49 +00:00
* @ param string $variant Link for alternate report
2017-04-29 12:53:29 +00:00
* @ param string $period Period of report
* @ param string $periodlink Link to switch period
* @ param string $description Description
2019-03-11 00:01:15 +00:00
* @ param integer $builddate Date of generation
2017-04-29 12:53:29 +00:00
* @ param string $exportlink Link for export or ''
2024-11-04 11:32:13 +00:00
* @ param array < string , mixed > $moreparam Array with list of params to add into hidden fields of form
2017-04-29 12:53:29 +00:00
* @ param string $calcmode Calculation mode
* @ param string $varlink Add a variable into the address of the page
2024-11-04 11:32:13 +00:00
* @ param array < string , mixed > $moreoptions Array with list of params to add to table
2017-04-29 12:53:29 +00:00
* @ return void
*/
2024-04-20 22:12:32 +00:00
function journalHead ( $nom , $variant , $period , $periodlink , $description , $builddate , $exportlink = '' , $moreparam = array (), $calcmode = '' , $varlink = '' , $moreoptions = array ())
2017-04-29 12:53:29 +00:00
{
2020-09-08 19:27:28 +00:00
global $langs ;
print " \n \n <!-- start banner journal --> \n " ;
2021-02-23 21:03:23 +00:00
if ( ! is_empty ( $varlink )) {
$varlink = '?' . $varlink ;
}
2020-09-08 19:27:28 +00:00
$head = array ();
$h = 0 ;
$head [ $h ][ 0 ] = $_SERVER [ " PHP_SELF " ] . $varlink ;
$head [ $h ][ 1 ] = $langs -> trans ( " Journalization " );
$head [ $h ][ 2 ] = 'journal' ;
print '<form method="POST" action="' . $_SERVER [ " PHP_SELF " ] . $varlink . '">' ;
print '<input type="hidden" name="token" value="' . newToken () . '">' ;
2020-10-22 20:50:03 +00:00
print dol_get_fiche_head ( $head , 'journal' );
2020-09-08 19:27:28 +00:00
2021-02-23 21:03:23 +00:00
foreach ( $moreparam as $key => $value ) {
2020-09-08 19:27:28 +00:00
print '<input type="hidden" name="' . $key . '" value="' . $value . '">' ;
}
2021-02-28 10:48:35 +00:00
print '<table class="border centpercent tableforfield">' ;
2020-09-08 19:27:28 +00:00
2026-02-04 13:49:13 +00:00
// Title
2020-09-08 19:27:28 +00:00
print '<tr>' ;
2021-02-28 10:48:35 +00:00
print '<td class="titlefieldcreate">' . $langs -> trans ( " Name " ) . '</td>' ;
2020-09-08 19:27:28 +00:00
print '<td colspan="3">' ;
print $nom ;
print '</td>' ;
print '</tr>' ;
// Calculation mode
2021-02-23 21:03:23 +00:00
if ( $calcmode ) {
2020-09-08 19:27:28 +00:00
print '<tr>' ;
2021-02-28 10:48:35 +00:00
print '<td>' . $langs -> trans ( " CalculationMode " ) . '</td>' ;
2024-02-09 14:58:49 +00:00
if ( ! $variant ) {
2021-02-23 21:03:23 +00:00
print '<td colspan="3">' ;
} else {
print '<td>' ;
}
2020-09-08 19:27:28 +00:00
print $calcmode ;
2024-02-09 14:58:49 +00:00
if ( $variant ) {
print '</td><td colspan="2">' . $variant ;
2021-02-23 21:03:23 +00:00
}
2020-09-08 19:27:28 +00:00
print '</td>' ;
print '</tr>' ;
}
2026-02-04 13:49:13 +00:00
// Period of report
2020-09-08 19:27:28 +00:00
print '<tr>' ;
print '<td>' . $langs -> trans ( " ReportPeriod " ) . '</td>' ;
2021-02-23 21:03:23 +00:00
if ( ! $periodlink ) {
print '<td colspan="3">' ;
} else {
print '<td>' ;
}
if ( $period ) {
print $period ;
}
if ( $periodlink ) {
print '</td><td colspan="2">' . $periodlink ;
}
2020-09-08 19:27:28 +00:00
print '</td>' ;
print '</tr>' ;
2026-02-04 13:49:13 +00:00
// Line description
2020-09-08 19:27:28 +00:00
print '<tr>' ;
print '<td>' . $langs -> trans ( " ReportDescription " ) . '</td>' ;
print '<td colspan="3">' . $description . '</td>' ;
print '</tr>' ;
2024-04-20 22:12:32 +00:00
// more options
foreach ( $moreoptions as $key => $value ) {
print '<tr>' ;
print '<td>' . $langs -> trans ( $key ) . '</td>' ;
print '<td colspan="3">' . $value . '</td>' ;
print '</tr>' ;
}
2020-09-08 19:27:28 +00:00
print '</table>' ;
2020-10-27 17:19:31 +00:00
print dol_get_fiche_end ();
2020-09-08 19:27:28 +00:00
print '<div class="center"><input type="submit" class="button" name="submit" value="' . $langs -> trans ( " Refresh " ) . '"></div>' ;
print '</form>' ;
print " \n <!-- end banner journal --> \n \n " ;
2017-04-29 12:53:29 +00:00
}
2020-09-07 19:38:39 +00:00
/**
* Return Default dates for transfer based on periodicity option in accountancy setup
*
2024-11-04 11:32:13 +00:00
* @ return array { date_start : int , date_end : int , pastmonthyear : int , pastmonth : int } Dates of periodicity by default
2020-09-07 19:38:39 +00:00
*/
function getDefaultDatesForTransfer ()
{
2025-08-25 12:13:17 +00:00
global $db ;
2020-09-07 19:38:39 +00:00
2022-12-09 15:51:06 +00:00
$date_start = '' ;
$date_end = '' ;
2022-09-15 04:33:43 +00:00
$pastmonth = 0 ;
$pastmonthyear = 0 ;
2020-09-07 19:38:39 +00:00
// Period by default on transfer (0: previous month | 1: current month | 2: fiscal year)
2023-11-11 14:33:15 +00:00
$periodbydefaultontransfer = getDolGlobalInt ( 'ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER' , 0 );
2022-12-09 15:51:06 +00:00
if ( $periodbydefaultontransfer == 2 ) { // fiscal year
$sql = " SELECT date_start, date_end FROM " . MAIN_DB_PREFIX . " accounting_fiscalyear " ;
2021-04-01 02:37:47 +00:00
$sql .= " WHERE date_start < ' " . $db -> idate ( dol_now ()) . " ' AND date_end > ' " . $db -> idate ( dol_now ()) . " ' " ;
2020-09-07 19:38:39 +00:00
$sql .= $db -> plimit ( 1 );
$res = $db -> query ( $sql );
2025-01-15 19:01:40 +00:00
if ( $db -> num_rows ( $res ) > 0 ) {
2022-12-09 15:51:06 +00:00
$obj = $db -> fetch_object ( $res );
$date_start = $db -> jdate ( $obj -> date_start );
2025-11-06 16:25:18 +00:00
$date_end = dol_get_last_hour ( $db -> jdate ( $obj -> date_end ));
2020-09-07 19:38:39 +00:00
} else {
2022-12-09 15:51:06 +00:00
$month_start = getDolGlobalInt ( 'SOCIETE_FISCAL_MONTH_START' , 1 );
2024-08-15 14:57:02 +00:00
$year_start = ( int ) dol_print_date ( dol_now (), '%Y' );
if ( $month_start > ( int ) dol_print_date ( dol_now (), '%m' )) {
2024-08-07 00:53:45 +00:00
$year_start -= 1 ;
2021-04-01 02:37:47 +00:00
}
2020-09-07 19:38:39 +00:00
$year_end = $year_start + 1 ;
$month_end = $month_start - 1 ;
2021-02-23 21:03:23 +00:00
if ( $month_end < 1 ) {
2020-09-07 19:38:39 +00:00
$month_end = 12 ;
$year_end -- ;
}
$date_start = dol_mktime ( 0 , 0 , 0 , $month_start , 1 , $year_start );
2025-11-06 16:25:18 +00:00
$lastday = dol_get_last_day ( $year_end , $month_end );
$date_end = dol_mktime ( 23 , 59 , 59 , $month_end , ( int ) dol_print_date ( $lastday , '%d' ), $year_end );
2020-09-07 19:38:39 +00:00
}
2022-12-09 15:51:06 +00:00
} elseif ( $periodbydefaultontransfer == 1 ) { // current month
$year_current = ( int ) dol_print_date ( dol_now ( 'gmt' ), " %Y " , 'gmt' );
$pastmonth = ( int ) dol_print_date ( dol_now ( 'gmt' ), '%m' , 'gmt' );
2020-09-07 19:38:39 +00:00
$pastmonthyear = $year_current ;
if ( $pastmonth == 0 ) {
$pastmonth = 12 ;
2020-09-08 19:27:28 +00:00
$pastmonthyear -- ;
2020-09-07 19:38:39 +00:00
}
2022-12-09 15:51:06 +00:00
} else { // previous month
$year_current = ( int ) dol_print_date ( dol_now ( 'gmt' ), " %Y " , 'gmt' );
$pastmonth = ( int ) dol_print_date ( dol_now ( 'gmt' ), '%m' , 'gmt' ) - 1 ;
2020-09-07 19:38:39 +00:00
$pastmonthyear = $year_current ;
if ( $pastmonth == 0 ) {
$pastmonth = 12 ;
2020-09-08 19:27:28 +00:00
$pastmonthyear -- ;
2020-09-07 19:38:39 +00:00
}
}
return array (
'date_start' => $date_start ,
'date_end' => $date_end ,
'pastmonthyear' => $pastmonthyear ,
'pastmonth' => $pastmonth
);
}
2023-04-29 05:37:02 +00:00
/**
2024-10-26 18:03:22 +00:00
* Get current period of fiscal year ?
2023-04-29 05:37:02 +00:00
*
2024-10-26 18:03:22 +00:00
* @ param DoliDB $db Database handler
* @ param Conf $conf Config
2024-11-04 11:32:13 +00:00
* @ param ? int $from_time [ = null ] Get current time or set time to find fiscal period
* @ param 'tzserver' | 'gmt' $gm 'gmt' => we return GMT timestamp ( recommended ), 'tzserver' => we return in the PHP server timezone
2024-11-08 13:46:13 +00:00
* @ param int $withenddateonly Do not return period if end date is not defined
2024-11-04 11:32:13 +00:00
* @ return array { date_start : int , date_end : int } Period of fiscal year : [ date_start , date_end ]
2023-04-29 05:37:02 +00:00
*/
2024-10-26 18:03:22 +00:00
function getCurrentPeriodOfFiscalYear ( $db , $conf , $from_time = null , $gm = 'tzserver' , $withenddateonly = 1 )
2023-04-29 05:37:02 +00:00
{
$now = dol_now ();
$now_arr = dol_getdate ( $now );
if ( $from_time === null ) {
$from_time = $now ;
2024-11-08 13:46:13 +00:00
} else {
$now_arr = dol_getdate ( $from_time );
2023-04-29 05:37:02 +00:00
}
2024-10-26 18:03:22 +00:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
// Take the first period found
2023-04-29 05:37:02 +00:00
$sql = " SELECT date_start, date_end FROM " . $db -> prefix () . " accounting_fiscalyear " ;
2024-10-26 18:03:22 +00:00
$sql .= " WHERE date_start <= ' " . $db -> idate ( $from_time , $gm ) . " ' " ;
if ( $withenddateonly ) {
$sql .= " AND (date_end >= ' " . $db -> idate ( $from_time , $gm ) . " ') " ;
} else {
$sql .= " AND (date_end >= ' " . $db -> idate ( $from_time , $gm ) . " ' OR date_end IS NULL) " ;
}
//$sql .= " AND statut = 0"
$sql .= " AND entity IN ( " . getEntity ( 'accounting_fiscalyear' ) . " ) " ;
2023-04-29 05:37:02 +00:00
$sql .= $db -> order ( 'date_start' , 'DESC' );
$sql .= $db -> plimit ( 1 );
2024-10-26 18:03:22 +00:00
2023-04-29 05:37:02 +00:00
$res = $db -> query ( $sql );
2024-10-26 18:03:22 +00:00
2023-04-29 05:37:02 +00:00
if ( $db -> num_rows ( $res ) > 0 ) {
2024-10-26 18:03:22 +00:00
// If found
2023-04-29 05:37:02 +00:00
$obj = $db -> fetch_object ( $res );
2024-10-26 18:03:22 +00:00
$date_start = $db -> jdate ( $obj -> date_start , $gm );
$date_end = dol_get_last_hour ( $db -> jdate ( $obj -> date_end , $gm ), $gm );
2023-04-29 05:37:02 +00:00
} else {
2024-10-26 18:03:22 +00:00
// If not found, we generate a period
2023-04-29 05:37:02 +00:00
$month_start = 1 ;
2024-10-26 18:03:22 +00:00
$conf_fiscal_month_start = getDolGlobalInt ( 'SOCIETE_FISCAL_MONTH_START' );
2023-04-29 05:37:02 +00:00
if ( $conf_fiscal_month_start >= 1 && $conf_fiscal_month_start <= 12 ) {
$month_start = $conf_fiscal_month_start ;
}
$year_start = $now_arr [ 'year' ];
if ( $conf_fiscal_month_start > $now_arr [ 'mon' ]) {
2024-08-07 00:53:45 +00:00
$year_start -= 1 ;
2023-04-29 05:37:02 +00:00
}
$year_end = $year_start + 1 ;
$month_end = $month_start - 1 ;
if ( $month_end < 1 ) {
$month_end = 12 ;
$year_end -- ;
}
2024-10-26 18:03:22 +00:00
$date_start = dol_mktime ( 0 , 0 , 0 , $month_start , 1 , $year_start , $gm );
$date_end = dol_get_last_day ( $year_end , $month_end , $gm );
2023-04-29 05:37:02 +00:00
}
return array (
'date_start' => $date_start ,
'date_end' => $date_end ,
);
}
2025-12-08 08:56:42 +00:00
/**
* Get next fiscal year period after a given date
*
* @ param DoliDB $db Database handler
* @ param int $after_date Get fiscal period that starts after this date
* @ param 'tzserver' | 'gmt' $gm 'gmt' => we return GMT timestamp , 'tzserver' => PHP server timezone
* @ return array { date_start : int , date_end : int } | null Period of next fiscal year or null if not found
*/
function getNextFiscalYear ( $db , $after_date , $gm = 'tzserver' )
{
// Find the fiscal year that starts strictly after the given date
$sql = " SELECT date_start, date_end FROM " . $db -> prefix () . " accounting_fiscalyear " ;
$sql .= " WHERE date_start > ' " . $db -> idate ( $after_date , $gm ) . " ' " ;
$sql .= " AND entity IN ( " . getEntity ( 'accounting_fiscalyear' ) . " ) " ;
$sql .= $db -> order ( 'date_start' , 'ASC' ); // Get the first one (earliest)
$sql .= $db -> plimit ( 1 );
$res = $db -> query ( $sql );
if ( $res && $db -> num_rows ( $res ) > 0 ) {
$obj = $db -> fetch_object ( $res );
$date_start = $db -> jdate ( $obj -> date_start , $gm );
2025-12-08 09:12:02 +00:00
$date_end = $db -> jdate ( $obj -> date_end , $gm ); // Without dol_get_last_hour to avoid the bug
2025-12-08 08:56:42 +00:00
return array (
'date_start' => $date_start ,
'date_end' => $date_end ,
);
}
return null ; // No next fiscal year found
}