dolibarr 21.0.0-beta
balance.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2016 Olivier Geffroy <jeff@jeffinfo.com>
3 * Copyright (C) 2016 Florian Henry <florian.henry@open-concept.pro>
4 * Copyright (C) 2016-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
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';
30
31// Class
32require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
35require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
36require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
37require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
39require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
40
49// Load translation files required by the page
50$langs->loadLangs(array("accountancy", "compta"));
51
52$action = GETPOST('action', 'aZ09');
53$optioncss = GETPOST('optioncss', 'alpha');
54$type = GETPOST('type', 'alpha');
55if ($type == 'sub') {
56 $context_default = 'balancesubaccountlist';
57} else {
58 $context_default = 'balancelist';
59}
60$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : $context_default;
61$show_subgroup = GETPOST('show_subgroup', 'alpha');
62$search_date_start = dol_mktime(0, 0, 0, GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
63$search_date_end = dol_mktime(23, 59, 59, GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
64$search_ledger_code = GETPOST('search_ledger_code', 'array');
65$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha');
66if ($search_accountancy_code_start == - 1) {
67 $search_accountancy_code_start = '';
68}
69$search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha');
70if ($search_accountancy_code_end == - 1) {
71 $search_accountancy_code_end = '';
72}
73$search_not_reconciled = GETPOST('search_not_reconciled', 'alpha');
74
75// Load variable for pagination
76$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
77$sortfield = GETPOST('sortfield', 'aZ09comma');
78$sortorder = GETPOST('sortorder', 'aZ09comma');
79$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
80if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
81 // If $page is not defined, or '' or -1 or if we click on clear filters
82 $page = 0;
83}
84$offset = $limit * $page;
85$pageprev = $page - 1;
86$pagenext = $page + 1;
87if ($sortorder == "") {
88 $sortorder = "ASC";
89}
90if ($sortfield == "") {
91 $sortfield = "t.numero_compte";
92}
93
94// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
95$object = new BookKeeping($db);
96$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array
97
98$formaccounting = new FormAccounting($db);
99$formother = new FormOther($db);
100$form = new Form($db);
101
102if (empty($search_date_start) && !GETPOSTISSET('formfilteraction')) {
103 $sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear ";
104 $sql .= " WHERE date_start < '".$db->idate(dol_now())."' AND date_end > '".$db->idate(dol_now())."'";
105 $sql .= $db->plimit(1);
106 $res = $db->query($sql);
107
108 if ($db->num_rows($res) > 0) {
109 $fiscalYear = $db->fetch_object($res);
110 $search_date_start = strtotime($fiscalYear->date_start);
111 $search_date_end = strtotime($fiscalYear->date_end);
112 } else {
113 $month_start = getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1);
114 $year_start = (int) dol_print_date(dol_now(), '%Y');
115 if (dol_print_date(dol_now(), '%m') < $month_start) {
116 $year_start--; // If current month is lower that starting fiscal month, we start last year
117 }
118 $year_end = $year_start + 1;
119 $month_end = $month_start - 1;
120 if ($month_end < 1) {
121 $month_end = 12;
122 $year_end--;
123 }
124 $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start);
125 $search_date_end = dol_get_last_day($year_end, $month_end);
126 }
127}
128
129if (!isModEnabled('accounting')) {
131}
132if ($user->socid > 0) {
134}
135if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
137}
138
139
140/*
141 * Action
142 */
143
144$param = '';
145$urlparam = '';
146$parameters = array();
147$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
148if ($reshook < 0) {
149 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
150}
151
152if (empty($reshook)) {
153 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
154 $show_subgroup = '';
155 $search_date_start = '';
156 $search_date_end = '';
157 $search_date_startyear = '';
158 $search_date_startmonth = '';
159 $search_date_startday = '';
160 $search_date_endyear = '';
161 $search_date_endmonth = '';
162 $search_date_endday = '';
163 $search_accountancy_code_start = '';
164 $search_accountancy_code_end = '';
165 $search_not_reconciled = '';
166 $search_ledger_code = array();
167 $filter = array();
168 }
169
170 // Must be after the remove filter action, before the export.
171 $filter = array();
172
173 if (!empty($search_date_start)) {
174 $filter['t.doc_date>='] = $search_date_start;
175 $param .= '&date_startmonth=' . GETPOSTINT('date_startmonth') . '&date_startday=' . GETPOSTINT('date_startday') . '&date_startyear=' . GETPOSTINT('date_startyear');
176 }
177 if (!empty($search_date_end)) {
178 $filter['t.doc_date<='] = $search_date_end;
179 $param .= '&date_endmonth=' . GETPOSTINT('date_endmonth') . '&date_endday=' . GETPOSTINT('date_endday') . '&date_endyear=' . GETPOSTINT('date_endyear');
180 }
181 if (!empty($search_accountancy_code_start)) {
182 if ($type == 'sub') {
183 $filter['t.subledger_account>='] = $search_accountancy_code_start;
184 } else {
185 $filter['t.numero_compte>='] = $search_accountancy_code_start;
186 }
187 $param .= '&search_accountancy_code_start=' . urlencode($search_accountancy_code_start);
188 }
189 if (!empty($search_accountancy_code_end)) {
190 if ($type == 'sub') {
191 $filter['t.subledger_account<='] = $search_accountancy_code_end;
192 } else {
193 $filter['t.numero_compte<='] = $search_accountancy_code_end;
194 }
195 $param .= '&search_accountancy_code_end=' . urlencode($search_accountancy_code_end);
196 }
197 if (!empty($search_ledger_code)) {
198 $filter['t.code_journal'] = $search_ledger_code;
199 foreach ($search_ledger_code as $code) {
200 $param .= '&search_ledger_code[]=' . urlencode($code);
201 }
202 }
203 if (!empty($search_not_reconciled)) {
204 $filter['t.reconciled_option'] = $search_not_reconciled;
205 $param .= '&search_not_reconciled='.urlencode($search_not_reconciled);
206 }
207
208 // param with type of list
209 $url_param = substr($param, 1); // remove first "&"
210 if (!empty($type)) {
211 $param = '&type=' . $type . $param;
212 }
213}
214
215if ($action == 'export_csv' && $user->hasRight('accounting', 'mouvements', 'lire')) {
216 $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
217
218 $filename = 'balance';
219 $type_export = 'balance';
220 include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
221
222 if ($type == 'sub') {
223 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, 0, $filter, 'AND', 1);
224 } else {
225 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, 0, $filter);
226 }
227 if ($result < 0) {
228 setEventMessages($object->error, $object->errors, 'errors');
229 }
230
231 foreach ($object->lines as $line) {
232 if ($type == 'sub') {
233 print '"' . length_accounta($line->subledger_account) . '"' . $sep;
234 print '"' . $line->subledger_label . '"' . $sep;
235 } else {
236 print '"' . length_accountg($line->numero_compte) . '"' . $sep;
237 print '"' . $object->get_compte_desc($line->numero_compte) . '"' . $sep;
238 }
239 print '"'.price($line->debit).'"'.$sep;
240 print '"'.price($line->credit).'"'.$sep;
241 print '"'.price($line->debit - $line->credit).'"'.$sep;
242 print "\n";
243 }
244
245 exit;
246}
247
248
249/*
250 * View
251 */
252
253if ($type == 'sub') {
254 $title_page = $langs->trans("AccountBalanceSubAccount");
255} else {
256 $title_page = $langs->trans("AccountBalance");
257}
258
259$help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double';
260
261llxHeader('', $title_page, $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-consultation page-'.(($type == 'sub') ? 'sub' : '').'balance');
262
263
264if ($action != 'export_csv') {
265 // List
266 $nbtotalofrecords = '';
267 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
268 if ($type == 'sub') {
269 $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter, 'AND', 1);
270 } else {
271 $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter);
272 }
273
274 if ($nbtotalofrecords < 0) {
275 setEventMessages($object->error, $object->errors, 'errors');
276 }
277 }
278
279 if ($type == 'sub') {
280 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1);
281 } else {
282 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter);
283 }
284
285 if ($result < 0) {
286 setEventMessages($object->error, $object->errors, 'errors');
287 }
288
289 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
290 print '<input type="hidden" name="token" value="'.newToken().'">';
291 print '<input type="hidden" name="action" id="action" value="list">';
292 if ($optioncss != '') {
293 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
294 }
295 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
296 print '<input type="hidden" name="type" value="'.$type.'">';
297 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
298 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
299 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
300 print '<input type="hidden" name="page" value="'.$page.'">';
301
302 $url_param = '';
303
304 $parameters = array();
305 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
306
307 if ($reshook < 0) {
308 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
309 }
310
311 $newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint;
312
313 if (empty($reshook)) {
314 $newcardbutton = '<input type="button" id="exportcsvbutton" name="exportcsvbutton" class="butAction" value="'.$langs->trans("Export").' (' . getDolGlobalString('ACCOUNTING_EXPORT_FORMAT').')" />';
315
316 print '<script type="text/javascript">
317 jQuery(document).ready(function() {
318 jQuery("#exportcsvbutton").click(function(event) {
319 event.preventDefault();
320 console.log("Set action to export_csv");
321 jQuery("#action").val("export_csv");
322 jQuery("#searchFormList").submit();
323 jQuery("#action").val("list");
324 });
325 });
326 </script>';
327
328 if ($type == 'sub') {
329 $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly'));
330 $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
331 } else {
332 $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
333 $newcardbutton .= dolGetButtonTitle($langs->trans('AccountBalance')." - ".$langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/balance.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly'));
334 }
335 $newcardbutton .= dolGetButtonTitleSeparator();
336 $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create');
337 }
338 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
339 $param .= '&contextpage='.urlencode($contextpage);
340 }
341 if ($limit > 0 && $limit != $conf->liste_limit) {
342 $param .= '&limit='.((int) $limit);
343 }
344
345 print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1);
346
347 $selectedfields = '';
348
349 // Warning to explain why list of record is not consistent with the other list view (missing a lot of lines)
350 if ($type == 'sub') {
351 print info_admin($langs->trans("WarningRecordWithoutSubledgerAreExcluded"));
352 }
353
354 $moreforfilter = '';
355
356 $moreforfilter .= '<div class="divsearchfield">';
357 $moreforfilter .= $langs->trans('DateStart').': ';
358 $moreforfilter .= $form->selectDate($search_date_start ? $search_date_start : -1, 'date_start', 0, 0, 1, '', 1, 0);
359 $moreforfilter .= $langs->trans('DateEnd').': ';
360 $moreforfilter .= $form->selectDate($search_date_end ? $search_date_end : -1, 'date_end', 0, 0, 1, '', 1, 0);
361 $moreforfilter .= '</div>';
362
363 $moreforfilter .= '<div class="divsearchfield">';
364 $moreforfilter .= '<label for="show_subgroup">'.$langs->trans('ShowSubtotalByGroup').'</label>: ';
365 $moreforfilter .= '<input type="checkbox" name="show_subgroup" id="show_subgroup" value="show_subgroup"'.($show_subgroup == 'show_subgroup' ? ' checked' : '').'>';
366 $moreforfilter .= '</div>';
367
368 $moreforfilter .= '<div class="divsearchfield">';
369 $moreforfilter .= $langs->trans("Journals").': ';
370 $moreforfilter .= $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1);
371 $moreforfilter .= '</div>';
372
373 //$moreforfilter .= '<br>';
374 $moreforfilter .= '<div class="divsearchfield">';
375 // Accountancy account
376 $moreforfilter .= $langs->trans('AccountAccounting').': ';
377 if ($type == 'sub') {
378 $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200');
379 } else {
380 $moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200', 'accounts');
381 }
382 $moreforfilter .= ' ';
383 if ($type == 'sub') {
384 $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200');
385 } else {
386 $moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200', 'accounts');
387 }
388 $moreforfilter .= '</div>';
389
390 if (getDolGlobalString('ACCOUNTING_ENABLE_LETTERING')) {
391 $moreforfilter .= '<div class="divsearchfield">';
392 $moreforfilter .= '<label for="notreconciled">'.$langs->trans('NotReconciled').'</label>: ';
393 $moreforfilter .= '<input type="checkbox" name="search_not_reconciled" id="notreconciled" value="notreconciled"'.($search_not_reconciled == 'notreconciled' ? ' checked' : '').'>';
394 $moreforfilter .= '</div>';
395 }
396
397 print '<div class="liste_titre liste_titre_bydiv centpercent">';
398 print $moreforfilter;
399 $parameters = array();
400 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
401 print $hookmanager->resPrint;
402 print '</div>';
403
404
405 $colspan = (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE') ? 5 : 4);
406
407 print '<table class="liste '.($moreforfilter ? "listwithfilterbefore" : "").'">';
408
409 print '<tr class="liste_titre_filter">';
410
411 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
412 print '<td class="liste_titre maxwidthsearch">';
413 $searchpicto = $form->showFilterButtons();
414 print $searchpicto;
415 print '</td>';
416 }
417
418 print '<td class="liste_titre" colspan="'.$colspan.'">';
419 print '</td>';
420
421 // Fields from hook
422 $parameters = array();
423 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
424 print $hookmanager->resPrint;
425
426 // Action column
427 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
428 print '<td class="liste_titre maxwidthsearch">';
429 $searchpicto = $form->showFilterButtons();
430 print $searchpicto;
431 print '</td>';
432 }
433 print '</tr>'."\n";
434
435 print '<tr class="liste_titre">';
436 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
437 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
438 }
439 print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder);
440 // TODO : Retrieve the type of third party: Customer / Supplier / Employee
441 //if ($type == 'sub') {
442 // print_liste_field_titre("Type", $_SERVER['PHP_SELF'], "t.type", "", $param, "", $sortfield, $sortorder);
443 //}
444 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
445 print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder);
446 }
447 print_liste_field_titre("AccountingDebit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder);
448 print_liste_field_titre("AccountingCredit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder);
449 print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder);
450
451 // Hook fields
452 $parameters = array('param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder);
453 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
454 print $hookmanager->resPrint;
455 // Action column
456 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
457 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
458 }
459 print '</tr>'."\n";
460
461 $total_debit = 0;
462 $total_credit = 0;
463 $sous_total_debit = 0;
464 $sous_total_credit = 0;
465 $total_opening_balance = 0;
466 $sous_total_opening_balance = 0;
467 $displayed_account = "";
468
469 $accountingaccountstatic = new AccountingAccount($db);
470
471 // TODO Debug - This feature is dangerous, it takes all the entries and adds all the accounts
472 // without time and class limits (Class 6 and 7 accounts ???) and does not take into account the "a-nouveau" journal.
473 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
474 $sql = "SELECT t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance";
475 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as t";
476 $sql .= " WHERE t.entity = " . $conf->entity; // Never do sharing into accounting features
477 $sql .= " AND t.doc_date < '" . $db->idate($search_date_start) . "'";
478 $sql .= " GROUP BY t.numero_compte";
479
480 $resql = $db->query($sql);
481 $opening_balances = array();
482 if ($resql) {
483 $nrows = $db->num_rows($resql);
484 for ($i = 0; $i < $nrows; $i++) {
485 $arr = $db->fetch_array($resql);
486 if (is_array($arr)) {
487 $opening_balances["'" . $arr['numero_compte'] . "'"] = $arr['opening_balance'];
488 }
489 }
490 } else {
491 dol_print_error($db);
492 }
493 }
494
495 foreach ($object->lines as $line) {
496 // reset before the fetch (in case of the fetch fails)
497 $accountingaccountstatic->id = 0;
498 $accountingaccountstatic->account_number = '';
499 $accounting_account = '';
500
501 if ($type != 'sub') {
502 $accountingaccountstatic->fetch(0, $line->numero_compte, true);
503 if (!empty($accountingaccountstatic->account_number)) {
504 $accounting_account = $accountingaccountstatic->getNomUrl(0, 1, 1);
505 } else {
506 $accounting_account = length_accountg($line->numero_compte);
507 }
508 }
509
510 $link = '';
511 $total_debit += $line->debit;
512 $total_credit += $line->credit;
513 $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0;
514 $total_opening_balance += $opening_balance;
515
516 $tmparrayforrootaccount = $object->getRootAccount($line->numero_compte);
517 $root_account_description = $tmparrayforrootaccount['label'];
518 $root_account_number = $tmparrayforrootaccount['account_number'];
519
520 //var_dump($tmparrayforrootaccount);
521 //var_dump($accounting_account);
522 //var_dump($accountingaccountstatic);
523 if (empty($accountingaccountstatic->label) && $accountingaccountstatic->id > 0) {
524 $link = '<a class="editfielda reposition" href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=update&token=' . newToken() . '&id=' . $accountingaccountstatic->id . '">' . img_edit() . '</a>';
525 } elseif ($accounting_account == 'NotDefined') {
526 $link = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=create&token=' . newToken() . '&accountingaccount=' . length_accountg($line->numero_compte) . '">' . img_edit_add() . '</a>';
527 } /* elseif (empty($tmparrayforrootaccount['label'])) {
528 // $tmparrayforrootaccount['label'] not defined = the account has not parent with a parent.
529 // This is useless, we should not create a new account when an account has no parent, we must edit it to fix its parent.
530 // BUG 1: Accounts on level root or level 1 must not have a parent 2 level higher, so should not show a link to create another account.
531 // BUG 2: Adding a link to create a new accounting account here is useless because it is not add as parent of the orphelin.
532 //$link = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=create&token=' . newToken() . '&accountingaccount=' . length_accountg($line->numero_compte) . '">' . img_edit_add() . '</a>';
533 } */
534
535 if (!empty($show_subgroup)) {
536 // Show accounting account
537 if (empty($displayed_account) || $root_account_number != $displayed_account) {
538 // Show subtotal per accounting account
539 if ($displayed_account != "") {
540 print '<tr class="liste_total">';
541 print '<td class="right">'.$langs->trans("SubTotal").':</td>';
542 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
543 print '<td></td>';
544 }
545 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
546 print '<td class="right nowraponall amount">'.price($sous_total_opening_balance).'</td>';
547 }
548 print '<td class="right nowraponall amount">'.price($sous_total_debit).'</td>';
549 print '<td class="right nowraponall amount">'.price($sous_total_credit).'</td>';
550 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
551 print '<td class="right nowraponall amount">'.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit)).'</td>';
552 } else {
553 print '<td class="right nowraponall amount">'.price(price2num($sous_total_debit - $sous_total_credit)).'</td>';
554 }
555 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
556 print "<td></td>\n";
557 }
558 print '</tr>';
559 }
560
561 // Show first line of a break
562 print '<tr class="trforbreak">';
563 print '<td colspan="'.($colspan + 1).'" class="tdforbreak">'.$root_account_number.($root_account_description ? ' - '.$root_account_description : '').'</td>';
564 print '</tr>';
565
566 $displayed_account = $root_account_number;
567 $sous_total_debit = 0;
568 $sous_total_credit = 0;
569 $sous_total_opening_balance = 0;
570 }
571 }
572
573 print '<tr class="oddeven">';
574
575 // Action column
576 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
577 print '<td class="center">';
578 print $link;
579 print '</td>';
580 }
581
582 // Accounting account
583 if ($type == 'sub') {
584 print '<td>'.$line->subledger_account.' <span class="opacitymedium">('.$line->subledger_label.')</span></td>';
585 } else {
586 print '<td>'.$accounting_account.'</td>';
587 }
588
589 // Type
590 // TODO Retrieve the type of third party: Customer / Supplier / Employee
591 //if ($type == 'sub') {
592 // print '<td></td>';
593 //}
594
595 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
596 print '<td class="right nowraponall amount">'.price(price2num($opening_balance, 'MT')).'</td>';
597 }
598
599 $urlzoom = '';
600 if ($type == 'sub') {
601 if ($line->subledger_account) {
602 $urlzoom = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&search_accountancy_code_start=' . urlencode($line->subledger_account) . '&search_accountancy_code_end=' . urlencode($line->subledger_account);
603 if (GETPOSTISSET('date_startmonth')) {
604 $urlzoom .= '&search_date_startmonth=' . GETPOSTINT('date_startmonth') . '&search_date_startday=' . GETPOSTINT('date_startday') . '&search_date_startyear=' . GETPOSTINT('date_startyear');
605 }
606 if (GETPOSTISSET('date_endmonth')) {
607 $urlzoom .= '&search_date_endmonth=' . GETPOSTINT('date_endmonth') . '&search_date_endday=' . GETPOSTINT('date_endday') . '&search_date_endyear=' . GETPOSTINT('date_endyear');
608 }
609 }
610 } else {
611 if ($line->numero_compte) {
612 $urlzoom = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($line->numero_compte) . '&search_accountancy_code_end=' . urlencode($line->numero_compte);
613 if (GETPOSTISSET('date_startmonth')) {
614 $urlzoom .= '&search_date_startmonth=' . GETPOSTINT('date_startmonth') . '&search_date_startday=' . GETPOSTINT('date_startday') . '&search_date_startyear=' . GETPOSTINT('date_startyear');
615 }
616 if (GETPOSTISSET('date_endmonth')) {
617 $urlzoom .= '&search_date_endmonth=' . GETPOSTINT('date_endmonth') . '&search_date_endday=' . GETPOSTINT('date_endday') . '&search_date_endyear=' . GETPOSTINT('date_endyear');
618 }
619 }
620 }
621 // Debit
622 print '<td class="right nowraponall amount"><a href="'.$urlzoom.'">'.price(price2num($line->debit, 'MT')).'</a></td>';
623 // Credit
624 print '<td class="right nowraponall amount"><a href="'.$urlzoom.'">'.price(price2num($line->credit, 'MT')).'</a></td>';
625
626 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
627 print '<td class="right nowraponall amount">'.price(price2num($opening_balance + $line->debit - $line->credit, 'MT')).'</td>';
628 } else {
629 print '<td class="right nowraponall amount">'.price(price2num($line->debit - $line->credit, 'MT')).'</td>';
630 }
631
632 // Action column
633 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
634 print '<td class="center">';
635 print $link;
636 print '</td>';
637 }
638
639 print "</tr>\n";
640
641 // Records the sub-total
642 $sous_total_debit += $line->debit;
643 $sous_total_credit += $line->credit;
644 $sous_total_opening_balance += $opening_balance;
645 }
646
647 if (!empty($show_subgroup)) {
648 print '<tr class="liste_total">';
649 // Action column
650 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
651 print "<td></td>\n";
652 }
653 print '<td class="right">'.$langs->trans("SubTotal").':</td>';
654 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
655 print '<td class="right nowraponall amount">'.price(price2num($sous_total_opening_balance, 'MT')).'</td>';
656 }
657 print '<td class="right nowraponall amount">'.price(price2num($sous_total_debit, 'MT')).'</td>';
658 print '<td class="right nowraponall amount">'.price(price2num($sous_total_credit, 'MT')).'</td>';
659 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
660 print '<td class="right nowraponall amount">' . price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')) . '</td>';
661 } else {
662 print '<td class="right nowraponall amount">' . price(price2num($sous_total_debit - $sous_total_credit, 'MT')) . '</td>';
663 }
664 // Action column
665 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
666 print "<td></td>\n";
667 }
668 print '</tr>';
669 }
670
671 print '<tr class="liste_total">';
672 // Action column
673 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
674 print "<td></td>\n";
675 }
676 print '<td class="right">'.$langs->trans("AccountBalance").':</td>';
677 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
678 print '<td class="nowrap right">'.price(price2num($total_opening_balance, 'MT')).'</td>';
679 }
680 print '<td class="right nowraponall amount">'.price(price2num($total_debit, 'MT')).'</td>';
681 print '<td class="right nowraponall amount">'.price(price2num($total_credit, 'MT')).'</td>';
682 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
683 print '<td class="right nowraponall amount">' . price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')) . '</td>';
684 } else {
685 print '<td class="right nowraponall amount">' . price(price2num($total_debit - $total_credit, 'MT')) . '</td>';
686 }
687 // Action column
688 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
689 print "<td></td>\n";
690 }
691 print '</tr>';
692
693 // Accounting result
694 if (getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT')) {
695 print '<tr class="liste_total">';
696 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
697 print "<td></td>\n";
698 }
699 print '<td class="right">' . $langs->trans("AccountingResult") . ':</td>';
700 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
701 print '<td></td>';
702 }
703
704 $accountingResult = $object->accountingResult($search_date_start, $search_date_end);
705 if ($accountingResult < 0) {
706 $accountingResultDebit = price(abs((float) price2num($accountingResult, 'MT')));
707 $accountingResultCredit = '';
708 $accountingResultClassCSS = ' error';
709 } else {
710 $accountingResultDebit = '';
711 $accountingResultCredit = price(price2num($accountingResult, 'MT'));
712 $accountingResultClassCSS = ' green';
713 }
714 print '<td class="right nowraponall amount' . $accountingResultClassCSS . '">' . $accountingResultDebit . '</td>';
715 print '<td class="right nowraponall amount' . $accountingResultClassCSS . '">' . $accountingResultCredit . '</td>';
716
717 print '<td></td>';
718 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
719 print "<td></td>\n";
720 }
721 print '</tr>';
722 }
723
724 $parameters = array();
725 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
726 print $hookmanager->resPrint;
727
728 print "</table>";
729 print '</form>';
730}
731
732// End of page
733llxFooter();
734$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
length_accounta($accounta)
Return Auxiliary accounting account of thirdparties with defined length.
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 accounting accounts.
Class to manage Ledger (General Ledger and Subledger)
Class to manage generation of HTML components for accounting management.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
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
llxFooter()
Footer empty.
Definition document.php:107
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.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
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).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
dolGetButtonTitleSeparator($moreClass="")
Add space between dolGetButtonTitle.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_edit_add($titlealt='default', $other='')
Show 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.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.