dolibarr 24.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-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
5 * Copyright (C) 2018-2025 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
63$search_date_start = GETPOSTDATE('date_start', 'getpost', 'auto', 'search_date_start_accountancy');
64$search_date_end = GETPOSTDATE('date_end', 'getpostend', 'auto', 'search_date_end_accountancy');
65
66$search_ledger_code = GETPOST('search_ledger_code', 'array');
67$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha');
68if ($search_accountancy_code_start == - 1) {
69 $search_accountancy_code_start = '';
70}
71$search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha');
72if ($search_accountancy_code_end == - 1) {
73 $search_accountancy_code_end = '';
74}
75$search_not_reconciled = GETPOST('search_not_reconciled', 'alpha');
76
77// Load variable for pagination
78$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
79$sortfield = GETPOST('sortfield', 'aZ09comma');
80$sortorder = GETPOST('sortorder', 'aZ09comma');
81$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
82if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
83 // If $page is not defined, or '' or -1 or if we click on clear filters
84 $page = 0;
85}
86$offset = $limit * $page;
87$pageprev = $page - 1;
88$pagenext = $page + 1;
89if ($sortorder == "") {
90 $sortorder = "ASC";
91}
92if ($sortfield == "") {
93 $sortfield = "t.numero_compte";
94}
95
96// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
98$hookmanager->initHooks(array($contextpage)); // Note that conf->hooks_modules contains array
99
100$formaccounting = new FormAccounting($db);
101$form = new Form($db);
102
103if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('formfilteraction')) {
104 $sql = "SELECT date_start, date_end";
105 $sql .=" FROM ".MAIN_DB_PREFIX."accounting_fiscalyear ";
106 if (getDolGlobalInt('ACCOUNTANCY_FISCALYEAR_DEFAULT')) {
107 $sql .= " WHERE rowid = " . getDolGlobalInt('ACCOUNTANCY_FISCALYEAR_DEFAULT');
108 } else {
109 $sql .= " WHERE date_start < '" . $db->idate(dol_now()) . "' and date_end > '" . $db->idate(dol_now()) . "'";
110 }
111 $sql .= $db->plimit(1);
112 $res = $db->query($sql);
113
114 if ($db->num_rows($res) > 0) {
115 $fiscalYear = $db->fetch_object($res);
116 $search_date_start = strtotime($fiscalYear->date_start);
117 $search_date_end = strtotime($fiscalYear->date_end);
118 } else {
119 $month_start = getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1);
120 $year_start = (int) dol_print_date(dol_now(), '%Y');
121 if (dol_print_date(dol_now(), '%m') < $month_start) {
122 $year_start--; // If current month is lower that starting fiscal month, we start last year
123 }
124 $year_end = $year_start + 1;
125 $month_end = $month_start - 1;
126 if ($month_end < 1) {
127 $month_end = 12;
128 $year_end--;
129 }
130 $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start);
131 $search_date_end = dol_get_last_day($year_end, $month_end);
132 }
133}
134
135if (!isModEnabled('accounting')) {
137}
138if ($user->socid > 0) {
140}
141if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
143}
144
145// Permissions
146$permissiontoread = $user->hasRight('accounting', 'mouvements', 'lire');
147$permissiontoadd = $user->hasRight('accounting', 'mouvements', 'creer');
148$permissiontodelete = $user->hasRight('accounting', 'mouvements', 'supprimer');
149$permissiontoexport = $user->hasRight('accounting', 'mouvements', 'export');
150
151
152/*
153 * Action
154 */
155
156$param = '';
157$urlparam = '';
158$parameters = array();
159$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
160if ($reshook < 0) {
161 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
162}
163
164$filter = array();
165
166if (empty($reshook)) {
167 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
168 $show_subgroup = '';
169 $search_date_start = '';
170 $search_date_end = '';
171 $search_accountancy_code_start = '';
172 $search_accountancy_code_end = '';
173 $search_not_reconciled = '';
174 $search_ledger_code = array();
175 unset($_SESSION['DOLDATE_search_date_start_accountancy_day']);
176 unset($_SESSION['DOLDATE_search_date_start_accountancy_month']);
177 unset($_SESSION['DOLDATE_search_date_start_accountancy_year']);
178 unset($_SESSION['DOLDATE_search_date_end_accountancy_day']);
179 unset($_SESSION['DOLDATE_search_date_end_accountancy_month']);
180 unset($_SESSION['DOLDATE_search_date_end_accountancy_year']);
181 }
182
183 if (!empty($search_date_start)) {
184 $filter['t.doc_date>='] = $search_date_start;
185 $param .= '&date_startmonth=' . GETPOSTINT('date_startmonth') . '&date_startday=' . GETPOSTINT('date_startday') . '&date_startyear=' . GETPOSTINT('date_startyear');
186 }
187 if (!empty($search_date_end)) {
188 $filter['t.doc_date<='] = $search_date_end;
189 $param .= '&date_endmonth=' . GETPOSTINT('date_endmonth') . '&date_endday=' . GETPOSTINT('date_endday') . '&date_endyear=' . GETPOSTINT('date_endyear');
190 }
191 if (!empty($search_accountancy_code_start)) {
192 if ($type == 'sub') {
193 $filter['t.subledger_account>='] = $search_accountancy_code_start;
194 } else {
195 $filter['t.numero_compte>='] = $search_accountancy_code_start;
196 }
197 $param .= '&search_accountancy_code_start=' . urlencode($search_accountancy_code_start);
198 }
199 if (!empty($search_accountancy_code_end)) {
200 if ($type == 'sub') {
201 $filter['t.subledger_account<='] = $search_accountancy_code_end;
202 } else {
203 $filter['t.numero_compte<='] = $search_accountancy_code_end;
204 }
205 $param .= '&search_accountancy_code_end=' . urlencode($search_accountancy_code_end);
206 }
207 if (!empty($search_ledger_code)) {
208 $filter['t.code_journal'] = $search_ledger_code;
209 foreach ($search_ledger_code as $code) {
210 $param .= '&search_ledger_code[]=' . urlencode($code);
211 }
212 }
213 if (!empty($search_not_reconciled)) {
214 $filter['t.reconciled_option'] = $search_not_reconciled;
215 $param .= '&search_not_reconciled='.urlencode($search_not_reconciled);
216 }
217 if (!empty($show_subgroup)) {
218 $param .= '&show_subgroup='.urlencode($show_subgroup);
219 }
220
221 // param with type of list
222 $url_param = substr($param, 1); // remove first "&"
223 if (!empty($type)) {
224 $param = '&type=' . $type . $param;
225 }
226}
227
228if ($action == 'export' && $user->hasRight('accounting', 'mouvements', 'lire')) {
229 $exportType = GETPOST('export_type');
230
231 if ($type == 'sub') {
232 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, 0, $filter, 'AND', 1);
233 } else {
234 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, 0, $filter);
235 }
236 if ($result < 0) {
237 setEventMessages($object->error, $object->errors, 'errors');
238 }
239
240 if ($exportType === 'csv') {
241 $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
242 $filename = 'balance'; // Used by the tpl
243 $type_export = 'balance'; // Used by the tpl
244 include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
245
246 foreach ($object->lines as $line) {
247 if ($type == 'sub') {
248 print '"' . length_accounta($line->subledger_account) . '"' . $sep;
249 print '"' . $line->subledger_label . '"' . $sep;
250 } else {
251 print '"' . length_accountg($line->numero_compte) . '"' . $sep;
252 print '"' . $object->get_compte_desc($line->numero_compte) . '"' . $sep;
253 }
254 print '"'.price($line->debit).'"'.$sep;
255 print '"'.price($line->credit).'"'.$sep;
256 print '"'.price($line->debit - $line->credit).'"'.$sep;
257 print "\n";
258 }
259 exit;
260 } else {
261 require_once DOL_DOCUMENT_ROOT . '/core/modules/accountancy/doc/pdf_balance.modules.php';
262 $pdf = new pdf_balance($db);
263 $pdf->fromDate = dol_mktime(12, 0, 0, GETPOSTINT('search_date_startmonth'), GETPOSTINT('search_date_startday'), GETPOSTINT('search_date_startyear'));
264 if (empty($pdf->fromDate)) {
265 $pdf->fromDate = dol_mktime(12, 0, 0, GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
266 }
267 $pdf->toDate = dol_mktime(12, 0, 0, GETPOSTINT('search_date_endmonth'), GETPOSTINT('search_date_endday'), GETPOSTINT('search_date_endyear'));
268 if (empty($pdf->toDate)) {
269 $pdf->toDate = dol_mktime(12, 0, 0, GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
270 }
271 $pdf->balanceType = $type;
272
273 $result = $pdf->write_file($object, $langs);
274
275 if ($result < 0) {
276 setEventMessage($pdf->error, "errors");
277 } else {
278 // Generated PDF is directly sent to the browser
279 exit;
280 }
281 }
282}
283
284
285/*
286 * View
287 */
288
289if ($type == 'sub') {
290 $title_page = $langs->trans("AccountBalanceSubAccount");
291} else {
292 $title_page = $langs->trans("AccountBalance");
293}
294
295$help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double';
296
297llxHeader('', $title_page, $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-consultation page-'.(($type == 'sub') ? 'sub' : '').'balance');
298
299
300if ($action != 'export') {
301 // List
302 $nbtotalofrecords = '';
303 if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
304 if ($type == 'sub') {
305 $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter, 'AND', 1);
306 } else {
307 $nbtotalofrecords = $object->fetchAllBalance($sortorder, $sortfield, 0, 0, $filter);
308 }
309
310 if ($nbtotalofrecords < 0) {
311 setEventMessages($object->error, $object->errors, 'errors');
312 }
313 }
314
315 if ($type == 'sub') {
316 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1);
317 } else {
318 $result = $object->fetchAllBalance($sortorder, $sortfield, $limit, $offset, $filter);
319 }
320
321 if ($result < 0) {
322 setEventMessages($object->error, $object->errors, 'errors');
323 }
324
325 print '<form method="POST" id="searchFormList" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
326 print '<input type="hidden" name="token" value="'.newToken().'">';
327 print '<input type="hidden" name="action" id="action" value="list">';
328 print '<input type="hidden" name="export_type" id="export_type" value="">';
329 if ($optioncss != '') {
330 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
331 }
332 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
333 print '<input type="hidden" name="type" value="'.$type.'">';
334 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
335 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
336 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
337 print '<input type="hidden" name="page" value="'.$page.'">';
338
339 $url_param = '';
340
341 $parameters = array();
342 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
343
344 if ($reshook < 0) {
345 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
346 }
347
348 $newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint;
349
350 if (empty($reshook)) {
351 if ($type == 'sub') {
352 $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'));
353 $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'));
354 } else {
355 $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'));
356 $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'));
357 }
358
359 $newcardbutton .= dolGetButtonTitle($langs->trans("Export").' (' . getDolGlobalString('ACCOUNTING_EXPORT_FORMAT').')', '', 'fa fa-file-csv paddingleft', $_SERVER['PHP_SELF'], 'exportcsvbutton', $permissiontoexport, array('morecss' => 'marginleftonly'));
360
361 print '<script type="text/javascript">
362 jQuery(document).ready(function() {
363 jQuery("#exportcsvbutton, #exportpdfbutton").click(function(event) {
364 event.preventDefault();
365 const exportType = this.id === "exportcsvbutton" ? "csv" : "pdf";
366 console.log("Set action to export, export_type to " + exportType);
367 jQuery("#action").val("export");
368 jQuery("#export_type").val(exportType);
369 jQuery("#searchFormList").submit();
370 jQuery("#action").val("list");
371 });
372 });
373 </script>';
374
375 $newcardbutton .= dolGetButtonTitle($langs->trans('ExportToPdf'), '', 'fa fa-file-pdf paddingleft', $_SERVER['PHP_SELF'] . '&token=' . newToken(), 'exportpdfbutton', $permissiontoexport, array('morecss' => 'marginleftonly'));
376
377 $newcardbutton .= dolGetButtonTitleSeparator();
378 $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'.(!empty($type)?'&type=sub':'').'&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
379 }
380 if ($contextpage != $_SERVER["PHP_SELF"]) {
381 $param .= '&contextpage='.urlencode($contextpage);
382 }
383 if ($limit > 0 && $limit != $conf->liste_limit) {
384 $param .= '&limit='.((int) $limit);
385 }
386
387 print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1);
388
389 $selectedfields = '';
390
391 // Warning to explain why list of record is not consistent with the other list view (missing a lot of lines)
392 if ($type == 'sub') {
393 print info_admin($langs->trans("WarningRecordWithoutSubledgerAreExcluded"));
394 }
395
396 $moreforfilter = '';
397
398 $moreforfilter .= '<div class="divsearchfield">';
399 $moreforfilter .= $langs->trans('DateStart').': ';
400 $moreforfilter .= $form->selectDate($search_date_start ? $search_date_start : -1, 'date_start', 0, 0, 1, '', 1, 0);
401 $moreforfilter .= $langs->trans('DateEnd').': ';
402 $moreforfilter .= $form->selectDate($search_date_end ? $search_date_end : -1, 'date_end', 0, 0, 1, '', 1, 0);
403 $moreforfilter .= '</div>';
404
405 $moreforfilter .= '<div class="divsearchfield">';
406 $moreforfilter .= '<label for="show_subgroup">'.$langs->trans('ShowSubtotalByGroup').'</label>: ';
407 $moreforfilter .= '<input type="checkbox" name="show_subgroup" id="show_subgroup" value="show_subgroup"'.($show_subgroup == 'show_subgroup' ? ' checked' : '').'>';
408 $moreforfilter .= '</div>';
409
410 $moreforfilter .= '<div class="divsearchfield">';
411 $moreforfilter .= $langs->trans("Journals").': ';
412 $moreforfilter .= $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1);
413 $moreforfilter .= '</div>';
414
415 //$moreforfilter .= '<br>';
416 $moreforfilter .= '<div class="divsearchfield">';
417 // Accountancy account
418 $moreforfilter .= $langs->trans('AccountAccounting').': ';
419 if ($type == 'sub') {
420 $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200');
421 } else {
422 $moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200', 'accounts');
423 }
424 $moreforfilter .= ' ';
425 if ($type == 'sub') {
426 $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200');
427 } else {
428 $moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200', 'accounts');
429 }
430 $moreforfilter .= '</div>';
431
432 if (getDolGlobalString('ACCOUNTING_ENABLE_LETTERING')) {
433 $moreforfilter .= '<div class="divsearchfield">';
434 $moreforfilter .= '<label for="notreconciled">'.$langs->trans('NotReconciled').'</label>: ';
435 $moreforfilter .= '<input type="checkbox" name="search_not_reconciled" id="notreconciled" value="notreconciled"'.($search_not_reconciled == 'notreconciled' ? ' checked' : '').'>';
436 $moreforfilter .= '</div>';
437 }
438
439 print '<div class="liste_titre liste_titre_bydiv centpercent">';
440 print $moreforfilter;
441 $parameters = array();
442 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
443 print $hookmanager->resPrint;
444 print '</div>';
445
446
447 $colspan = (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE') ? 5 : 4);
448
449 print '<table class="liste '.($moreforfilter ? "listwithfilterbefore" : "").'">';
450
451 print '<tr class="liste_titre_filter">';
452
453 if ($conf->main_checkbox_left_column) {
454 print '<td class="liste_titre maxwidthsearch">';
455 $searchpicto = $form->showFilterButtons();
456 print $searchpicto;
457 print '</td>';
458 }
459
460 print '<td class="liste_titre" colspan="'.$colspan.'">';
461 print '</td>';
462
463 // Fields from hook
464 $parameters = array();
465 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
466 print $hookmanager->resPrint;
467
468 // Action column
469 if (!$conf->main_checkbox_left_column) {
470 print '<td class="liste_titre maxwidthsearch">';
471 $searchpicto = $form->showFilterButtons();
472 print $searchpicto;
473 print '</td>';
474 }
475 print '</tr>'."\n";
476
477 print '<tr class="liste_titre">';
478 if ($conf->main_checkbox_left_column) {
479 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
480 }
481 print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder);
482 // TODO : Retrieve the type of third party: Customer / Supplier / Employee
483 //if ($type == 'sub') {
484 // print_liste_field_titre("Type", $_SERVER['PHP_SELF'], "t.type", "", $param, "", $sortfield, $sortorder);
485 //}
486 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
487 print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", "", $param, 'class="right"', $sortfield, $sortorder);
488 }
489 print_liste_field_titre("AccountingDebit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder);
490 print_liste_field_titre("AccountingCredit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder);
491 print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
492
493 // Hook fields
494 $parameters = array('param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder);
495 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
496 print $hookmanager->resPrint;
497 // Action column
498 if (!$conf->main_checkbox_left_column) {
499 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
500 }
501 print '</tr>'."\n";
502
503 $total_debit = 0;
504 $total_credit = 0;
505 $sous_total_debit = 0;
506 $sous_total_credit = 0;
507 $total_opening_balance = 0;
508 $sous_total_opening_balance = 0;
509 $displayed_account = "";
510
511 $accountingaccountstatic = new AccountingAccount($db);
512
513 // TODO Debug - This feature is dangerous, it takes all the entries and adds all the accounts
514 // without time and class limits (Class 6 and 7 accounts ???) and does not take into account the "a-nouveau" journal.
515 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
516 $sql = "SELECT t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance";
517 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as t";
518 $sql .= " WHERE t.entity = " . $conf->entity; // Never do sharing into accounting features
519 $sql .= " AND t.doc_date < '" . $db->idate($search_date_start) . "'";
520 $sql .= " GROUP BY t.numero_compte";
521
522 $resql = $db->query($sql);
523 $opening_balances = array();
524 if ($resql) {
525 $nrows = $db->num_rows($resql);
526 for ($i = 0; $i < $nrows; $i++) {
527 $arr = $db->fetch_array($resql);
528 if (is_array($arr)) {
529 $opening_balances["'" . $arr['numero_compte'] . "'"] = $arr['opening_balance'];
530 }
531 }
532 } else {
534 }
535 }
536
537 foreach ($object->lines as $line) {
538 // reset before the fetch (in case of the fetch fails)
539 $accountingaccountstatic->id = 0;
540 $accountingaccountstatic->account_number = '';
541 $accounting_account = '';
542
543 if ($type != 'sub') {
544 $accountingaccountstatic->fetch(0, $line->numero_compte, true);
545 if (!empty($accountingaccountstatic->account_number)) {
546 $accounting_account = $accountingaccountstatic->getNomUrl(0, 1, 1);
547 } else {
548 $accounting_account = length_accountg($line->numero_compte);
549 }
550 }
551
552 $link = '';
553 $total_debit += $line->debit;
554 $total_credit += $line->credit;
555 $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0;
556 $total_opening_balance += $opening_balance;
557
558 $tmparrayforrootaccount = $object->getRootAccount($line->numero_compte);
559 $root_account_description = $tmparrayforrootaccount['label'];
560 $root_account_number = $tmparrayforrootaccount['account_number'];
561
562 //var_dump($tmparrayforrootaccount);
563 //var_dump($accounting_account);
564 //var_dump($accountingaccountstatic);
565 if (empty($accountingaccountstatic->label) && $accountingaccountstatic->id > 0) {
566 $link = '<a class="editfielda reposition" href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=update&token=' . newToken() . '&id=' . $accountingaccountstatic->id . '">' . img_edit() . '</a>';
567 } elseif ($accounting_account == 'NotDefined') {
568 $link = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=create&token=' . newToken() . '&accountingaccount=' . length_accountg($line->numero_compte) . '">' . img_edit_add() . '</a>';
569 } /* elseif (empty($tmparrayforrootaccount['label'])) {
570 // $tmparrayforrootaccount['label'] not defined = the account has not parent with a parent.
571 // This is useless, we should not create a new account when an account has no parent, we must edit it to fix its parent.
572 // 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.
573 // BUG 2: Adding a link to create a new accounting account here is useless because it is not add as parent of the orphelin.
574 //$link = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=create&token=' . newToken() . '&accountingaccount=' . length_accountg($line->numero_compte) . '">' . img_edit_add() . '</a>';
575 } */
576
577 if (!empty($show_subgroup)) {
578 // Show accounting account
579 if (empty($displayed_account) || $root_account_number != $displayed_account) {
580 // Show subtotal per accounting account
581 if ($displayed_account != "") {
582 print '<tr class="liste_total">';
583 print '<td class="right">'.$langs->trans("SubTotal").':</td>';
584 if ($conf->main_checkbox_left_column) {
585 print '<td></td>';
586 }
587 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
588 print '<td class="right nowraponall amount">'.price($sous_total_opening_balance).'</td>';
589 }
590 print '<td class="right nowraponall amount">'.price($sous_total_debit).'</td>';
591 print '<td class="right nowraponall amount">'.price($sous_total_credit).'</td>';
592 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
593 print '<td class="right nowraponall amount">'.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit)).'</td>';
594 } else {
595 print '<td class="right nowraponall amount">'.price(price2num($sous_total_debit - $sous_total_credit)).'</td>';
596 }
597 if (!$conf->main_checkbox_left_column) {
598 print "<td></td>\n";
599 }
600 print '</tr>';
601 }
602
603 // Show first line of a break
604 print '<tr class="trforbreak">';
605 print '<td colspan="'.($colspan + 1).'" class="tdforbreak">'.$root_account_number.($root_account_description ? ' - '.$root_account_description : '').'</td>';
606 print '</tr>';
607
608 $displayed_account = $root_account_number;
609 $sous_total_debit = 0;
610 $sous_total_credit = 0;
611 $sous_total_opening_balance = 0;
612 }
613 }
614
615 print '<tr class="oddeven">';
616
617 // Action column
618 if ($conf->main_checkbox_left_column) {
619 print '<td class="center">';
620 print $link;
621 print '</td>';
622 }
623
624 // Accounting account
625 if ($type == 'sub') {
626 print '<td>'.$line->subledger_account.' <span class="opacitymedium">('.$line->subledger_label.')</span></td>';
627 } else {
628 print '<td>'.$accounting_account.'</td>';
629 }
630
631 // Type
632 // TODO Retrieve the type of third party: Customer / Supplier / Employee
633 //if ($type == 'sub') {
634 // print '<td></td>';
635 //}
636
637 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
638 print '<td class="right nowraponall amount">'.price(price2num($opening_balance, 'MT')).'</td>';
639 }
640
641 $urlzoom = '';
642 if ($type == 'sub') {
643 if ($line->subledger_account) {
644 $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);
645 if (GETPOSTISSET('date_startmonth')) {
646 $urlzoom .= '&search_date_startmonth=' . GETPOSTINT('date_startmonth') . '&search_date_startday=' . GETPOSTINT('date_startday') . '&search_date_startyear=' . GETPOSTINT('date_startyear');
647 }
648 if (GETPOSTISSET('date_endmonth')) {
649 $urlzoom .= '&search_date_endmonth=' . GETPOSTINT('date_endmonth') . '&search_date_endday=' . GETPOSTINT('date_endday') . '&search_date_endyear=' . GETPOSTINT('date_endyear');
650 }
651 }
652 } else {
653 if ($line->numero_compte) {
654 $urlzoom = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($line->numero_compte) . '&search_accountancy_code_end=' . urlencode($line->numero_compte);
655 if (GETPOSTISSET('date_startmonth')) {
656 $urlzoom .= '&search_date_startmonth=' . GETPOSTINT('date_startmonth') . '&search_date_startday=' . GETPOSTINT('date_startday') . '&search_date_startyear=' . GETPOSTINT('date_startyear');
657 }
658 if (GETPOSTISSET('date_endmonth')) {
659 $urlzoom .= '&search_date_endmonth=' . GETPOSTINT('date_endmonth') . '&search_date_endday=' . GETPOSTINT('date_endday') . '&search_date_endyear=' . GETPOSTINT('date_endyear');
660 }
661 }
662 }
663 // Debit
664 print '<td class="right nowraponall amount"><a href="'.$urlzoom.'">'.price(price2num($line->debit, 'MT')).'</a></td>';
665 // Credit
666 print '<td class="right nowraponall amount"><a href="'.$urlzoom.'">'.price(price2num($line->credit, 'MT')).'</a></td>';
667
668 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
669 print '<td class="right nowraponall amount">'.price(price2num($opening_balance + $line->debit - $line->credit, 'MT')).'</td>';
670 } else {
671 print '<td class="right nowraponall amount">'.price(price2num($line->debit - $line->credit, 'MT')).'</td>';
672 }
673
674 // Action column
675 if (!$conf->main_checkbox_left_column) {
676 print '<td class="center">';
677 print $link;
678 print '</td>';
679 }
680
681 print "</tr>\n";
682
683 // Records the sub-total
684 $sous_total_debit += $line->debit;
685 $sous_total_credit += $line->credit;
686 $sous_total_opening_balance += $opening_balance;
687 }
688
689 if (!empty($show_subgroup)) {
690 print '<tr class="liste_total">';
691 // Action column
692 if ($conf->main_checkbox_left_column) {
693 print "<td></td>\n";
694 }
695 print '<td class="right">'.$langs->trans("SubTotal").':</td>';
696 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
697 print '<td class="right nowraponall amount">'.price(price2num($sous_total_opening_balance, 'MT')).'</td>';
698 }
699 print '<td class="right nowraponall amount">'.price(price2num($sous_total_debit, 'MT')).'</td>';
700 print '<td class="right nowraponall amount">'.price(price2num($sous_total_credit, 'MT')).'</td>';
701 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
702 print '<td class="right nowraponall amount">' . price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')) . '</td>';
703 } else {
704 print '<td class="right nowraponall amount">' . price(price2num($sous_total_debit - $sous_total_credit, 'MT')) . '</td>';
705 }
706 // Action column
707 if (!$conf->main_checkbox_left_column) {
708 print "<td></td>\n";
709 }
710 print '</tr>';
711 }
712
713 print '<tr class="liste_total">';
714 // Action column
715 if ($conf->main_checkbox_left_column) {
716 print "<td></td>\n";
717 }
718 print '<td class="right">'.$langs->trans("AccountBalance").':</td>';
719 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
720 print '<td class="nowrap right">'.price(price2num($total_opening_balance, 'MT')).'</td>';
721 }
722 print '<td class="right nowraponall amount">'.price(price2num($total_debit, 'MT')).'</td>';
723 print '<td class="right nowraponall amount">'.price(price2num($total_credit, 'MT')).'</td>';
724 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
725 print '<td class="right nowraponall amount">' . price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')) . '</td>';
726 } else {
727 print '<td class="right nowraponall amount">' . price(price2num($total_debit - $total_credit, 'MT')) . '</td>';
728 }
729 // Action column
730 if (!$conf->main_checkbox_left_column) {
731 print "<td></td>\n";
732 }
733 print '</tr>';
734
735 // Accounting result
736 if (getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT')) {
737 print '<tr class="liste_total">';
738 if ($conf->main_checkbox_left_column) {
739 print "<td></td>\n";
740 }
741 print '<td class="right">' . $langs->trans("AccountingResult") . ':</td>';
742 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
743 print '<td></td>';
744 }
745
746 $accountingResult = $object->accountingResult($search_date_start, $search_date_end);
747 if ($accountingResult < 0) {
748 $accountingResultDebit = price(abs((float) price2num($accountingResult, 'MT')));
749 $accountingResultCredit = '';
750 $accountingResultClassCSS = ' error';
751 } else {
752 $accountingResultDebit = '';
753 $accountingResultCredit = price(price2num($accountingResult, 'MT'));
754 $accountingResultClassCSS = ' green';
755 }
756 print '<td class="right nowraponall amount' . $accountingResultClassCSS . '">' . $accountingResultDebit . '</td>';
757 print '<td class="right nowraponall amount' . $accountingResultClassCSS . '">' . $accountingResultCredit . '</td>';
758
759 print '<td></td>';
760 if (!$conf->main_checkbox_left_column) {
761 print "<td></td>\n";
762 }
763 print '</tr>';
764 }
765
766 $parameters = array();
767 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
768 print $hookmanager->resPrint;
769
770 print "</table>";
771 print '</form>';
772}
773
774// End of page
775llxFooter();
776$db->close();
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
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.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
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:73
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 to build sending documents with model Espadon.
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:623
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
GETPOSTDATE($prefix, $hourTime='', $gm='auto', $saverestore='')
Helper function that combines values of a dolibarr DatePicker (such as Form\selectDate) for year,...
print_liste_field_titre($name, $file="", $field="", $begin="", $param="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
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.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='')
Show information in HTML for admin users or standard users.
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 '.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0, $attop=0)
Set event message in dol_events session object.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.