dolibarr 24.0.0-beta
account.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
3 * Copyright (C) 2013-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
4 * Copyright (C) 2016-2018 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
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';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
40require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
41
42// Load translation files required by the page
43$langs->loadLangs(array('accountancy', 'admin', 'bills', 'compta', 'salaries'));
44
45$action = GETPOST('action', 'aZ09');
46$cancel = GETPOST('cancel', 'alpha');
48$rowid = GETPOSTINT('rowid');
49$massaction = GETPOST('massaction', 'aZ09');
50$optioncss = GETPOST('optioncss', 'alpha');
51$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'accountingaccountlist'; // To manage different context of search
52$mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
53
54$search_account = GETPOST('search_account', 'alpha');
55$search_label = GETPOST('search_label', 'alpha');
56$search_labelshort = GETPOST('search_labelshort', 'alpha');
57$search_accountparent = GETPOST('search_accountparent', 'alpha');
58$search_pcgtype = GETPOST('search_pcgtype', 'alpha');
59$search_import_key = GETPOST('search_import_key', 'alpha');
60$search_reconcilable = GETPOST("search_reconcilable", 'int');
61$search_centralized = GETPOST("search_centralized", 'int');
62$search_active = GETPOST("search_active", 'int');
63$toselect = GETPOST('toselect', 'array:int');
64$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
65$confirm = GETPOST('confirm', 'alpha');
66
67$chartofaccounts = GETPOSTINT('chartofaccounts');
68
69$permissiontoadd = $user->hasRight('accounting', 'chartofaccount');
70$permissiontodelete = $user->hasRight('accounting', 'chartofaccount');
71
72// Security check
73if ($user->socid > 0) {
75}
76if (!$permissiontoadd) {
78}
79// now $permissiontoadd or $user->hasRight('accounting', 'chartofaccount') are always equal to 1
80
81// Load variable for pagination
82$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
83$sortfield = GETPOST('sortfield', 'aZ09comma');
84$sortorder = GETPOST('sortorder', 'aZ09comma');
85$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT('page');
86if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
87 // If $page is not defined, or '' or -1 or if we click on clear filters
88 $page = 0;
89}
90$offset = $limit * $page;
91$pageprev = $page - 1;
92$pagenext = $page + 1;
93if (!$sortfield) {
94 $sortfield = "aa.account_number";
95}
96if (!$sortorder) {
97 $sortorder = "ASC";
98}
99
101
102$arrayfields = array(
103 'aa.account_number' => array('label' => "AccountNumber", 'checked' => '1', 'csslist' => 'maxwidth50'),
104 'aa.label' => array('label' => "Label", 'checked' => '1'),
105 'aa.labelshort' => array('label' => "ShortLabel", 'checked' => '1'),
106 'aa.account_parent' => array('label' => "Accountparent", 'checked' => '1'),
107 'aa.pcg_type' => array('label' => "Pcgtype", 'checked' => '1', 'help' => 'PcgtypeDesc'),
108 'categories' => array('label' => "AccountingCategories", 'checked' => '-1', 'help' => 'AccountingCategoriesDesc'),
109 'aa.reconcilable' => array('label' => "Reconcilable", 'checked' => '1'),
110 'aa.centralized' => array('label' => "Centralized", 'checked' => '1', 'help' => 'CentralizedAccountHelp'),
111 'aa.import_key' => array('label' => "ImportId", 'checked' => '-1', 'help' => ''),
112 'aa.active' => array('label' => "Activated", 'checked' => '1')
113);
114
115if (!getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
116 unset($arrayfields['categories']);
117 unset($arrayfields['aa.reconcilable']);
118}
119
120$accounting = new AccountingAccount($db);
121
122// Initialize a technical object to manage hooks. Note that conf->hooks_modules contains array
123$hookmanager->initHooks(array('accountancyadminaccount'));
124
125
126/*
127 * Actions
128 */
129
130if (GETPOST('cancel', 'alpha')) {
131 $action = 'list';
132 $massaction = '';
133}
134if (!GETPOST('confirmmassaction', 'alpha')) {
135 $massaction = '';
136}
137
138$parameters = array('chartofaccounts' => $chartofaccounts, 'permissiontoadd' => $permissiontoadd, 'permissiontodelete' => $permissiontodelete);
139$reshook = $hookmanager->executeHooks('doActions', $parameters, $accounting, $action); // Note that $action and $object may have been monowraponalldified by some hooks
140if ($reshook < 0) {
141 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
142}
143
144if (empty($reshook)) {
145 if (!empty($cancel)) {
146 $action = '';
147 }
148
149 $objectclass = 'AccountingAccount';
150 $uploaddir = $conf->accounting->multidir_output[$conf->entity];
151 include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
152
153 if ($action == "delete") {
154 $action = "";
155 }
156 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
157
158 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers
159 $search_account = "";
160 $search_label = "";
161 $search_labelshort = "";
162 $search_accountparent = "";
163 $search_pcgtype = "";
164 $search_import_key = "";
165 $search_reconcilable = "";
166 $search_centralized = "";
167 $search_active = "";
168 $search_array_options = array();
169 }
170 if ((GETPOSTINT('valid_change_chart') && GETPOSTINT('chartofaccounts') > 0) // explicit click on button 'Change and load' with js on
171 || (GETPOSTINT('chartofaccounts') > 0 && GETPOSTINT('chartofaccounts') != getDolGlobalInt('CHARTOFACCOUNTS'))) { // a submit of form is done and chartofaccounts combo has been modified
172 $error = 0;
173
174 if ($chartofaccounts > 0 /* && $permissiontoadd */) {
175 $country_code = '';
176 // Get language code for this $chartofaccounts
177 $sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'c_country as c, '.MAIN_DB_PREFIX.'accounting_system as a';
178 $sql .= ' WHERE c.rowid = a.fk_country AND a.rowid = '.(int) $chartofaccounts;
179 $resql = $db->query($sql);
180 if ($resql) {
181 $obj = $db->fetch_object($resql);
182 if ($obj) {
183 $country_code = $obj->code;
184 }
185 } else {
187 }
188
189 // Try to load sql file
190 if ($country_code) {
191 $sqlfile = DOL_DOCUMENT_ROOT.'/install/mysql/data/llx_accounting_account_'.strtolower($country_code).'.sql';
192
193 $offsetforchartofaccount = 0;
194 // Get the comment line '-- ADD CCCNNNNN to rowid...' to find CCCNNNNN (CCC is country num, NNNNN is id of accounting account)
195 // and pass CCCNNNNN + (num of company * 100 000 000) as offset to the run_sql as a new parameter to say to update sql on the fly to add offset to rowid and account_parent value.
196 // This is to be sure there is no conflict for each chart of account, whatever is country, whatever is company when multicompany is used.
197 $tmp = file_get_contents($sqlfile);
198 $reg = array();
199 if (preg_match('/-- ADD (\d+) to rowid/ims', $tmp, $reg)) {
200 $offsetforchartofaccount += $reg[1];
201 }
202 $offsetforchartofaccount += ($conf->entity * 100000000);
203
204 $result = run_sql($sqlfile, 1, $conf->entity, 1, '', 'default', 32768, 0, $offsetforchartofaccount);
205
206 if ($result > 0) {
207 setEventMessages($langs->trans("ChartLoaded"), null, 'mesgs');
208 } else {
209 setEventMessages($langs->trans("ErrorDuringChartLoad"), null, 'warnings');
210 }
211 }
212
213 if (!dolibarr_set_const($db, 'CHARTOFACCOUNTS', $chartofaccounts, 'chaine', 0, '', $conf->entity)) {
214 $error++;
215 }
216 } else {
217 $error++;
218 }
219 }
220
221 if ($action == 'disable' /* && $permissiontoadd */) {
222 if ($accounting->fetch($id)) {
223 $mode = GETPOSTINT('mode');
224 $result = $accounting->accountDeactivate($id, $mode);
225 if ($result < 0) {
226 setEventMessages($accounting->error, $accounting->errors, 'errors');
227 }
228 }
229
230 $action = 'update';
231 } elseif ($action == 'enable' /* && $permissiontoadd */) {
232 if ($accounting->fetch($id)) {
233 $mode = GETPOSTINT('mode');
234 // Block the activation of matching on a centralized account
235 if ($mode == 1 && !empty($accounting->centralized)) {
236 setEventMessages($langs->trans('CentralizedAccountCannotBeMatchable'), null, 'errors');
237 } else {
238 $result = $accounting->accountActivate($id, $mode);
239 if ($result < 0) {
240 setEventMessages($accounting->error, $accounting->errors, 'errors');
241 }
242 // When activating centralized mode, force matchable to 0
243 if ($mode == 2 && $result >= 0) {
244 $result = $accounting->accountDeactivate($id, 1);
245 if ($result < 0) {
246 setEventMessages($accounting->error, $accounting->errors, 'errors');
247 }
248 }
249 }
250 }
251 $action = 'update';
252 }
253}
254
255
256/*
257 * View
258 */
259$form = new Form($db);
260$formaccounting = new FormAccounting($db);
261
262$help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
263
264llxHeader('', $langs->trans("ListAccounts"), $help_url, '', 0, 0, '', '', '', 'mod-accountancy page-admin_account');
265
266if ($action == 'delete') {
267 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$id, $langs->trans('DeleteAccount'), $langs->trans('ConfirmDeleteAccount'), 'confirm_delete', '', 0, 1);
268 print $formconfirm;
269}
270
271$pcgver = getDolGlobalInt('CHARTOFACCOUNTS');
272
273$sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.account_number, aa.account_parent, aa.label, aa.labelshort, aa.fk_accounting_category,";
274if (getDolGlobalInt('ACCOUNTING_ENABLE_MULTI_REPORT')) {
275 $sql .= " (SELECT COUNT(*) FROM ".MAIN_DB_PREFIX."accounting_category_account aca WHERE aca.fk_accounting_account = aa.rowid) as nb_categories,";
276}
277$sql .= " aa.reconcilable, aa.centralized, aa.active, aa.import_key,";
278$sql .= " a2.rowid as rowid2, a2.label as label2, a2.account_number as account_number2";
279
280// Add fields from hooks
281$parameters = array();
282$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
283$sql .= $hookmanager->resPrint;
284$sql = preg_replace('/,\s*$/', '', $sql);
285
286$sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
287$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version AND aa.entity = ".((int) $conf->entity);
288$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as a2 ON a2.rowid = aa.account_parent AND a2.entity = ".((int) $conf->entity);
289
290// Add table from hooks
291$parameters = array();
292$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
293$sql .= $hookmanager->resPrint;
294
295$sql .= " WHERE asy.rowid = ".((int) $pcgver);
296
297if (strlen(trim($search_account))) {
298 $lengthpaddingaccount = 0;
299 if (getDolGlobalInt('ACCOUNTING_LENGTH_GACCOUNT') || getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT')) {
300 $lengthpaddingaccount = max(getDolGlobalInt('ACCOUNTING_LENGTH_GACCOUNT'), getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT'));
301 }
302 $search_account_tmp = $search_account;
303 $weremovedsomezero = 0;
304 if (strlen($search_account_tmp) <= $lengthpaddingaccount) {
305 for ($i = 0; $i < $lengthpaddingaccount; $i++) {
306 if (preg_match('/0$/', $search_account_tmp)) {
307 $weremovedsomezero++;
308 $search_account_tmp = preg_replace('/0$/', '', $search_account_tmp);
309 }
310 }
311 }
312
313 //var_dump($search_account); exit;
314 if ($search_account_tmp) {
315 if ($weremovedsomezero) {
316 $search_account_tmp_clean = $search_account_tmp;
317 $search_account_clean = $search_account;
318 $startchar = '%';
319 if (substr($search_account_tmp, 0, 1) === '^') {
320 $startchar = '';
321 $search_account_tmp_clean = preg_replace('/^\^/', '', $search_account_tmp);
322 $search_account_clean = preg_replace('/^\^/', '', $search_account);
323 }
324 $sql .= " AND (aa.account_number LIKE '".$db->escape($startchar.$search_account_tmp_clean)."'";
325 $sql .= " OR aa.account_number LIKE '".$db->escape($startchar.$search_account_clean)."%')";
326 } else {
327 $sql .= natural_search("aa.account_number", $search_account_tmp);
328 }
329 }
330}
331if (strlen(trim($search_label))) {
332 $sql .= natural_search("aa.label", $search_label);
333}
334if (strlen(trim($search_labelshort))) {
335 $sql .= natural_search("aa.labelshort", $search_labelshort);
336}
337if (strlen(trim($search_accountparent)) && $search_accountparent != '-1') {
338 $sql .= natural_search("aa.account_parent", $search_accountparent, 2);
339}
340if (strlen(trim($search_pcgtype))) {
341 $sql .= natural_search("aa.pcg_type", $search_pcgtype);
342}
343if ($search_reconcilable != '' && $search_reconcilable != '-1') {
344 $sql .= " AND aa.reconcilable = ".((int) $search_reconcilable);
345}
346if ($search_centralized != '' && $search_centralized != '-1') {
347 $sql .= " AND aa.centralized = ".((int) $search_centralized);
348}
349if ($search_active != '' && $search_active != '-1') {
350 $sql .= " AND aa.active = ".((int) $search_active);
351}
352if (strlen(trim($search_import_key))) {
353 $sql .= natural_search("aa.import_key", $search_import_key);
354}
355
356// Add where from hooks
357$parameters = array();
358$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
359$sql .= $hookmanager->resPrint;
360
361$sql .= $db->order($sortfield, $sortorder);
362//print $sql;
363
364// Count total nb of records
365$nbtotalofrecords = '';
366if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
367 $resql = $db->query($sql);
368 $nbtotalofrecords = $db->num_rows($resql);
369 if (($page * $limit) > (int) $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
370 $page = 0;
371 $offset = 0;
372 }
373}
374
375$sql .= $db->plimit($limit + 1, $offset);
376
377dol_syslog("accountancy/admin/account.php:: sql=".$sql);
378$resql = $db->query($sql);
379
380if ($resql) {
381 $num = $db->num_rows($resql);
382
383 $arrayofselected = is_array($toselect) ? $toselect : array();
384
385 $param = '';
386 // if null contextpage is forced to 'accountingaccountlist' so never empty
387 if (/* !empty($contextpage) && */$contextpage != $_SERVER["PHP_SELF"]) {
388 $param .= '&contextpage='.urlencode($contextpage);
389 }
390 if ($limit > 0 && $limit != $conf->liste_limit) {
391 $param .= '&limit='.((int) $limit);
392 }
393 if ($search_account) {
394 $param .= '&search_account='.urlencode($search_account);
395 }
396 if ($search_label) {
397 $param .= '&search_label='.urlencode($search_label);
398 }
399 if ($search_labelshort) {
400 $param .= '&search_labelshort='.urlencode($search_labelshort);
401 }
402 if ($search_accountparent > 0 || $search_accountparent == '0') {
403 $param .= '&search_accountparent='.urlencode($search_accountparent);
404 }
405 if ($search_pcgtype) {
406 $param .= '&search_pcgtype='.urlencode($search_pcgtype);
407 }
408 if ($search_import_key) {
409 $param .= '&search_import_key='.urlencode($search_import_key);
410 }
411 if ($optioncss != '') {
412 $param .= '&optioncss='.urlencode($optioncss);
413 }
414
415 // Add $param from hooks
416 $parameters = array();
417 $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
418 $param .= $hookmanager->resPrint;
419
420 if (!empty($conf->use_javascript_ajax)) {
421 print '<!-- Add javascript to reload page when we click "Change plan" -->
422 <script type="text/javascript">
423 $(document).ready(function () {
424 $("#change_chart").on("click", function (e) {
425 console.log("chartofaccounts selected = "+$("#chartofaccounts").val());
426 // reload page
427 window.location.href = "'.$_SERVER["PHP_SELF"].'?valid_change_chart=1&chartofaccounts="+$("#chartofaccounts").val();
428 });
429 });
430 </script>';
431 }
432
433 // List of mass actions available
434 $arrayofmassactions = array();
435 // if ($permissiontoadd) { // test is always true
436 $arrayofmassactions['predelete'] = '<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
437 // }
438 if (in_array($massaction, array('presend', 'predelete', 'closed'))) {
439 $arrayofmassactions = array();
440 }
441
442 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
443
444 $newcardbutton = '';
445 $newcardbutton = dolGetButtonTitle($langs->trans('Addanaccount'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/accountancy/admin/card.php?action=create', '', $permissiontoadd);
446
447
448 print '<form method="POST" id="searchFormList" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
449 if ($optioncss != '') {
450 print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
451 }
452 print '<input type="hidden" name="token" value="'.newToken().'">';
453 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
454 print '<input type="hidden" name="action" value="list">';
455 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
456 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
457 print '<input type="hidden" name="page" value="'.$page.'">';
458 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
459 print '<input type="hidden" name="page_y" value="">';
460
461 // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
462 print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'accounting_account', 0, $newcardbutton, '', $limit, 0, 0, 1);
463
464 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
465
466 print '<div class="neutral">';
467
468 // Box to select active chart of account
469 print $langs->trans("Selectchartofaccounts")." : ";
470 print '<select class="flat minwidth200" name="chartofaccounts" id="chartofaccounts">';
471 $sql = "SELECT a.rowid, a.pcg_version, a.label, a.active, c.code as country_code";
472 $sql .= " FROM ".MAIN_DB_PREFIX."accounting_system as a";
473 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON a.fk_country = c.rowid AND c.active = 1";
474 $sql .= " WHERE a.active = 1";
475 $sql .= " ORDER BY c.code, a.pcg_version";
476
477 dol_syslog("accountancy/admin/account.php sql=".$sql);
478
479 $resqlchart = $db->query($sql);
480 if ($resqlchart) {
481 $numbis = $db->num_rows($resqlchart);
482 $i = 0;
483 print '<option value="-1">&nbsp;</option>';
484 while ($i < $numbis) {
485 $obj = $db->fetch_object($resqlchart);
486 if ($obj) {
487 $labeltoshow = $obj->country_code.' - '.$obj->pcg_version.' - '.$obj->label;
488 $htmltoshow = picto_from_langcode($obj->country_code).' '.$obj->country_code.' - '.$obj->pcg_version.' <span class="opacitymedium">- '.$obj->label.'</span>';
489 print '<option value="'.$obj->rowid.'" data-html="'.dolPrintHTMLForAttribute($htmltoshow).'"';
490 print ($pcgver == $obj->rowid) ? ' selected' : '';
491 print '>'.$labeltoshow.'</option>';
492 }
493 $i++;
494 }
495 } else {
497 }
498 print "</select>";
499 print ajax_combobox("chartofaccounts");
500 print '<input type="'.(empty($conf->use_javascript_ajax) ? 'submit' : 'button').'" class="button button-edit small" name="change_chart" id="change_chart" value="'.dol_escape_htmltag($langs->trans("ChangeAndLoad")).'">';
501
502 print '</div>';
503
504 $parameters = array('chartofaccounts' => $chartofaccounts, 'permissiontoadd' => $permissiontoadd, 'permissiontodelete' => $permissiontodelete);
505 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $accounting, $action); // Note that $action and $object may have been modified by hook
506 print $hookmanager->resPrint;
507
508 $parameters = array();
509 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
510 print $hookmanager->resPrint;
511
512 print '<br>';
513
514 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
515 $htmlofselectarray = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, $conf->main_checkbox_left_column); // This also change content of $arrayfields with user setup
516 $selectedfields = ($mode != 'kanban' ? $htmlofselectarray : '');
517 $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
518
519 $accountstatic = new AccountingAccount($db);
520 $accountparent = new AccountingAccount($db);
521 $totalarray = array();
522 $totalarray['nbfield'] = 0;
523
524 $moreforfilter = '';
525 // if ($moreforfilter) {
526 // print '<div class="liste_titre liste_titre_bydiv centpercent">';
527 // print $moreforfilter;
528 // print '</div>';
529 // }
530
531 print '<div class="div-table-responsive">';
532 // print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
533 print '<table class="tagtable liste">'."\n";
534
535 // Fields title search
536 // --------------------------------------------------------------------
537 print '<tr class="liste_titre_filter">';
538
539 // Action column
540 if ($conf->main_checkbox_left_column) {
541 print '<td class="liste_titre center maxwidthsearch">';
542 $searchpicto = $form->showFilterButtons('left');
543 print $searchpicto;
544 print '</td>';
545 }
546 if (!empty($arrayfields['aa.account_number']['checked'])) {
547 print '<td class="liste_titre"><input type="text" class="flat width75" name="search_account" value="'.$search_account.'"></td>';
548 }
549 if (!empty($arrayfields['aa.label']['checked'])) {
550 print '<td class="liste_titre"><input type="text" class="flat width100" name="search_label" value="'.$search_label.'"></td>';
551 }
552 if (!empty($arrayfields['aa.labelshort']['checked'])) {
553 print '<td class="liste_titre"><input type="text" class="flat width100" name="search_labelshort" value="'.$search_labelshort.'"></td>';
554 }
555 if (!empty($arrayfields['aa.account_parent']['checked'])) {
556 print '<td class="liste_titre">';
557 print $formaccounting->select_account($search_accountparent, 'search_accountparent', 2, array(), 0, 0, 'maxwidth150');
558 print '</td>';
559 }
560 // Predefined group
561 if (!empty($arrayfields['aa.pcg_type']['checked'])) {
562 print '<td class="liste_titre"><input type="text" class="flat width75" name="search_pcgtype" value="'.$search_pcgtype.'"></td>';
563 }
564 // Custom groups
565 if (!empty($arrayfields['categories']['checked'])) {
566 print '<td class="liste_titre"></td>';
567 }
568
569 // Fields from hook
570 $parameters = array('arrayfields' => $arrayfields);
571 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
572 print $hookmanager->resPrint;
573
574 // Import key
575 if (!empty($arrayfields['aa.import_key']['checked'])) {
576 print '<td class="liste_titre"><input type="text" class="flat width75" name="search_import_key" value="'.$search_import_key.'"></td>';
577 }
578
579 // Reconcilable
580 if (!empty($arrayfields['aa.reconcilable']['checked'])) {
581 print '<td class="liste_titre center">';
582 print $form->selectyesno('search_reconcilable', $search_reconcilable, 1, false, 1, 1, 'search_status onrightofpage width75');
583 print '</td>';
584 }
585
586 // Centralized
587 if (!empty($arrayfields['aa.centralized']['checked'])) {
588 print '<td class="liste_titre center">';
589 print $form->selectyesno('search_centralized', $search_centralized, 1, false, 1, 1, 'search_status onrightofpage width75');
590 print '</td>';
591 }
592
593 // Active
594 if (!empty($arrayfields['aa.active']['checked'])) {
595 print '<td class="liste_titre center parentonrightofpage">';
596 print $form->selectyesno('search_active', $search_active, 1, false, 1, 1, 'search_status onrightofpage width75');
597 print '</td>';
598 }
599
600 // Action column
601 if (!$conf->main_checkbox_left_column) {
602 print '<td class="liste_titre center maxwidthsearch">';
603 $searchpicto = $form->showFilterButtons();
604 print $searchpicto;
605 print '</td>';
606 }
607 print '</tr>'."\n";
608
609 $totalarray = array();
610 $totalarray['nbfield'] = 0;
611
612 // Fields title label
613 // --------------------------------------------------------------------
614 print '<tr class="liste_titre">';
615 // Action column
616 if ($conf->main_checkbox_left_column) {
617 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch actioncolumn ');
618 $totalarray['nbfield']++;
619 }
620 if (!empty($arrayfields['aa.account_number']['checked'])) {
621 print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder);
622 $totalarray['nbfield']++;
623 }
624 if (!empty($arrayfields['aa.label']['checked'])) {
625 print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"], "aa.label", "", $param, '', $sortfield, $sortorder);
626 $totalarray['nbfield']++;
627 }
628 if (!empty($arrayfields['aa.labelshort']['checked'])) {
629 print_liste_field_titre($arrayfields['aa.labelshort']['label'], $_SERVER["PHP_SELF"], "aa.labelshort", "", $param, '', $sortfield, $sortorder);
630 $totalarray['nbfield']++;
631 }
632 if (!empty($arrayfields['aa.account_parent']['checked'])) {
633 print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"], "aa.account_parent", "", $param, '', $sortfield, $sortorder, 'left ');
634 $totalarray['nbfield']++;
635 }
636 // Main group
637 if (!empty($arrayfields['aa.pcg_type']['checked'])) {
638 print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_type,aa.account_number', '', $param, '', $sortfield, $sortorder, 'right ', $arrayfields['aa.pcg_type']['help'].'::-1', 1);
639 $totalarray['nbfield']++;
640 }
641 // Number of custom groups
642 if (!empty($arrayfields['categories']['checked'])) {
643 print_liste_field_titre($arrayfields['categories']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '', $arrayfields['categories']['help'].'::-1', 1);
644 $totalarray['nbfield']++;
645 }
646
647 // Hook fields
648 $parameters = array('arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder);
649 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
650 print $hookmanager->resPrint;
651
652 if (!empty($arrayfields['aa.import_key']['checked'])) {
653 print_liste_field_titre($arrayfields['aa.import_key']['label'], $_SERVER["PHP_SELF"], 'aa.import_key', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.import_key']['help'].'::-1', 1);
654 $totalarray['nbfield']++;
655 }
656 if (!empty($arrayfields['aa.reconcilable']['checked'])) {
657 print_liste_field_titre($arrayfields['aa.reconcilable']['label'], $_SERVER["PHP_SELF"], 'aa.reconcilable', '', $param, '', $sortfield, $sortorder, 'center ');
658 $totalarray['nbfield']++;
659 }
660 if (!empty($arrayfields['aa.centralized']['checked'])) {
661 print_liste_field_titre($arrayfields['aa.centralized']['label'], $_SERVER["PHP_SELF"], 'aa.centralized', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.centralized']['help'].'::-1', 1);
662 $totalarray['nbfield']++;
663 }
664 if (!empty($arrayfields['aa.active']['checked'])) {
665 print_liste_field_titre($arrayfields['aa.active']['label'], $_SERVER["PHP_SELF"], 'aa.active', '', $param, '', $sortfield, $sortorder, 'center ');
666 $totalarray['nbfield']++;
667 }
668 // Action column
669 if (!$conf->main_checkbox_left_column) {
670 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
671 $totalarray['nbfield']++;
672 }
673 print "</tr>\n";
674
675 // Loop on record
676 // --------------------------------------------------------------------
677 $i = 0;
678 while ($i < min($num, $limit)) {
679 $obj = $db->fetch_object($resql);
680
681 $accountstatic->id = $obj->rowid;
682 $accountstatic->label = $obj->label;
683 $accountstatic->account_number = $obj->account_number;
684
685 print '<tr class="oddeven">';
686
687 // Action column
688 if ($conf->main_checkbox_left_column) {
689 print '<td class="center nowraponall">';
690 // if ($permissiontoadd) { // test is always true
691 print '<a class="editfielda" href="./card.php?action=update&token='.newToken().'&id='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?'.$param).'">';
692 print img_edit();
693 print '</a>';
694 print '&nbsp;';
695 print '<a class="marginleftonly" href="./card.php?action=delete&token='.newToken().'&id='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?'.$param).'">';
696 print img_delete();
697 print '</a>';
698 print '&nbsp;';
699 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
700 $selected = 0;
701 if (in_array($obj->rowid, $arrayofselected)) {
702 $selected = 1;
703 }
704 print '<input id="cb'.$obj->rowid.'" class="flat checkforselect marginleftonly" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
705 }
706 // }
707 print '</td>'."\n";
708 if (!$i) {
709 $totalarray['nbfield']++;
710 }
711 }
712
713 // Account number
714 if (!empty($arrayfields['aa.account_number']['checked'])) {
715 print "<td>";
716 print $accountstatic->getNomUrl(1, 0, 0, '', 0, 1, 0, 'accountcard');
717 print "</td>\n";
718 if (!$i) {
719 $totalarray['nbfield']++;
720 }
721 }
722
723 // Account label
724 if (!empty($arrayfields['aa.label']['checked'])) {
725 print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($obj->label).'">';
726 print dol_escape_htmltag($obj->label);
727 print "</td>\n";
728 if (!$i) {
729 $totalarray['nbfield']++;
730 }
731 }
732
733 // Account label to show (label short)
734 if (!empty($arrayfields['aa.labelshort']['checked'])) {
735 print "<td>";
736 print dol_escape_htmltag($obj->labelshort);
737 print "</td>\n";
738 if (!$i) {
739 $totalarray['nbfield']++;
740 }
741 }
742
743 // Account parent
744 if (!empty($arrayfields['aa.account_parent']['checked'])) {
745 // Note: obj->account_parent is a foreign key to a rowid. It is field in child table and obj->rowid2 is same, but in parent table.
746 // So for orphans, obj->account_parent is set but not obj->rowid2
747 if (!empty($obj->account_parent) && !empty($obj->rowid2)) {
748 print "<td>";
749 print '<!-- obj->account_parent = '.$obj->account_parent.' obj->rowid2 = '.$obj->rowid2.' -->';
750 $accountparent->id = $obj->rowid2;
751 $accountparent->label = $obj->label2;
752 $accountparent->account_number = $obj->account_number2; // Store an account number for output
753 print $accountparent->getNomUrl(1);
754 print "</td>\n";
755 if (!$i) {
756 $totalarray['nbfield']++;
757 }
758 } else {
759 print '<td>';
760 if (!empty($obj->account_parent)) {
761 print '<!-- Bad value for obj->account_parent = '.$obj->account_parent.': is a rowid that does not exists -->';
762 }
763 print '</td>';
764 if (!$i) {
765 $totalarray['nbfield']++;
766 }
767 }
768 }
769
770 // Predefined group (deprecated)
771 if (!empty($arrayfields['aa.pcg_type']['checked'])) {
772 print "<td>";
773 print dol_escape_htmltag($obj->pcg_type);
774 print "</td>\n";
775 if (!$i) {
776 $totalarray['nbfield']++;
777 }
778 }
779 // Custom accounts
780 if (!empty($arrayfields['categories']['checked'])) {
781 print '<td>';
782
783 if (getDolGlobalInt('ACCOUNTING_ENABLE_MULTI_REPORT')) {
784 // Multi report system
785 if (!empty($obj->nb_categories)) {
786 $accountingcategory_temp = new AccountancyCategory($db);
787 $categories = $accountingcategory_temp->getCategoriesForAccount($obj->rowid);
788
789 $categoriesLabels = array();
790 foreach ($categories as $cat) {
791 $categoriesLabels[] = '<span class="badge badge-status4" title="'.dol_escape_htmltag($cat['label']).'">'.dol_escape_htmltag($cat['code']).'</span>';
792 }
793 print implode(' ', $categoriesLabels);
794 } else {
795 print '<span class="opacitymedium">-</span>';
796 }
797 } else {
798 // OLD SYSTEM: One-to-many
799 if (!empty($obj->fk_accounting_category)) {
800 print dol_escape_htmltag($obj->fk_accounting_category);
801 } else {
802 print '<span class="opacitymedium">-</span>';
803 }
804 }
805
806 print "</td>\n";
807 if (!$i) {
808 $totalarray['nbfield']++;
809 }
810 }
811
812 // Fields from hook
813 $parameters = array('arrayfields' => $arrayfields, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray);
814 $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
815 print $hookmanager->resPrint;
816
817 // Import id
818 if (!empty($arrayfields['aa.import_key']['checked'])) {
819 print "<td>";
820 print dol_escape_htmltag($obj->import_key);
821 print "</td>\n";
822 if (!$i) {
823 $totalarray['nbfield']++;
824 }
825 }
826
827 // Activated or not matching on an accounting account
828 if (!empty($arrayfields['aa.reconcilable']['checked'])) {
829 print '<td class="center">';
830 if (!empty($obj->centralized)) {
831 // Centralized account: matching not possible, grayed out switch
832 print '<a style="cursor:not-allowed;" title="' . dol_escape_htmltag($langs->trans('CentralizedAccountCannotBeMatchable')) . '">';
833 print img_picto('', !empty($obj->reconcilable) ? 'switch_on' : 'switch_off', '', 0, 0, 1, '', 'opacitymedium');
834 print '</a>';
835 } else {
836 if (empty($obj->reconcilable)) {
837 print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=enable&page=' . $page . '&mode=1&token=' . newToken() . '">';
838 print img_picto($langs->trans('Disabled'), 'switch_off');
839 print '</a>';
840 } else {
841 print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=disable&page=' . $page . '&mode=1&token=' . newToken() . '">';
842 print img_picto($langs->trans('Activated'), 'switch_on');
843 print '</a>';
844 }
845 }
846 print '</td>';
847 if (!$i) {
848 $totalarray['nbfield']++;
849 }
850 }
851
852 // Centralized or not
853 if (!empty($arrayfields['aa.centralized']['checked'])) {
854 print '<td class="center">';
855 if (empty($obj->centralized)) {
856 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&page='.$page.'&mode=2&token='.newToken().'">';
857 print img_picto($langs->trans("Disabled"), 'switch_off');
858 print '</a>';
859 } else {
860 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&page='.$page.'&mode=2&token='.newToken().'">';
861 print img_picto($langs->trans("Activated"), 'switch_on');
862 print '</a>';
863 }
864 print '</td>';
865 if (!$i) {
866 $totalarray['nbfield']++;
867 }
868 }
869
870 // Activated or not
871 if (!empty($arrayfields['aa.active']['checked'])) {
872 print '<td class="center">';
873 if (empty($obj->active)) {
874 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&page='.$page.'&mode=0&token='.newToken().'">';
875 print img_picto($langs->trans("Disabled"), 'switch_off');
876 print '</a>';
877 } else {
878 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&page='.$page.'&mode=0&token='.newToken().'">';
879 print img_picto($langs->trans("Activated"), 'switch_on');
880 print '</a>';
881 }
882 print '</td>';
883 if (!$i) {
884 $totalarray['nbfield']++;
885 }
886 }
887
888 // Action column
889 if (!$conf->main_checkbox_left_column) {
890 print '<td class="center nowraponall">';
891 // if ($permissiontoadd) { // test is always true
892 print '<a class="editfielda" href="./card.php?action=update&token='.newToken().'&id='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?'.$param.'&page='.$page).'">';
893 print img_edit();
894 print '</a>';
895 print '&nbsp;';
896 print '<a class="marginleftonly" href="./card.php?action=delete&token='.newToken().'&id='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?'.$param.'&page='.$page).'">';
897 print img_delete();
898 print '</a>';
899 print '&nbsp;';
900 if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
901 $selected = 0;
902 if (in_array($obj->rowid, $arrayofselected)) {
903 $selected = 1;
904 }
905 print '<input id="cb'.$obj->rowid.'" class="flat checkforselect marginleftonly" type="checkbox" name="toselect[]" value="'.$obj->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
906 }
907 // }
908 print '</td>'."\n";
909 if (!$i) {
910 $totalarray['nbfield']++;
911 }
912 }
913
914 print "</tr>\n";
915 $i++;
916 }
917
918 if ($num == 0) {
919 $colspan = 1;
920 foreach ($arrayfields as $key => $val) {
921 if (!empty($val['checked'])) {
922 $colspan++;
923 }
924 }
925 print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
926 }
927
928 $db->free($resql);
929
930 $parameters = array('arrayfields' => $arrayfields, 'sql' => $sql);
931 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
932 print $hookmanager->resPrint;
933
934 print '</table>'."\n";
935 print '</div>'."\n";
936
937 print '</form>'."\n";
938} else {
940}
941
942// End of page
943llxFooter();
944$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$totalarray
Definition list.php:497
run_sql($sqlfile, $silent=1, $entity=0, $usesavepoint=1, $handler='', $okerror='default', $linelengthlimit=32768, $nocommentremoval=0, $offsetforchartofaccount=0, $colspan=0, $onlysqltoimportwebsite=0, $database='')
Launch a sql file.
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:476
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 categories of an accounting account.
Class to manage accounting accounts.
Class to manage generation of HTML components for accounting management.
Class to manage generation of HTML components Only common components must be here.
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
picto_from_langcode($codelang, $moreatt='', $notitlealt=0)
Return img flag of country for a language code or country code.
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.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dolPrintHTMLForAttribute($s, $escapeonlyhtmltags=0, $allowothertags=array())
Return a string ready to be output into an HTML attribute (alt, title, data-html, ....
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($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.