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