dolibarr 22.0.5
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-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
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
97$object = new BookKeeping($db);
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';
243 $type_export = 'balance';
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="'.$_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'], '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 if (getDolGlobalString('ACCOUNTANCY_COMBO_FOR_AUX')) {
421 $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200');
422 } else {
423 $moreforfilter .= '<input type="text" class="maxwidth150" name="search_accountancy_code_start" value="'.dol_escape_htmltag($search_accountancy_code_start).'" placeholder="'.$langs->trans('From').'">';
424 }
425 } else {
426 $moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200', 'accounts');
427 }
428 $moreforfilter .= ' ';
429 if ($type == 'sub') {
430 if (getDolGlobalString('ACCOUNTANCY_COMBO_FOR_AUX')) {
431 $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200');
432 } else {
433 $moreforfilter .= '<input type="text" class="maxwidth150" name="search_accountancy_code_end" value="'.dol_escape_htmltag($search_accountancy_code_end).'" placeholder="'.$langs->trans('to').'">';
434 }
435 } else {
436 $moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200', 'accounts');
437 }
438 $moreforfilter .= '</div>';
439
440 if (getDolGlobalString('ACCOUNTING_ENABLE_LETTERING')) {
441 $moreforfilter .= '<div class="divsearchfield">';
442 $moreforfilter .= '<label for="notreconciled">'.$langs->trans('NotReconciled').'</label>: ';
443 $moreforfilter .= '<input type="checkbox" name="search_not_reconciled" id="notreconciled" value="notreconciled"'.($search_not_reconciled == 'notreconciled' ? ' checked' : '').'>';
444 $moreforfilter .= '</div>';
445 }
446
447 print '<div class="liste_titre liste_titre_bydiv centpercent">';
448 print $moreforfilter;
449 $parameters = array();
450 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
451 print $hookmanager->resPrint;
452 print '</div>';
453
454
455 $colspan = (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE') ? 5 : 4);
456
457 print '<table class="liste '.($moreforfilter ? "listwithfilterbefore" : "").'">';
458
459 print '<tr class="liste_titre_filter">';
460
461 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
462 print '<td class="liste_titre maxwidthsearch">';
463 $searchpicto = $form->showFilterButtons();
464 print $searchpicto;
465 print '</td>';
466 }
467
468 print '<td class="liste_titre" colspan="'.$colspan.'">';
469 print '</td>';
470
471 // Fields from hook
472 $parameters = array();
473 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
474 print $hookmanager->resPrint;
475
476 // Action column
477 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
478 print '<td class="liste_titre maxwidthsearch">';
479 $searchpicto = $form->showFilterButtons();
480 print $searchpicto;
481 print '</td>';
482 }
483 print '</tr>'."\n";
484
485 print '<tr class="liste_titre">';
486 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
487 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
488 }
489 print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder);
490 // TODO : Retrieve the type of third party: Customer / Supplier / Employee
491 //if ($type == 'sub') {
492 // print_liste_field_titre("Type", $_SERVER['PHP_SELF'], "t.type", "", $param, "", $sortfield, $sortorder);
493 //}
494 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
495 print_liste_field_titre("OpeningBalance", $_SERVER['PHP_SELF'], "", "", $param, 'class="right"', $sortfield, $sortorder);
496 }
497 print_liste_field_titre("AccountingDebit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder);
498 print_liste_field_titre("AccountingCredit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder);
499 print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder);
500
501 // Hook fields
502 $parameters = array('param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder);
503 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook
504 print $hookmanager->resPrint;
505 // Action column
506 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
507 print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
508 }
509 print '</tr>'."\n";
510
511 $total_debit = 0;
512 $total_credit = 0;
513 $sous_total_debit = 0;
514 $sous_total_credit = 0;
515 $total_opening_balance = 0;
516 $sous_total_opening_balance = 0;
517 $displayed_account = "";
518
519 $accountingaccountstatic = new AccountingAccount($db);
520
521 // TODO Debug - This feature is dangerous, it takes all the entries and adds all the accounts
522 // without time and class limits (Class 6 and 7 accounts ???) and does not take into account the "a-nouveau" journal.
523 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
524 $sql = "SELECT t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance";
525 $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as t";
526 $sql .= " WHERE t.entity = " . $conf->entity; // Never do sharing into accounting features
527 $sql .= " AND t.doc_date < '" . $db->idate($search_date_start) . "'";
528 $sql .= " GROUP BY t.numero_compte";
529
530 $resql = $db->query($sql);
531 $opening_balances = array();
532 if ($resql) {
533 $nrows = $db->num_rows($resql);
534 for ($i = 0; $i < $nrows; $i++) {
535 $arr = $db->fetch_array($resql);
536 if (is_array($arr)) {
537 $opening_balances["'" . $arr['numero_compte'] . "'"] = $arr['opening_balance'];
538 }
539 }
540 } else {
541 dol_print_error($db);
542 }
543 }
544
545 foreach ($object->lines as $line) {
546 // reset before the fetch (in case of the fetch fails)
547 $accountingaccountstatic->id = 0;
548 $accountingaccountstatic->account_number = '';
549 $accounting_account = '';
550
551 if ($type != 'sub') {
552 $accountingaccountstatic->fetch(0, $line->numero_compte, true);
553 if (!empty($accountingaccountstatic->account_number)) {
554 $accounting_account = $accountingaccountstatic->getNomUrl(0, 1, 1);
555 } else {
556 $accounting_account = length_accountg($line->numero_compte);
557 }
558 }
559
560 $link = '';
561 $total_debit += $line->debit;
562 $total_credit += $line->credit;
563 $opening_balance = isset($opening_balances["'".$line->numero_compte."'"]) ? $opening_balances["'".$line->numero_compte."'"] : 0;
564 $total_opening_balance += $opening_balance;
565
566 $tmparrayforrootaccount = $object->getRootAccount($line->numero_compte);
567 $root_account_description = $tmparrayforrootaccount['label'];
568 $root_account_number = $tmparrayforrootaccount['account_number'];
569
570 //var_dump($tmparrayforrootaccount);
571 //var_dump($accounting_account);
572 //var_dump($accountingaccountstatic);
573 if (empty($accountingaccountstatic->label) && $accountingaccountstatic->id > 0) {
574 $link = '<a class="editfielda reposition" href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=update&token=' . newToken() . '&id=' . $accountingaccountstatic->id . '">' . img_edit() . '</a>';
575 } elseif ($accounting_account == 'NotDefined') {
576 $link = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=create&token=' . newToken() . '&accountingaccount=' . length_accountg($line->numero_compte) . '">' . img_edit_add() . '</a>';
577 } /* elseif (empty($tmparrayforrootaccount['label'])) {
578 // $tmparrayforrootaccount['label'] not defined = the account has not parent with a parent.
579 // This is useless, we should not create a new account when an account has no parent, we must edit it to fix its parent.
580 // 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.
581 // BUG 2: Adding a link to create a new accounting account here is useless because it is not add as parent of the orphelin.
582 //$link = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/card.php?action=create&token=' . newToken() . '&accountingaccount=' . length_accountg($line->numero_compte) . '">' . img_edit_add() . '</a>';
583 } */
584
585 if (!empty($show_subgroup)) {
586 // Show accounting account
587 if (empty($displayed_account) || $root_account_number != $displayed_account) {
588 // Show subtotal per accounting account
589 if ($displayed_account != "") {
590 print '<tr class="liste_total">';
591 print '<td class="right">'.$langs->trans("SubTotal").':</td>';
592 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
593 print '<td></td>';
594 }
595 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
596 print '<td class="right nowraponall amount">'.price($sous_total_opening_balance).'</td>';
597 }
598 print '<td class="right nowraponall amount">'.price($sous_total_debit).'</td>';
599 print '<td class="right nowraponall amount">'.price($sous_total_credit).'</td>';
600 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
601 print '<td class="right nowraponall amount">'.price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit)).'</td>';
602 } else {
603 print '<td class="right nowraponall amount">'.price(price2num($sous_total_debit - $sous_total_credit)).'</td>';
604 }
605 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
606 print "<td></td>\n";
607 }
608 print '</tr>';
609 }
610
611 // Show first line of a break
612 print '<tr class="trforbreak">';
613 print '<td colspan="'.($colspan + 1).'" class="tdforbreak">'.$root_account_number.($root_account_description ? ' - '.$root_account_description : '').'</td>';
614 print '</tr>';
615
616 $displayed_account = $root_account_number;
617 $sous_total_debit = 0;
618 $sous_total_credit = 0;
619 $sous_total_opening_balance = 0;
620 }
621 }
622
623 print '<tr class="oddeven">';
624
625 // Action column
626 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
627 print '<td class="center">';
628 print $link;
629 print '</td>';
630 }
631
632 // Accounting account
633 if ($type == 'sub') {
634 print '<td>'.$line->subledger_account.' <span class="opacitymedium">('.$line->subledger_label.')</span></td>';
635 } else {
636 print '<td>'.$accounting_account.'</td>';
637 }
638
639 // Type
640 // TODO Retrieve the type of third party: Customer / Supplier / Employee
641 //if ($type == 'sub') {
642 // print '<td></td>';
643 //}
644
645 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
646 print '<td class="right nowraponall amount">'.price(price2num($opening_balance, 'MT')).'</td>';
647 }
648
649 $urlzoom = '';
650 if ($type == 'sub') {
651 if ($line->subledger_account) {
652 $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);
653 if (GETPOSTISSET('date_startmonth')) {
654 $urlzoom .= '&search_date_startmonth=' . GETPOSTINT('date_startmonth') . '&search_date_startday=' . GETPOSTINT('date_startday') . '&search_date_startyear=' . GETPOSTINT('date_startyear');
655 }
656 if (GETPOSTISSET('date_endmonth')) {
657 $urlzoom .= '&search_date_endmonth=' . GETPOSTINT('date_endmonth') . '&search_date_endday=' . GETPOSTINT('date_endday') . '&search_date_endyear=' . GETPOSTINT('date_endyear');
658 }
659 }
660 } else {
661 if ($line->numero_compte) {
662 $urlzoom = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($line->numero_compte) . '&search_accountancy_code_end=' . urlencode($line->numero_compte);
663 if (GETPOSTISSET('date_startmonth')) {
664 $urlzoom .= '&search_date_startmonth=' . GETPOSTINT('date_startmonth') . '&search_date_startday=' . GETPOSTINT('date_startday') . '&search_date_startyear=' . GETPOSTINT('date_startyear');
665 }
666 if (GETPOSTISSET('date_endmonth')) {
667 $urlzoom .= '&search_date_endmonth=' . GETPOSTINT('date_endmonth') . '&search_date_endday=' . GETPOSTINT('date_endday') . '&search_date_endyear=' . GETPOSTINT('date_endyear');
668 }
669 }
670 }
671 // Debit
672 print '<td class="right nowraponall amount"><a href="'.$urlzoom.'">'.price(price2num($line->debit, 'MT')).'</a></td>';
673 // Credit
674 print '<td class="right nowraponall amount"><a href="'.$urlzoom.'">'.price(price2num($line->credit, 'MT')).'</a></td>';
675
676 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
677 print '<td class="right nowraponall amount">'.price(price2num($opening_balance + $line->debit - $line->credit, 'MT')).'</td>';
678 } else {
679 print '<td class="right nowraponall amount">'.price(price2num($line->debit - $line->credit, 'MT')).'</td>';
680 }
681
682 // Action column
683 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
684 print '<td class="center">';
685 print $link;
686 print '</td>';
687 }
688
689 print "</tr>\n";
690
691 // Records the sub-total
692 $sous_total_debit += $line->debit;
693 $sous_total_credit += $line->credit;
694 $sous_total_opening_balance += $opening_balance;
695 }
696
697 if (!empty($show_subgroup)) {
698 print '<tr class="liste_total">';
699 // Action column
700 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
701 print "<td></td>\n";
702 }
703 print '<td class="right">'.$langs->trans("SubTotal").':</td>';
704 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
705 print '<td class="right nowraponall amount">'.price(price2num($sous_total_opening_balance, 'MT')).'</td>';
706 }
707 print '<td class="right nowraponall amount">'.price(price2num($sous_total_debit, 'MT')).'</td>';
708 print '<td class="right nowraponall amount">'.price(price2num($sous_total_credit, 'MT')).'</td>';
709 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
710 print '<td class="right nowraponall amount">' . price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')) . '</td>';
711 } else {
712 print '<td class="right nowraponall amount">' . price(price2num($sous_total_debit - $sous_total_credit, 'MT')) . '</td>';
713 }
714 // Action column
715 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
716 print "<td></td>\n";
717 }
718 print '</tr>';
719 }
720
721 print '<tr class="liste_total">';
722 // Action column
723 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
724 print "<td></td>\n";
725 }
726 print '<td class="right">'.$langs->trans("AccountBalance").':</td>';
727 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
728 print '<td class="nowrap right">'.price(price2num($total_opening_balance, 'MT')).'</td>';
729 }
730 print '<td class="right nowraponall amount">'.price(price2num($total_debit, 'MT')).'</td>';
731 print '<td class="right nowraponall amount">'.price(price2num($total_credit, 'MT')).'</td>';
732 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
733 print '<td class="right nowraponall amount">' . price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')) . '</td>';
734 } else {
735 print '<td class="right nowraponall amount">' . price(price2num($total_debit - $total_credit, 'MT')) . '</td>';
736 }
737 // Action column
738 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
739 print "<td></td>\n";
740 }
741 print '</tr>';
742
743 // Accounting result
744 if (getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT')) {
745 print '<tr class="liste_total">';
746 if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
747 print "<td></td>\n";
748 }
749 print '<td class="right">' . $langs->trans("AccountingResult") . ':</td>';
750 if (getDolGlobalString('ACCOUNTANCY_SHOW_OPENING_BALANCE')) {
751 print '<td></td>';
752 }
753
754 $accountingResult = $object->accountingResult($search_date_start, $search_date_end);
755 if ($accountingResult < 0) {
756 $accountingResultDebit = price(abs((float) price2num($accountingResult, 'MT')));
757 $accountingResultCredit = '';
758 $accountingResultClassCSS = ' error';
759 } else {
760 $accountingResultDebit = '';
761 $accountingResultCredit = price(price2num($accountingResult, 'MT'));
762 $accountingResultClassCSS = ' green';
763 }
764 print '<td class="right nowraponall amount' . $accountingResultClassCSS . '">' . $accountingResultDebit . '</td>';
765 print '<td class="right nowraponall amount' . $accountingResultClassCSS . '">' . $accountingResultCredit . '</td>';
766
767 print '<td></td>';
768 if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
769 print "<td></td>\n";
770 }
771 print '</tr>';
772 }
773
774 $parameters = array();
775 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
776 print $hookmanager->resPrint;
777
778 print "</table>";
779 print '</form>';
780}
781
782// End of page
783llxFooter();
784$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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:619
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
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.
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.
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.
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'.
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.