dolibarr 21.0.3
result.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2016-2017 Jamal Elbaz <jamelbaz@gmail.com>
3 * Copyright (C) 2016-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
4 * Copyright (C) 2018-2020 Laurent Destailleur <eldy@destailleur.fr>
5 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
6 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
28// Load Dolibarr environment
29require '../../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
34require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancycategory.class.php';
35require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyreport.class.php';
36
46// Load translation files required by the page
47$langs->loadLangs(array('compta', 'bills', 'donation', 'salaries', 'accountancy'));
48
49$id_report = GETPOSTINT('id_report');
50if ($id_report <= 0) {
51 $id_report = 1;
52}
53
54$error = 0;
55
56$mesg = '';
57$action = GETPOST('action', 'aZ09');
58$cat_id = GETPOST('account_category');
59$selectcpt = GETPOST('cpt_bk');
60$id = GETPOSTINT('id');
61$rowid = GETPOSTINT('rowid');
62$cancel = GETPOST('cancel', 'alpha');
63$showaccountdetail = GETPOST('showaccountdetail', 'aZ09') ? GETPOST('showaccountdetail', 'aZ09') : 'no';
64
65
66$date_startmonth = GETPOSTINT('date_startmonth');
67$date_startday = GETPOSTINT('date_startday');
68$date_startyear = GETPOSTINT('date_startyear');
69$date_endmonth = GETPOSTINT('date_endmonth');
70$date_endday = GETPOSTINT('date_endday');
71$date_endyear = GETPOSTINT('date_endyear');
72
73$nbofyear = 1;
74
75// Change this to test different cases of setup
76//$conf->global->SOCIETE_FISCAL_MONTH_START = 7;
77
78// Date range
79$year = GETPOSTINT('year'); // year with current month, is the month of the period we must show
80if (empty($year)) {
81 $year_current = (int) dol_print_date(dol_now('gmt'), "%Y", 'gmt');
82 $month_current = (int) dol_print_date(dol_now(), "%m");
83 $year_start = $year_current - ($nbofyear - 1);
84} else {
85 $year_current = $year;
86 $month_current = (int) dol_print_date(dol_now(), "%m");
87 $year_start = $year - ($nbofyear - 1);
88}
89$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
90$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
91
92// We define date_start and date_end
93if (empty($date_start) || empty($date_end)) { // We define date_start and date_end
94 $q = GETPOSTINT("q") ? GETPOSTINT("q") : 0;
95 if ($q == 0) {
96 // We define date_start and date_end
97 $year_end = $year_start + ($nbofyear - 1);
98 $month_start = GETPOSTINT("month") ? GETPOSTINT("month") : getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1);
99 $date_startmonth = $month_start;
100 if (!GETPOST('month')) {
101 if (!$year && $month_start > $month_current) {
102 $year_start--;
103 $year_end--;
104 }
105 $month_end = $month_start - 1;
106 if ($month_end < 1) {
107 $month_end = 12;
108 } else {
109 $year_end++;
110 }
111 } else {
112 $month_end = $month_start;
113 }
114 $date_start = dol_get_first_day($year_start, $month_start, false);
115 $date_end = dol_get_last_day($year_end, $month_end, false);
116 }
117 if ($q == 1) {
118 $date_start = dol_get_first_day($year_start, 1, false);
119 $date_end = dol_get_last_day($year_start, 3, false);
120 }
121 if ($q == 2) {
122 $date_start = dol_get_first_day($year_start, 4, false);
123 $date_end = dol_get_last_day($year_start, 6, false);
124 }
125 if ($q == 3) {
126 $date_start = dol_get_first_day($year_start, 7, false);
127 $date_end = dol_get_last_day($year_start, 9, false);
128 }
129 if ($q == 4) {
130 $date_start = dol_get_first_day($year_start, 10, false);
131 $date_end = dol_get_last_day($year_start, 12, false);
132 }
133}
134
135if (($date_start < dol_time_plus_duree($date_end, -1, 'y')) || ($date_start > $date_end)) {
136 $date_end = dol_time_plus_duree($date_start - 1, 1, 'y');
137}
138
139// $date_start and $date_end are defined. We force $start_year and $nbofyear
140$tmps = dol_getdate($date_start);
141$start_year = $tmps['year'];
142$start_month = $tmps['mon'];
143$tmpe = dol_getdate($date_end);
144$year_end = $tmpe['year'];
145$month_end = $tmpe['mon'];
146$nbofyear = ($year_end - $start_year) + 1;
147
148$date_startmonth = $start_month;
149$date_endmonth = $month_end;
150
151$date_start_previous = dol_time_plus_duree($date_start, -1, 'y');
152$date_end_previous = dol_time_plus_duree($date_end, -1, 'y');
153
154//var_dump($date_start." ".$date_end." ".$date_start_previous." ".$date_end_previous." ".$nbofyear);
155
156
157if ($cat_id == 0) {
158 $cat_id = null;
159}
160
161// Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES' or 'BOOKKEEPING')
162$modecompta = getDolGlobalString('ACCOUNTING_MODE');
163if (isModEnabled('accounting')) {
164 $modecompta = 'BOOKKEEPING';
165}
166if (GETPOST("modecompta", 'alpha')) {
167 $modecompta = GETPOST("modecompta", 'alpha');
168}
169
170$AccCat = new AccountancyCategory($db);
171
172// Security check
173$socid = GETPOSTINT('socid');
174if ($user->socid > 0) {
175 $socid = $user->socid;
176}
177$hookmanager->initHooks(['resultreportlist']);
178if (isModEnabled('comptabilite')) {
179 $result = restrictedArea($user, 'compta', '', '', 'resultat');
180}
181if (isModEnabled('accounting')) {
182 $result = restrictedArea($user, 'accounting', '', '', 'comptarapport');
183}
184
185/*
186 * View
187 */
188
189$months = array(
190 $langs->trans("MonthShort01"),
191 $langs->trans("MonthShort02"),
192 $langs->trans("MonthShort03"),
193 $langs->trans("MonthShort04"),
194 $langs->trans("MonthShort05"),
195 $langs->trans("MonthShort06"),
196 $langs->trans("MonthShort07"),
197 $langs->trans("MonthShort08"),
198 $langs->trans("MonthShort09"),
199 $langs->trans("MonthShort10"),
200 $langs->trans("MonthShort11"),
201 $langs->trans("MonthShort12"),
202);
203
204llxHeader('', $langs->trans('ReportInOut'));
205
206$builddate = 0;
207$name = '';
208$period = '';
209$calcmode = 0;
210
211$form = new Form($db);
212
213$textprevyear = '<a href="'.$_SERVER["PHP_SELF"].'?year='.($start_year - 1).'&showaccountdetail='.urlencode($showaccountdetail).'">'.img_previous().'</a>';
214$textnextyear = ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?year='.($start_year + 1).'&showaccountdetail='.urlencode($showaccountdetail).'">'.img_next().'</a>';
215
216
217// Affiche en-tete de rapport
218if ($modecompta == "CREANCES-DETTES") {
219 $name = $langs->trans("AnnualByAccountDueDebtMode");
220 $calcmode = $langs->trans("CalcModeDebt");
221 $calcmode .= '<br>('.$langs->trans("SeeReportInInputOutputMode", '<a href="'.$_SERVER["PHP_SELF"].'?year='.$start_year.(GETPOST("month") > 0 ? '&month='.GETPOST("month") : '').'&modecompta=RECETTES-DEPENSES">', '</a>').')';
222 if (isModEnabled('accounting')) {
223 $calcmode .= '<br>('.$langs->trans("SeeReportInBookkeepingMode", '<a href="'.$_SERVER["PHP_SELF"].'?year='.$start_year.'&modecompta=BOOKKEEPING">', '</a>').')';
224 }
225 $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
226 //$periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
227 $description = $langs->trans("RulesResultDue");
228 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
229 $description .= $langs->trans("DepositsAreNotIncluded");
230 } else {
231 $description .= $langs->trans("DepositsAreIncluded");
232 }
233 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
234 $description .= $langs->trans("SupplierDepositsAreNotIncluded");
235 }
236 $builddate = dol_now();
237 //$exportlink=$langs->trans("NotYetAvailable");
238} elseif ($modecompta == "RECETTES-DEPENSES") {
239 $name = $langs->trans("AnnualByAccountInputOutputMode");
240 $calcmode = $langs->trans("CalcModePayment");
241 $calcmode .= '<br>('.$langs->trans("SeeReportInDueDebtMode", '<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.(GETPOST("month") > 0 ? '&month='.GETPOST("month") : '').'&modecompta=CREANCES-DETTES">', '</a>').')';
242 if (isModEnabled('accounting')) {
243 $calcmode .= '<br>('.$langs->trans("SeeReportInBookkeepingMode", '<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=BOOKKEEPING">', '</a>').')';
244 }
245 $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
246 //$periodlink='<a href="'.$_SERVER["PHP_SELF"].'?year='.($year-1).'&modecompta='.$modecompta.'">'.img_previous().'</a> <a href="'.$_SERVER["PHP_SELF"].'?year='.($year+1).'&modecompta='.$modecompta.'">'.img_next().'</a>';
247 $description = $langs->trans("RulesResultInOut");
248 $builddate = dol_now();
249 //$exportlink=$langs->trans("NotYetAvailable");
250} elseif ($modecompta == "BOOKKEEPING") {
251 $accountingreportstatic = new AccountancyReport($db);
252 $accountingreportstatic->fetch($id_report);
253 $reportLabel = '';
254 $reportLabel = $accountingreportstatic->label;
255
256 $name = $langs->trans("ReportInOut").', '.$langs->trans("ByPersonalizedAccountGroups").' '.$reportLabel;
257 $calcmode = $langs->trans("CalcModeBookkeeping");
258 //$calcmode.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=CREANCES-DETTES">','</a>').')';
259 //$calcmode.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year_start='.$year_start.'&modecompta=RECETTES-DEPENSES">','</a>').')';
260 $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0);
261 $arraylist = array('no' => $langs->trans("None"), 'yes' => $langs->trans("AccountWithNonZeroValues"), 'all' => $langs->trans("All"));
262 $period .= ' &nbsp; &nbsp; <span class="opacitymedium">'.$langs->trans("DetailBy").'</span> '.$form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0);
263 $periodlink = $textprevyear.$textnextyear;
264 $exportlink = '';
265 $description = $langs->trans("RulesResultBookkeepingPersonalized");
266 $description .= ' ('.$langs->trans("SeePageForSetup", DOL_URL_ROOT.'/accountancy/admin/categories_list.php?search_country_id='.$mysoc->country_id.'&mainmenu=accountancy&leftmenu=accountancy_admin', $langs->transnoentitiesnoconv("Accountancy").' / '.$langs->transnoentitiesnoconv("Setup").' / '.$langs->transnoentitiesnoconv("AccountingCategory")).')';
267 $builddate = dol_now();
268}
269
270report_header($name, '', $period, $periodlink ?? '', $description, $builddate, $exportlink ?? '', array('modecompta' => $modecompta, 'action' => ''), $calcmode);
271
272
273if (isModEnabled('accounting') && $modecompta != 'BOOKKEEPING') {
274 print info_admin($langs->trans("WarningReportNotReliable"), 0, 0, '1');
275}
276
277
278$moreforfilter = '';
279
280print '<div class="div-table-responsive">';
281print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
282
283print '<tr class="liste_titre">';
284print '<th class="liste_titre">'.$langs->trans("AccountingCategory").'</th>';
285print '<th class="liste_titre"></th>';
286print '<th class="liste_titre right">'.$langs->trans("PreviousPeriod").'</th>';
287print '<th class="liste_titre right">'.$langs->trans("SelectedPeriod").'</th>';
288foreach ($months as $k => $v) {
289 if (($k + 1) >= $date_startmonth && (($date_startmonth <= $date_endmonth && ($k + 1) <= $date_endmonth) || ($date_startmonth > $date_endmonth))) {
290 print '<th class="liste_titre right width50">'.$langs->trans('MonthShort'.sprintf("%02d", ($k + 1))).'</th>';
291 }
292}
293if ($date_startmonth > $date_endmonth) {
294 foreach ($months as $k => $v) {
295 if (($k + 1) < $date_startmonth && ($k + 1) <= $date_endmonth) {
296 print '<th class="liste_titre right width50">'.$langs->trans('MonthShort'.sprintf("%02d", ($k + 1))).'</th>';
297 }
298 }
299}
300print '</tr>';
301
302if ($modecompta == 'CREANCES-DETTES') {
303 //if (!empty($date_start) && !empty($date_end))
304 // $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
305} elseif ($modecompta == "RECETTES-DEPENSES") {
306 //if (!empty($date_start) && !empty($date_end))
307 // $sql.= " AND p.datep >= '".$db->idate($date_start)."' AND p.datep <= '".$db->idate($date_end)."'";
308} elseif ($modecompta == "BOOKKEEPING") {
309 // Get array of all report groups that are active
310 $cats = $AccCat->getCats(-1, 1, $id_report); // WARNING: Computed groups must be after group they include
311 $unactive_cats = $AccCat->getCats(-1, 0, $id_report);
312
313 /*
314 $sql = 'SELECT DISTINCT t.numero_compte as nb FROM '.MAIN_DB_PREFIX.'accounting_bookkeeping as t, '.MAIN_DB_PREFIX.'accounting_account as aa';
315 $sql.= " WHERE t.numero_compte = aa.account_number AND aa.fk_accounting_category = 0";
316 if (!empty($date_start) && !empty($date_end))
317 $sql.= " AND t.doc_date >= '".$db->idate($date_start)."' AND t.doc_date <= '".$db->idate($date_end)."'";
318 if (!empty($month)) {
319 $sql .= " AND MONTH(t.doc_date) = " . ((int) $month);
320 }
321 $resql = $db->query($sql);
322 if ($resql)
323 {
324 $num_rows = $db->num_rows($resql);
325 if ($num_rows) {
326
327 print '<div class="warning">Warning: There is '.$num_rows.' accounts in your ledger table that are not set into a reporting group</div>';
328 $i = 0;
329 //while ($i < $num) {
330 // $obj = $db->fetch_object($resql);
331 // $i++;
332 //}
333 }
334 }
335 else dol_print_error($db);
336 */
337
338 $j = 1;
339 $sommes = array();
340 $totPerAccount = array();
341 if (!is_array($cats) && $cats < 0) {
342 setEventMessages(null, $AccCat->errors, 'errors');
343 } elseif (is_array($cats) && count($cats) == 0) {
344 print '<tr class="liste_total">';
345 print '<td colspan="15">';
346 print '<span class="opacitymedium">';
347 print $langs->trans("ErrorNoAccountingCategoryForThisCountry", $mysoc->country_code, $langs->transnoentitiesnoconv("Accountancy"), $langs->transnoentitiesnoconv("Setup"), $langs->transnoentitiesnoconv("AccountingCategory"));
348 print '</span>';
349 print '</td>';
350 print '</tr>';
351 } elseif (is_array($cats) && count($cats) > 0) {
352 // Loop on each custom group of accounts
353 foreach ($cats as $cat) {
354 if (!empty($cat['category_type'])) {
355 // category calculated
356 // When we enter here, $sommes was filled by group of accounts
357
358 $formula = $cat['formula'];
359
360 print '<tr class="liste_total">';
361
362 // Code and Label
363 print '<td class="liste_total tdoverflowmax100" title="'.dol_escape_htmltag($cat['code']).'">';
364 print dol_escape_htmltag($cat['code']);
365 print '</td><td class="tdoverflowmax250 borderright" title="'.dol_escape_htmltag($cat['label']).'">';
366 print dol_escape_htmltag($cat['label']);
367 print '</td>';
368
369 $vars = array();
370
371 // Unactive categories have a total of 0 to be used in the formula.
372 foreach ($unactive_cats as $un_cat) {
373 $vars[$un_cat['code']] = 0;
374 }
375
376 // Previous Fiscal year (N-1)
377 foreach ($sommes as $code => $det) {
378 $vars[$code] = empty($det['NP']) ? 0 : $det['NP'];
379 }
380
381 $result = strtr($formula, $vars);
382 $result = str_replace('--', '+', $result);
383
384 if (preg_match('/[a-z]/i', $result)) {
385 $r = 'Error bad formula: '.$result;
386 $rshort = 'Err';
387 print '<td class="liste_total right"><span class="amount" title="'.dol_escape_htmltag($r).'">'.$rshort.'</span></td>';
388 } else {
389 //var_dump($result);
390 //$r = $AccCat->calculate($result);
391 $r = (float) dol_eval($result, 1, 1, '1');
392
393 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
394 print '<td class="liste_total right"><span class="amount">'.price($r, 0, '', 1, 0, 0).'</span></td>';
395 } else {
396 print '<td class="liste_total right"><span class="amount">'.price($r).'</span></td>';
397 }
398 }
399
400 if (!isset($sommes[$code])) {
401 $sommes[$code] = array();
402 }
403 // Year N
404 $code = $cat['code']; // code of categorie ('VTE', 'MAR', ...)
405 if (empty($sommes[$code]['NP'])) {
406 $sommes[$code]['NP'] = $r;
407 } else {
408 $sommes[$code]['NP'] += $r;
409 }
410
411 // Current fiscal year (N)
412 if (is_array($sommes) && !empty($sommes)) {
413 foreach ($sommes as $code => $det) {
414 $vars[$code] = empty($det['N']) ? 0 : $det['N'];
415 }
416 }
417
418 $result = strtr($formula, $vars);
419 $result = str_replace('--', '+', $result);
420
421 //$r = $AccCat->calculate($result);
422 $r = (float) dol_eval($result, 1, 1, '1');
423
424 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
425 print '<td class="liste_total right borderright"><span class="amount">'.price($r, 0, '', 1, 0, 0).'</span></td>';
426 } else {
427 print '<td class="liste_total right borderright"><span class="amount">'.price($r).'</span></td>';
428 }
429 if (empty($sommes[$code]['N'])) {
430 $sommes[$code]['N'] = $r;
431 } else {
432 $sommes[$code]['N'] += $r;
433 }
434
435 // Detail by month
436 foreach ($months as $k => $v) {
437 if (($k + 1) >= $date_startmonth && (($date_startmonth <= $date_endmonth && ($k + 1) <= $date_endmonth) || ($date_startmonth > $date_endmonth))) {
438 foreach ($sommes as $code => $det) {
439 $vars[$code] = empty($det['M'][$k]) ? 0 : $det['M'][$k];
440 }
441 $result = strtr($formula, $vars);
442 $result = str_replace('--', '+', $result);
443
444 //$r = $AccCat->calculate($result);
445 $r = (float) dol_eval($result, 1, 1, '1');
446
447
448 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
449 print '<td class="liste_total right"><span class="amount">'.price($r, 0, '', 1, 0, 0).'</span></td>';
450 } else {
451 print '<td class="liste_total right"><span class="amount">'.price($r).'</span></td>';
452 }
453 if (empty($sommes[$code]['M'][$k])) {
454 $sommes[$code]['M'][$k] = $r;
455 } else {
456 $sommes[$code]['M'][$k] += $r;
457 }
458 }
459 }
460
461 if ($date_startmonth > $date_endmonth) {
462 foreach ($months as $k => $v) {
463 if (($k + 1) < $date_startmonth && ($k + 1) <= $date_endmonth) {
464 foreach ($sommes as $code => $det) {
465 $vars[$code] = empty($det['M'][$k]) ? 0 : $det['M'][$k];
466 }
467 $result = strtr($formula, $vars);
468 $result = str_replace('--', '+', $result);
469
470 //$r = $AccCat->calculate($result);
471 $r = (float) dol_eval($result, 1, 1, '1');
472
473 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
474 print '<td class="liste_total right"><span class="amount">'.price($r, 0, '', 1, 0, 0).'</span></td>';
475 } else {
476 print '<td class="liste_total right"><span class="amount">'.price($r).'</span></td>';
477 }
478 if (empty($sommes[$code]['M'][$k])) {
479 $sommes[$code]['M'][$k] = $r;
480 } else {
481 $sommes[$code]['M'][$k] += $r;
482 }
483 }
484 }
485 }
486
487 print "</tr>\n";
488
489 //var_dump($sommes);
490 } else { // normal category
491 $code = $cat['code']; // Category code we process
492
493 $totCat = array();
494 $totCat['NP'] = 0;
495 $totCat['N'] = 0;
496 $totCat['M'] = array();
497 foreach ($months as $k => $v) {
498 $totCat['M'][$k] = 0;
499 }
500 if (!isset($sommes[$code])) {
501 $sommes[$code] = array();
502 }
503
504 // Set $cpts with array of accounts in the category/group
505 $cpts = $AccCat->getCptsCat($cat['rowid']);
506 // We should loop over empty $cpts array, else the category _code_ is used in the formula, which leads to wrong result if the code is a number.
507 if (empty($cpts)) {
508 $cpts[] = array();
509 }
510
511 $arrayofaccountforfilter = array();
512 foreach ($cpts as $i => $cpt) { // Loop on each account.
513 if (isset($cpt['account_number'])) {
514 $arrayofaccountforfilter[] = $cpt['account_number'];
515 }
516 }
517
518 // N-1
519 if (!empty($arrayofaccountforfilter)) {
520 $return = $AccCat->getSumDebitCredit($arrayofaccountforfilter, $date_start_previous, $date_end_previous, empty($cat['dc']) ? 0 : $cat['dc']);
521 if ($return < 0) {
522 setEventMessages(null, $AccCat->errors, 'errors');
523 $resultNP = 0;
524 } else {
525 foreach ($cpts as $i => $cpt) { // Loop on each account found
526 $resultNP = empty($AccCat->sdcperaccount[$cpt['account_number']]) ? 0 : $AccCat->sdcperaccount[$cpt['account_number']];
527
528 if (empty($totCat['NP'])) {
529 $totCat['NP'] = $resultNP;
530 } else {
531 $totCat['NP'] += $resultNP;
532 }
533 if (empty($sommes[$code]['NP'])) {
534 $sommes[$code]['NP'] = $resultNP;
535 } else {
536 $sommes[$code]['NP'] += $resultNP;
537 }
538 $totPerAccount[$cpt['account_number']]['NP'] = $resultNP;
539 }
540 }
541 }
542
543 // Set value into column N and month M ($totCat)
544 // This make 12 calls for each accountancy account (12 months M)
545 foreach ($cpts as $i => $cpt) { // Loop on each account.
546 // We make 1 loop for each account because we may want detail per account.
547 // @todo Optimize to ask a 'group by' account and a filter with account in (..., ...) in request
548
549 // Each month
550 $resultN = 0;
551 foreach ($months as $k => $v) {
552 $monthtoprocess = $k + 1; // ($k+1) is month 1, 2, ..., 12
553 $yeartoprocess = $start_year;
554 if (($k + 1) < $start_month) {
555 $yeartoprocess++;
556 }
557
558 //var_dump($monthtoprocess.'_'.$yeartoprocess);
559 if (isset($cpt['account_number'])) {
560 $return = $AccCat->getSumDebitCredit($cpt['account_number'], $date_start, $date_end, empty($cat['dc']) ? 0 : $cat['dc'], 'nofilter', $monthtoprocess, $yeartoprocess);
561 if ($return < 0) {
562 setEventMessages(null, $AccCat->errors, 'errors');
563 $resultM = 0;
564 } else {
565 $resultM = $AccCat->sdc;
566 }
567 } else {
568 $resultM = 0;
569 }
570 if (empty($totCat['M'][$k])) {
571 $totCat['M'][$k] = $resultM;
572 } else {
573 $totCat['M'][$k] += $resultM;
574 }
575 if (empty($sommes[$code]['M'][$k])) {
576 $sommes[$code]['M'][$k] = $resultM;
577 } else {
578 $sommes[$code]['M'][$k] += $resultM;
579 }
580 if (isset($cpt['account_number'])) {
581 $totPerAccount[$cpt['account_number']]['M'][$k] = $resultM;
582 }
583
584 $resultN += $resultM;
585 }
586
587 if (empty($totCat)) {
588 $totCat['N'] = $resultN;
589 } else {
590 $totCat['N'] += $resultN;
591 }
592 if (empty($sommes[$code]['N'])) {
593 $sommes[$code]['N'] = $resultN;
594 } else {
595 $sommes[$code]['N'] += $resultN;
596 }
597 if (isset($cpt['account_number'])) {
598 $totPerAccount[$cpt['account_number']]['N'] = $resultN;
599 }
600 }
601
602
603 // Now output columns for row $code ('VTE', 'MAR', ...)
604
605 print '<tr'.($showaccountdetail != 'no' ? ' class="trforbreak"' : '').'>';
606
607 // Column group
608 print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($cat['code']).'">';
609 print dol_escape_htmltag($cat['code']);
610 print '</td>';
611
612 // Label of group
613 $labeltoshow = dol_escape_htmltag($cat['label']);
614 if (count($cpts) > 0 && !empty($cpts[0])) { // Show example of 5 first accounting accounts
615 $i = 0;
616 foreach ($cpts as $cpt) {
617 if ($i > 5) {
618 $labeltoshow .= '...)';
619 break;
620 }
621 if ($i > 0) {
622 $labeltoshow .= ', ';
623 } else {
624 $labeltoshow .= ' (';
625 }
626 $labeltoshow .= dol_escape_htmltag($cpt['account_number']);
627 $i++;
628 }
629 if ($i <= 5) {
630 $labeltoshow .= ')';
631 }
632 } else {
633 $labeltoshow .= ' - <span class="warning">'.$langs->trans("GroupIsEmptyCheckSetup").'</span>';
634 }
635 print '<td class="tdoverflowmax250 borderright" title="'.dol_escape_htmltag(dol_string_nohtmltag($labeltoshow)).'">';
636 print $labeltoshow;
637 print '</td>';
638
639 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
640 print '<td class="right"><span class="amount">'.price($totCat['NP'], 0, '', 1, 0, 0).'</span></td>';
641 print '<td class="right borderright"><span class="amount">'.price($totCat['N'], 0, '', 1, 0, 0).'</span></td>';
642 } else {
643 print '<td class="right"><span class="amount">'.price($totCat['NP']).'</span></td>';
644 print '<td class="right borderright"><span class="amount">'.price($totCat['N']).'</span></td>';
645 }
646
647 // Each month
648 foreach ($totCat['M'] as $k => $v) {
649 if (($k + 1) >= $date_startmonth && (($date_startmonth <= $date_endmonth && ($k + 1) <= $date_endmonth) || ($date_startmonth > $date_endmonth))) {
650 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
651 print '<td class="right nowraponall"><span class="amount">'.price($v, 0, '', 1, 0, 0).'</span></td>';
652 } else {
653 print '<td class="right nowraponall"><span class="amount">'.price($v).'</span></td>';
654 }
655 }
656 }
657 if ($date_startmonth > $date_endmonth) {
658 foreach ($totCat['M'] as $k => $v) {
659 if (($k + 1) < $date_startmonth && ($k + 1) <= $date_endmonth) {
660 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
661 print '<td class="right nowraponall"><span class="amount">'.price($v, 0, '', 1, 0, 0).'</span></td>';
662 } else {
663 print '<td class="right nowraponall"><span class="amount">'.price($v).'</span></td>';
664 }
665 }
666 }
667 }
668
669 print "</tr>\n";
670
671 // Loop on detail of all accounts to output the detail
672 if ($showaccountdetail != 'no') {
673 foreach ($cpts as $i => $cpt) {
674 if (isset($cpt['account_number'])) {
675 $resultNP = $totPerAccount[$cpt['account_number']]['NP'];
676 $resultN = $totPerAccount[$cpt['account_number']]['N'];
677 } else {
678 $resultNP = 0;
679 $resultN = 0;
680 }
681
682 if ($showaccountdetail == 'all' || $resultN != 0) {
683 print '<tr>';
684 print '<td></td>';
685
686 if (isset($cpt['account_number'])) {
687 $labeldetail = ' &nbsp; &nbsp; '.length_accountg($cpt['account_number']).' - '.$cpt['account_label'];
688 } else {
689 $labeldetail = '-';
690 }
691
692 print '<td class="tdoverflowmax250 borderright" title="'.dol_escape_htmltag($labeldetail).'">';
693 print dol_escape_htmltag($labeldetail);
694 print '</td>';
695 if (getDolGlobalInt('ACCOUNTANCY_TRUNC_DECIMAL_ON_BALANCE_REPORT')) {
696 print '<td class="right"><span class="amount">'.price($resultNP, 0, '', 1, 0, 0).'</span></td>';
697 print '<td class="right borderright"><span class="amount">'.price($resultN, 0, '', 1, 0, 0).'</span></td>';
698 } else {
699 print '<td class="right"><span class="amount">'.price($resultNP).'</span></td>';
700 print '<td class="right borderright"><span class="amount">'.price($resultN).'</span></td>';
701 }
702
703 // Make one call for each month
704 foreach ($months as $k => $v) {
705 if (($k + 1) >= $date_startmonth && (($date_startmonth <= $date_endmonth && ($k + 1) <= $date_endmonth) || ($date_startmonth > $date_endmonth))) {
706 if (isset($cpt['account_number'])) {
707 $resultM = $totPerAccount[$cpt['account_number']]['M'][$k];
708 } else {
709 $resultM = 0;
710 }
711 print '<td class="right"><span class="amount">'.price($resultM).'</span></td>';
712 }
713 }
714 if ($date_startmonth > $date_endmonth) {
715 foreach ($months as $k => $v) {
716 if (($k + 1) < $date_startmonth && ($k + 1) <= $date_endmonth) {
717 if (isset($cpt['account_number'])) {
718 $resultM = empty($totPerAccount[$cpt['account_number']]['M'][$k]) ? 0 : $totPerAccount[$cpt['account_number']]['M'][$k];
719 } else {
720 $resultM = 0;
721 }
722 print '<td class="right"><span class="amount">'.price($resultM).'</span></td>';
723 }
724 }
725 }
726 print "</tr>\n";
727 }
728 }
729 }
730 }
731 }
732 }
733}
734
735print "</table>";
736print '</div>';
737
738// End of page
739llxFooter();
740$db->close();
$id
Definition account.php:48
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:71
Class to manage categories of an accounting account.
Class to manage reports for accounting categories.
Class to manage generation of HTML components Only common components must be here.
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:600
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition date.lib.php:125
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:619
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...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dol_eval($s, $returnvalue=1, $hideerrors=1, $onlysimplestring='1')
Replace eval function to add more security.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
img_previous($titlealt='default', $moreatt='')
Show previous logo.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
img_next($titlealt='default', $moreatt='')
Show next logo.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
report_header($reportname, $notused, $period, $periodlink, $description, $builddate, $exportlink='', $moreparam=array(), $calcmode='', $varlink='')
Show header of a report.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.