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