dolibarr 24.0.0-beta
accounting.lib.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
3 * Copyright (C) 2013-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
4 * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
5 * Copyright (C) 2019 Eric Seigne <eric.seigne@cap-rel.fr>
6 * Copyright (C) 2021-2026 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
39function is_empty($var, $allow_false = false, $allow_ws = false)
40{
41 if (is_null($var) || !isset($var) || ($allow_ws == false && trim($var) == "" && !is_bool($var)) || ($allow_false === false && $var === false) || (is_array($var) && empty($var))) {
42 return true;
43 }
44 return false;
45}
46
54{
55 global $langs, $conf;
56
57 $h = 0;
58 $head = array();
59
60 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/accountancy/admin/card.php', ['id' => $object->id]);
61 $head[$h][1] = $langs->trans("AccountAccounting");
62 $head[$h][2] = 'card';
63 $h++;
64
65 // Show more tabs from modules
66 // Entries must be declared in modules descriptor with line
67 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
68 // $this->tabs = array('entity:-tabname); to remove a tab
69 complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_account');
70
71 complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_account', 'remove');
72
73 return $head;
74}
75
85function accounting_transaction_prepare_head(BookKeeping $object, $mode = '', $type = '', $backtopage = '/accountancy/bookkeeping/listbyaccount.php')
86{
87 global $langs, $conf;
88
89 $h = 0;
90 $head = array();
91
92 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/accountancy/bookkeeping/card.php', ['piece_num' => $object->piece_num, 'mode' => $mode, 'type' => $type, 'backtopage' => $backtopage]);
93 $head[$h][1] = $langs->trans("Transaction");
94 $head[$h][2] = 'transaction';
95 $h++;
96
97 // Show more tabs from modules
98 // Entries must be declared in modules descriptor with line
99 // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
100 // $this->tabs = array('entity:-tabname); to remove a tab
101 complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_transaction');
102
103 complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_transaction', 'remove');
104
105 return $head;
106}
107
115{
116 global $langs, $conf;
117
118 $h = 0;
119 $head = array();
120
121 $head[$h][0] = dolBuildUrl(DOL_URL_ROOT.'/accountancy/admin/template/card.php', ['id' => $object->id]);
122 $head[$h][1] = $langs->trans("BookkeepingTemplate");
123 $head[$h][2] = 'card';
124 $h++;
125
126 complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_template_transaction');
127
128 complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_template_transaction', 'remove');
129
130 return $head;
131}
132
139function clean_account($account)
140{
141 $account = rtrim($account, "0");
142
143 return $account;
144}
145
152function length_accountg($account)
153{
154 if ($account < 0 || is_empty($account)) {
155 return '';
156 }
157
158 if (getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
159 return $account;
160 }
161
162 $g = getDolGlobalInt('ACCOUNTING_LENGTH_GACCOUNT');
163 if (!is_empty($g)) {
164 // Clean parameters
165 $i = strlen($account);
166
167 if ($i >= 1) {
168 while ($i < $g) {
169 $account .= '0';
170 $i++;
171 }
172
173 return $account;
174 } else {
175 return $account;
176 }
177 } else {
178 return $account;
179 }
180}
181
188function length_accounta($accounta)
189{
190 global $conf;
191
192 if ($accounta < 0 || is_empty($accounta)) {
193 return '';
194 }
195
196 if (getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
197 return $accounta;
198 }
199
200 $a = getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT');
201 if (!is_empty($a)) {
202 // Clean parameters
203 $i = strlen($accounta);
204
205 if ($i >= 1) {
206 while ($i < $a) {
207 $accounta .= '0';
208 $i++;
209 }
210
211 return $accounta;
212 } else {
213 return $accounta;
214 }
215 } else {
216 return $accounta;
217 }
218}
219
229function checkGeneralAccountAllowsAuxiliary($db, $general_account, $auxiliary_account, $general_account_id = 0)
230{
231 global $conf;
232
233 if (empty($auxiliary_account)) return true; // No check needed if no auxiliary account used
234
235 // Build SQL to get general account info based on rowid or account number
236 $sql = "SELECT rowid, account_number, centralized";
237 $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account";
238 $sql .= " WHERE";
239 if ($general_account_id > 0) {
240 $sql .= " rowid = ".((int) $general_account_id);
241 } else {
242 $sql .= " account_number = '".$db->escape($general_account)."'";
243 }
244 $sql .= " AND entity = ". ((int) $conf->entity);
245 $sql .= " AND fk_pcg_version IN (SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid = ".((int) getDolGlobalInt('CHARTOFACCOUNTS')).")";
246
247 $resql = $db->query($sql);
248 if ($resql) {
249 $obj = $db->fetch_object($resql);
250 if ($obj && empty($obj->centralized)) {
251 // Not a centralized account -> not allowed to use auxiliary
252 return false;
253 }
254 }
255
256 return true;
257}
258
275function journalHead($nom, $variant, $period, $periodlink, $description, $builddate, $exportlink = '', $moreparam = array(), $calcmode = '', $varlink = '', $moreoptions = array())
276{
277 global $langs;
278
279 print "\n\n<!-- start banner journal -->\n";
280
281 if (!is_empty($varlink)) {
282 $varlink = '?'.$varlink;
283 }
284
285 $head = array();
286 $h = 0;
287 $head[$h][0] = $_SERVER["PHP_SELF"].$varlink;
288 $head[$h][1] = $langs->trans("Journalization");
289 $head[$h][2] = 'journal';
290
291 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].$varlink.'">';
292 print '<input type="hidden" name="token" value="'.newToken().'">';
293
294 print dol_get_fiche_head($head, 'journal');
295
296 foreach ($moreparam as $key => $value) {
297 print '<input type="hidden" name="'.$key.'" value="'.$value.'">';
298 }
299 print '<table class="border centpercent tableforfield">';
300
301 // Title
302 print '<tr>';
303 print '<td class="titlefieldcreate">'.$langs->trans("Name").'</td>';
304 print '<td colspan="3">';
305 print $nom;
306 print '</td>';
307 print '</tr>';
308
309 // Calculation mode
310 if ($calcmode) {
311 print '<tr>';
312 print '<td>'.$langs->trans("CalculationMode").'</td>';
313 if (!$variant) {
314 print '<td colspan="3">';
315 } else {
316 print '<td>';
317 }
318 print $calcmode;
319 if ($variant) {
320 print '</td><td colspan="2">'.$variant;
321 }
322 print '</td>';
323 print '</tr>';
324 }
325
326 // Period of report
327 print '<tr>';
328 print '<td>'.$langs->trans("ReportPeriod").'</td>';
329 if (!$periodlink) {
330 print '<td colspan="3">';
331 } else {
332 print '<td>';
333 }
334 if ($period) {
335 print $period;
336 }
337 if ($periodlink) {
338 print '</td><td colspan="2">'.$periodlink;
339 }
340 print '</td>';
341 print '</tr>';
342
343 // Line description
344 print '<tr>';
345 print '<td>'.$langs->trans("ReportDescription").'</td>';
346 print '<td colspan="3">'.$description.'</td>';
347 print '</tr>';
348
349
350 // more options
351 foreach ($moreoptions as $key => $value) {
352 print '<tr>';
353 print '<td>'.$langs->trans($key).'</td>';
354 print '<td colspan="3">'.$value.'</td>';
355 print '</tr>';
356 }
357
358 print '</table>';
359
360 print dol_get_fiche_end();
361
362 print '<div class="center"><input type="submit" class="button" name="submit" value="'.$langs->trans("Refresh").'"></div>';
363
364 print '</form>';
365
366 print "\n<!-- end banner journal -->\n\n";
367}
368
375{
376 global $db;
377
378 $date_start = '';
379 $date_end = '';
380 $pastmonth = 0;
381 $pastmonthyear = 0;
382
383 // Period by default on transfer (0: previous month | 1: current month | 2: fiscal year)
384 $periodbydefaultontransfer = getDolGlobalInt('ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER', 0);
385 if ($periodbydefaultontransfer == 2) { // fiscal year
386 $sql = "SELECT date_start, date_end FROM ".MAIN_DB_PREFIX."accounting_fiscalyear";
387 $sql .= " WHERE date_start < '".$db->idate(dol_now())."' AND date_end > '".$db->idate(dol_now())."'";
388 $sql .= $db->plimit(1);
389 $res = $db->query($sql);
390 if ($db->num_rows($res) > 0) {
391 $obj = $db->fetch_object($res);
392
393 $date_start = $db->jdate($obj->date_start);
394 $date_end = dol_get_last_hour($db->jdate($obj->date_end));
395 } else {
396 $month_start = getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1);
397 $year_start = (int) dol_print_date(dol_now(), '%Y');
398 if ($month_start > (int) dol_print_date(dol_now(), '%m')) {
399 $year_start -= 1;
400 }
401 $year_end = $year_start + 1;
402 $month_end = $month_start - 1;
403 if ($month_end < 1) {
404 $month_end = 12;
405 $year_end--;
406 }
407 $date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start);
408 $lastday = dol_get_last_day($year_end, $month_end);
409 $date_end = dol_mktime(23, 59, 59, $month_end, (int) dol_print_date($lastday, '%d'), $year_end);
410 }
411 } elseif ($periodbydefaultontransfer == 1) { // current month
412 $year_current = (int) dol_print_date(dol_now('gmt'), "%Y", 'gmt');
413 $pastmonth = (int) dol_print_date(dol_now('gmt'), '%m', 'gmt');
414 $pastmonthyear = $year_current;
415 if ($pastmonth == 0) {
416 $pastmonth = 12;
417 $pastmonthyear--;
418 }
419 } else { // previous month
420 $year_current = (int) dol_print_date(dol_now('gmt'), "%Y", 'gmt');
421 $pastmonth = (int) dol_print_date(dol_now('gmt'), '%m', 'gmt') - 1;
422 $pastmonthyear = $year_current;
423 if ($pastmonth == 0) {
424 $pastmonth = 12;
425 $pastmonthyear--;
426 }
427 }
428 return array(
429 'date_start' => $date_start,
430 'date_end' => $date_end,
431 'pastmonthyear' => $pastmonthyear,
432 'pastmonth' => $pastmonth
433 );
434}
435
446function getCurrentPeriodOfFiscalYear($db, $conf, $from_time = null, $gm = 'tzserver', $withenddateonly = 1)
447{
448 $now = dol_now();
449 $now_arr = dol_getdate($now);
450 if ($from_time === null) {
451 $from_time = $now;
452 } else {
453 $now_arr = dol_getdate($from_time);
454 }
455
456 include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
457
458 // Take the first period found
459 $sql = "SELECT date_start, date_end FROM ".$db->prefix()."accounting_fiscalyear";
460 $sql .= " WHERE date_start <= '".$db->idate($from_time, $gm)."'";
461 if ($withenddateonly) {
462 $sql .= " AND (date_end >= '".$db->idate($from_time, $gm)."')";
463 } else {
464 $sql .= " AND (date_end >= '".$db->idate($from_time, $gm)."' OR date_end IS NULL)";
465 }
466 //$sql .= " AND statut = 0"
467 $sql .= " AND entity IN (".getEntity('accounting_fiscalyear').")";
468 $sql .= $db->order('date_start', 'DESC');
469 $sql .= $db->plimit(1);
470
471 $res = $db->query($sql);
472
473 if ($db->num_rows($res) > 0) {
474 // If found
475 $obj = $db->fetch_object($res);
476
477 $date_start = $db->jdate($obj->date_start, $gm);
478 $date_end = dol_get_last_hour($db->jdate($obj->date_end, $gm), $gm);
479 } else {
480 // If not found, we generate a period
481 $month_start = 1;
482 $conf_fiscal_month_start = getDolGlobalInt('SOCIETE_FISCAL_MONTH_START');
483 if ($conf_fiscal_month_start >= 1 && $conf_fiscal_month_start <= 12) {
484 $month_start = $conf_fiscal_month_start;
485 }
486 $year_start = $now_arr['year'];
487 if ($conf_fiscal_month_start > $now_arr['mon']) {
488 $year_start -= 1;
489 }
490 $year_end = $year_start + 1;
491 $month_end = $month_start - 1;
492 if ($month_end < 1) {
493 $month_end = 12;
494 $year_end--;
495 }
496 $date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start, $gm);
497 $date_end = dol_get_last_day($year_end, $month_end, $gm);
498 }
499
500 return array(
501 'date_start' => $date_start,
502 'date_end' => $date_end,
503 );
504}
505
514function getNextFiscalYear($db, $after_date, $gm = 'tzserver')
515{
516 // Find the fiscal year that starts strictly after the given date
517 $sql = "SELECT date_start, date_end FROM ".$db->prefix()."accounting_fiscalyear";
518 $sql .= " WHERE date_start > '".$db->idate($after_date, $gm)."'";
519 $sql .= " AND entity IN (".getEntity('accounting_fiscalyear').")";
520 $sql .= $db->order('date_start', 'ASC'); // Get the first one (earliest)
521 $sql .= $db->plimit(1);
522
523 $res = $db->query($sql);
524
525 if ($res && $db->num_rows($res) > 0) {
526 $obj = $db->fetch_object($res);
527
528 $date_start = $db->jdate($obj->date_start, $gm);
529 $date_end = $db->jdate($obj->date_end, $gm); // Without dol_get_last_hour to avoid the bug
530
531 return array(
532 'date_start' => $date_start,
533 'date_end' => $date_end,
534 );
535 }
536
537 return null; // No next fiscal year found
538}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
accounting_transaction_prepare_head(BookKeeping $object, $mode='', $type='', $backtopage='/accountancy/bookkeeping/listbyaccount.php')
Prepare array with list of tabs for accounting transaction.
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
accounting_prepare_head(AccountingAccount $object)
Prepare array with list of tabs.
getCurrentPeriodOfFiscalYear($db, $conf, $from_time=null, $gm='tzserver', $withenddateonly=1)
Get current period of fiscal year?
accountingTransactionTemplatePrepareHead(BookkeepingTemplate $object)
Prepare array with list of tabs for accounting transaction template.
journalHead($nom, $variant, $period, $periodlink, $description, $builddate, $exportlink='', $moreparam=array(), $calcmode='', $varlink='', $moreoptions=array())
Show header of a page used to transfer/dispatch data in accounting.
is_empty($var, $allow_false=false, $allow_ws=false)
Check if a value is empty with some options.
getDefaultDatesForTransfer()
Return Default dates for transfer based on periodicity option in accountancy setup.
clean_account($account)
Return accounting account without zero on the right.
length_accounta($accounta)
Return Auxiliary accounting account of thirdparties with defined length.
checkGeneralAccountAllowsAuxiliary($db, $general_account, $auxiliary_account, $general_account_id=0)
Check if a general accounting account allows the use of an auxiliary account.
getNextFiscalYear($db, $after_date, $gm='tzserver')
Get next fiscal year period after a given date.
Class to manage accounting accounts.
Class to manage Ledger (General Ledger and Subledger)
Class for BookkeepingTemplate.
dol_get_last_hour($date, $gm='tzserver')
Return GMT time for last hour of a given GMT date (it replaces hours, min and second part to 23:59:59...
Definition date.lib.php:650
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:623
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
$date_start
Variables from include:
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add', $filterorigmodule='')
Complete or removed entries into a head array (used to build tabs).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.