Test Failed
Branch main (fda838)
by Rafael
50:22
created

AccountingAdminController   F

Complexity

Total Complexity 1072

Size/Duplication

Total Lines 7170
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 4377
dl 0
loc 7170
rs 0.8
c 0
b 0
f 0
wmc 1072

18 Methods

Rating   Name   Duplication   Size   Complexity  
F index() 0 528 73
C closure() 0 150 13
C fieldListJournal() 0 29 14
F categories_list() 0 980 21
F fiscalyear_card() 0 337 39
F card() 0 409 46
D fieldListAccountModel() 0 54 21
F account() 0 802 154
A fiscalyear_info() 0 51 4
F journals_list() 0 662 119
F export() 0 264 22
F fiscalyear() 0 163 18
F productaccount() 0 912 198
D fieldListAccountingCategories() 0 51 21
F defaultaccounts() 0 333 51
F subaccount() 0 525 111
F categories() 0 196 35
F accountmodel() 0 639 133

How to fix   Complexity   

Complex Class

Complex classes like AccountingAdminController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AccountingAdminController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/* Copyright (C) 2004       Rodolphe Quiedeville    <[email protected]>
4
 * Copyright (C) 2004-2024  Laurent Destailleur     <[email protected]>
5
 * Copyright (C) 2004       Benoit Mortier          <[email protected]>
6
 * Copyright (C) 2005-2012  Regis Houssin           <[email protected]>
7
 * Copyright (C) 2010-2016  Juanjo Menent           <[email protected]>
8
 * Copyright (C) 2011-2019  Philippe Grand          <[email protected]>
9
 * Copyright (C) 2011       Remy Younes             <[email protected]>
10
 * Copyright (C) 2012-2015  Marcos García           <[email protected]>
11
 * Copyright (C) 2012       Christophe Battarel     <[email protected]>
12
 * Copyright (C) 2011-2024  Alexandre Spangaro      <[email protected]>
13
 * Copyright (C) 2013-2014  Florian Henry           <[email protected]>
14
 * Copyright (C) 2013-2016  Olivier Geffroy         <[email protected]>
15
 * Copyright (C) 2014-2015  Ari Elbaz (elarifr)     <[email protected]>
16
 * Copyright (C) 2014       Juanjo Menent           <[email protected]>
17
 * Copyright (C) 2015       Ferran Marcet           <[email protected]>
18
 * Copyright (C) 2015       Jean-François Ferry     <[email protected]>
19
 * Copyright (C) 2016       Jamal Elbaz             <[email protected]>
20
 * Copyright (C) 2016       Raphaël Doursenaud      <[email protected]>
21
 * Copyright (C) 2017-2024  Frédéric France         <[email protected]>
22
 * Copyright (C) 2021       Ferran Marcet           <[email protected]>
23
 * Copyright (C) 2021       Gauthier VERDOL         <[email protected]>
24
 * Copyright (C) 2024		MDW						<[email protected]>
25
 * Copyright (C) 2024       Rafael San José         <[email protected]>
26
 *
27
 * This program is free software; you can redistribute it and/or modify
28
 * it under the terms of the GNU General Public License as published by
29
 * the Free Software Foundation; either version 3 of the License, or
30
 * (at your option) any later version.
31
 *
32
 * This program is distributed in the hope that it will be useful,
33
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
35
 * GNU General Public License for more details.
36
 *
37
 * You should have received a copy of the GNU General Public License
38
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
39
 */
40
41
namespace DoliModules\Accounting\Controller;
42
43
global $conf;
44
global $db;
45
global $user;
46
global $hookmanager;
47
global $user;
48
global $menumanager;
49
global $langs;
50
global $mysoc;
51
52
// Load Dolibarr environment
53
require BASE_PATH . '/main.inc.php';
54
require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
55
require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
56
require_once DOL_DOCUMENT_ROOT . '/core/class/fiscalyear.class.php';
57
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
58
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php';
59
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcategory.class.php';
60
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
61
require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
62
require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
63
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
64
require_once DOL_DOCUMENT_ROOT . '/core/lib/fiscalyear.lib.php';
65
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php';
66
require_once DOL_DOCUMENT_ROOT . '/core/lib/report.lib.php';
67
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
68
69
use AccountingAccount;
70
use Categorie;
71
use DoliCore\Base\DolibarrController;
72
use Fiscalyear;
73
use Form;
74
use FormAccounting;
75
use FormAdmin;
76
use FormCategory;
77
use FormCompany;
78
use Product;
79
use stdClass;
80
81
class AccountingAdminController extends DolibarrController
0 ignored issues
show
Deprecated Code introduced by
The class DoliCore\Base\DolibarrController has been deprecated: This class is only needed for compatibility with Dolibarr. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

81
class AccountingAdminController extends /** @scrutinizer ignore-deprecated */ DolibarrController
Loading history...
82
{
83
    /**
84
     * \file        htdocs/accountancy/admin/account.php
85
     * \ingroup     Accountancy (Double entries)
86
     * \brief       List accounting account
87
     */
88
    public function account()
89
    {
90
        global $conf;
91
        global $db;
92
        global $user;
93
        global $hookmanager;
94
        global $user;
95
        global $menumanager;
96
        global $langs;
97
98
// Load translation files required by the page
99
        $langs->loadLangs(['accountancy', 'admin', 'bills', 'compta', 'salaries']);
100
101
        $action = GETPOST('action', 'aZ09');
102
        $cancel = GETPOST('cancel', 'alpha');
103
        $id = GETPOSTINT('id');
104
        $rowid = GETPOSTINT('rowid');
105
        $massaction = GETPOST('massaction', 'aZ09');
106
        $optioncss = GETPOST('optioncss', 'alpha');
107
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'accountingaccountlist'; // To manage different context of search
108
        $mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
109
110
        $search_account = GETPOST('search_account', 'alpha');
111
        $search_label = GETPOST('search_label', 'alpha');
112
        $search_labelshort = GETPOST('search_labelshort', 'alpha');
113
        $search_accountparent = GETPOST('search_accountparent', 'alpha');
114
        $search_pcgtype = GETPOST('search_pcgtype', 'alpha');
115
        $search_import_key = GETPOST('search_import_key', 'alpha');
116
        $toselect = GETPOST('toselect', 'array');
117
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
118
        $confirm = GETPOST('confirm', 'alpha');
119
120
        $chartofaccounts = GETPOSTINT('chartofaccounts');
121
122
        $permissiontoadd = $user->hasRight('accounting', 'chartofaccount');
123
        $permissiontodelete = $user->hasRight('accounting', 'chartofaccount');
124
125
// Security check
126
        if ($user->socid > 0) {
127
            accessforbidden();
128
        }
129
        if (!$user->hasRight('accounting', 'chartofaccount')) {
130
            accessforbidden();
131
        }
132
133
// Load variable for pagination
134
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
135
        $sortfield = GETPOST('sortfield', 'aZ09comma');
136
        $sortorder = GETPOST('sortorder', 'aZ09comma');
137
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
138
        if (empty($page) || $page == -1) {
139
            $page = 0;
140
        }     // If $page is not defined, or '' or -1
141
        $offset = $limit * $page;
142
        $pageprev = $page - 1;
143
        $pagenext = $page + 1;
144
        if (!$sortfield) {
145
            $sortfield = "aa.account_number";
146
        }
147
        if (!$sortorder) {
148
            $sortorder = "ASC";
149
        }
150
151
        $arrayfields = [
152
            'aa.account_number' => ['label' => "AccountNumber", 'checked' => 1],
153
            'aa.label' => ['label' => "Label", 'checked' => 1],
154
            'aa.labelshort' => ['label' => "LabelToShow", 'checked' => 1],
155
            'aa.account_parent' => ['label' => "Accountparent", 'checked' => 1],
156
            'aa.pcg_type' => ['label' => "Pcgtype", 'checked' => 1, 'help' => 'PcgtypeDesc'],
157
            'categories' => ['label' => "AccountingCategories", 'checked' => -1, 'help' => 'AccountingCategoriesDesc'],
158
            'aa.reconcilable' => ['label' => "Reconcilable", 'checked' => 1],
159
            'aa.import_key' => ['label' => "ImportId", 'checked' => -1, 'help' => ''],
160
            'aa.active' => ['label' => "Activated", 'checked' => 1],
161
        ];
162
163
        if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
164
            unset($arrayfields['categories']);
165
            unset($arrayfields['aa.reconcilable']);
166
        }
167
168
        $accounting = new AccountingAccount($db);
169
170
// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
171
        $hookmanager->initHooks(['accountancyadminaccount']);
172
173
174
        /*
175
         * Actions
176
         */
177
178
        if (GETPOST('cancel', 'alpha')) {
179
            $action = 'list';
180
            $massaction = '';
181
        }
182
        if (!GETPOST('confirmmassaction', 'alpha')) {
183
            $massaction = '';
184
        }
185
186
        $parameters = ['chartofaccounts' => $chartofaccounts, 'permissiontoadd' => $permissiontoadd, 'permissiontodelete' => $permissiontodelete];
187
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $accounting, $action); // Note that $action and $object may have been monowraponalldified by some hooks
188
        if ($reshook < 0) {
189
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
190
        }
191
192
        if (empty($reshook)) {
193
            if (!empty($cancel)) {
194
                $action = '';
195
            }
196
197
            $objectclass = 'AccountingAccount';
198
            $uploaddir = $conf->accounting->multidir_output[$conf->entity];
199
            include DOL_DOCUMENT_ROOT . '/core/actions_massactions.inc.php';
200
201
            if ($action == "delete") {
202
                $action = "";
203
            }
204
            include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php';
205
206
            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
207
                $search_account = "";
208
                $search_label = "";
209
                $search_labelshort = "";
210
                $search_accountparent = "";
211
                $search_pcgtype = "";
212
                $search_import_key = "";
213
                $search_array_options = [];
214
            }
215
            if (
216
                (GETPOSTINT('valid_change_chart') && GETPOSTINT('chartofaccounts') > 0) // explicit click on button 'Change and load' with js on
217
                || (GETPOSTINT('chartofaccounts') > 0 && GETPOSTINT('chartofaccounts') != getDolGlobalInt('CHARTOFACCOUNTS'))
218
            ) {    // a submit of form is done and chartofaccounts combo has been modified
219
                $error = 0;
220
221
                if ($chartofaccounts > 0 && $permissiontoadd) {
222
                    $country_code = '';
223
                    // Get language code for this $chartofaccounts
224
                    $sql = 'SELECT code FROM ' . MAIN_DB_PREFIX . 'c_country as c, ' . MAIN_DB_PREFIX . 'accounting_system as a';
225
                    $sql .= ' WHERE c.rowid = a.fk_country AND a.rowid = ' . (int) $chartofaccounts;
226
                    $resql = $db->query($sql);
227
                    if ($resql) {
228
                        $obj = $db->fetch_object($resql);
229
                        if ($obj) {
230
                            $country_code = $obj->code;
231
                        }
232
                    } else {
233
                        dol_print_error($db);
234
                    }
235
236
                    // Try to load sql file
237
                    if ($country_code) {
238
                        $sqlfile = DOL_DOCUMENT_ROOT . '/install/mysql/data/llx_accounting_account_' . strtolower($country_code) . '.sql';
239
240
                        $offsetforchartofaccount = 0;
241
                        // Get the comment line '-- ADD CCCNNNNN to rowid...' to find CCCNNNNN (CCC is country num, NNNNN is id of accounting account)
242
                        // 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.
243
                        // This is to be sure there is no conflict for each chart of account, whatever is country, whatever is company when multicompany is used.
244
                        $tmp = file_get_contents($sqlfile);
245
                        $reg = [];
246
                        if (preg_match('/-- ADD (\d+) to rowid/ims', $tmp, $reg)) {
247
                            $offsetforchartofaccount += $reg[1];
248
                        }
249
                        $offsetforchartofaccount += ($conf->entity * 100000000);
250
251
                        $result = run_sql($sqlfile, 1, $conf->entity, 1, '', 'default', 32768, 0, $offsetforchartofaccount);
252
253
                        if ($result > 0) {
254
                            setEventMessages($langs->trans("ChartLoaded"), null, 'mesgs');
255
                        } else {
256
                            setEventMessages($langs->trans("ErrorDuringChartLoad"), null, 'warnings');
257
                        }
258
                    }
259
260
                    if (!dolibarr_set_const($db, 'CHARTOFACCOUNTS', $chartofaccounts, 'chaine', 0, '', $conf->entity)) {
261
                        $error++;
262
                    }
263
                } else {
264
                    $error++;
265
                }
266
            }
267
268
            if ($action == 'disable' && $permissiontoadd) {
269
                if ($accounting->fetch($id)) {
270
                    $mode = GETPOSTINT('mode');
271
                    $result = $accounting->accountDeactivate($id, $mode);
272
                    if ($result < 0) {
273
                        setEventMessages($accounting->error, $accounting->errors, 'errors');
274
                    }
275
                }
276
277
                $action = 'update';
278
            } elseif ($action == 'enable' && $permissiontoadd) {
279
                if ($accounting->fetch($id)) {
280
                    $mode = GETPOSTINT('mode');
281
                    $result = $accounting->accountActivate($id, $mode);
282
                    if ($result < 0) {
283
                        setEventMessages($accounting->error, $accounting->errors, 'errors');
284
                    }
285
                }
286
                $action = 'update';
287
            }
288
        }
289
290
291
        /*
292
         * View
293
         */
294
        $form = new Form($db);
295
        $formaccounting = new FormAccounting($db);
296
297
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
298
299
        llxHeader('', $langs->trans("ListAccounts"), $help_url);
300
301
        if ($action == 'delete') {
302
            $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $id, $langs->trans('DeleteAccount'), $langs->trans('ConfirmDeleteAccount'), 'confirm_delete', '', 0, 1);
303
            print $formconfirm;
304
        }
305
306
        $pcgver = getDolGlobalInt('CHARTOFACCOUNTS');
307
308
        $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,";
309
        $sql .= " aa.reconcilable, aa.active, aa.import_key,";
310
        $sql .= " a2.rowid as rowid2, a2.label as label2, a2.account_number as account_number2";
311
312
// Add fields from hooks
313
        $parameters = [];
314
        $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $object does not exist. Did you maybe mean $objectclass?
Loading history...
315
        $sql .= $hookmanager->resPrint;
316
        $sql = preg_replace('/,\s*$/', '', $sql);
317
318
        $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
319
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version AND aa.entity = " . ((int) $conf->entity);
320
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as a2 ON a2.rowid = aa.account_parent AND a2.entity = " . ((int) $conf->entity);
321
322
// Add table from hooks
323
        $parameters = [];
324
        $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
325
        $sql .= $hookmanager->resPrint;
326
327
        $sql .= " WHERE asy.rowid = " . ((int) $pcgver);
328
329
        if (strlen(trim($search_account))) {
330
            $lengthpaddingaccount = 0;
331
            if (getDolGlobalInt('ACCOUNTING_LENGTH_GACCOUNT') || getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT')) {
332
                $lengthpaddingaccount = max(getDolGlobalInt('ACCOUNTING_LENGTH_GACCOUNT'), getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT'));
333
            }
334
            $search_account_tmp = $search_account;
335
            $weremovedsomezero = 0;
336
            if (strlen($search_account_tmp) <= $lengthpaddingaccount) {
337
                for ($i = 0; $i < $lengthpaddingaccount; $i++) {
338
                    if (preg_match('/0$/', $search_account_tmp)) {
339
                        $weremovedsomezero++;
340
                        $search_account_tmp = preg_replace('/0$/', '', $search_account_tmp);
341
                    }
342
                }
343
            }
344
345
            //var_dump($search_account); exit;
346
            if ($search_account_tmp) {
347
                if ($weremovedsomezero) {
348
                    $search_account_tmp_clean = $search_account_tmp;
349
                    $search_account_clean = $search_account;
350
                    $startchar = '%';
351
                    if (substr($search_account_tmp, 0, 1) === '^') {
352
                        $startchar = '';
353
                        $search_account_tmp_clean = preg_replace('/^\^/', '', $search_account_tmp);
354
                        $search_account_clean = preg_replace('/^\^/', '', $search_account);
355
                    }
356
                    $sql .= " AND (aa.account_number LIKE '" . $db->escape($startchar . $search_account_tmp_clean) . "'";
357
                    $sql .= " OR aa.account_number LIKE '" . $db->escape($startchar . $search_account_clean) . "%')";
358
                } else {
359
                    $sql .= natural_search("aa.account_number", $search_account_tmp);
360
                }
361
            }
362
        }
363
        if (strlen(trim($search_label))) {
364
            $sql .= natural_search("aa.label", $search_label);
365
        }
366
        if (strlen(trim($search_labelshort))) {
367
            $sql .= natural_search("aa.labelshort", $search_labelshort);
368
        }
369
        if (strlen(trim($search_accountparent)) && $search_accountparent != '-1') {
370
            $sql .= natural_search("aa.account_parent", $search_accountparent, 2);
371
        }
372
        if (strlen(trim($search_pcgtype))) {
373
            $sql .= natural_search("aa.pcg_type", $search_pcgtype);
374
        }
375
        if (strlen(trim($search_import_key))) {
376
            $sql .= natural_search("aa.import_key", $search_import_key);
377
        }
378
379
// Add where from hooks
380
        $parameters = [];
381
        $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
382
        $sql .= $hookmanager->resPrint;
383
384
        $sql .= $db->order($sortfield, $sortorder);
385
//print $sql;
386
387
// Count total nb of records
388
        $nbtotalofrecords = '';
389
        if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
390
            $resql = $db->query($sql);
391
            $nbtotalofrecords = $db->num_rows($resql);
392
            if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
393
                $page = 0;
394
                $offset = 0;
395
            }
396
        }
397
398
        $sql .= $db->plimit($limit + 1, $offset);
399
400
        dol_syslog('accountancy/admin/account.php:: $sql=' . $sql);
401
        $resql = $db->query($sql);
402
403
        if ($resql) {
404
            $num = $db->num_rows($resql);
405
406
            $arrayofselected = is_array($toselect) ? $toselect : [];
407
408
            $param = '';
409
            if (!empty($contextpage) && $contextpage != $_SERVER['PHP_SELF']) {
410
                $param .= '&contextpage=' . urlencode($contextpage);
411
            }
412
            if ($limit > 0 && $limit != $conf->liste_limit) {
413
                $param .= '&limit=' . ((int) $limit);
414
            }
415
            if ($search_account) {
416
                $param .= '&search_account=' . urlencode($search_account);
417
            }
418
            if ($search_label) {
419
                $param .= '&search_label=' . urlencode($search_label);
420
            }
421
            if ($search_labelshort) {
422
                $param .= '&search_labelshort=' . urlencode($search_labelshort);
423
            }
424
            if ($search_accountparent > 0 || $search_accountparent == '0') {
425
                $param .= '&search_accountparent=' . urlencode($search_accountparent);
426
            }
427
            if ($search_pcgtype) {
428
                $param .= '&search_pcgtype=' . urlencode($search_pcgtype);
429
            }
430
            if ($search_import_key) {
431
                $param .= '&search_import_key=' . urlencode($search_import_key);
432
            }
433
            if ($optioncss != '') {
434
                $param .= '&optioncss=' . urlencode($optioncss);
435
            }
436
437
            // Add $param from hooks
438
            $parameters = [];
439
            $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
440
            $param .= $hookmanager->resPrint;
441
442
            if (!empty($conf->use_javascript_ajax)) {
443
                print '<!-- Add javascript to reload page when we click "Change plan" -->
444
			<script type="text/javascript">
445
			$(document).ready(function () {
446
		    	$("#change_chart").on("click", function (e) {
447
					console.log("chartofaccounts selected = "+$("#chartofaccounts").val());
448
					// reload page
449
					window.location.href = "' . $_SERVER['PHP_SELF'] . '?valid_change_chart=1&chartofaccounts="+$("#chartofaccounts").val();
450
			    });
451
			});
452
	    	</script>';
453
            }
454
455
            // List of mass actions available
456
            $arrayofmassactions = [];
457
            if ($user->hasRight('accounting', 'chartofaccount')) {
458
                $arrayofmassactions['predelete'] = '<span class="fa fa-trash paddingrightonly"></span>' . $langs->trans("Delete");
459
            }
460
            if (in_array($massaction, ['presend', 'predelete', 'closed'])) {
461
                $arrayofmassactions = [];
462
            }
463
464
            $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
465
466
            $newcardbutton = '';
467
            $newcardbutton = dolGetButtonTitle($langs->trans('Addanaccount'), '', 'fa fa-plus-circle', DOL_URL_ROOT . '/accountancy/admin/card.php?action=create', '', $permissiontoadd);
468
469
470
            print '<form method="POST" id="searchFormList" action="' . $_SERVER['PHP_SELF'] . '">';
471
            if ($optioncss != '') {
472
                print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
473
            }
474
            print '<input type="hidden" name="token" value="' . newToken() . '">';
475
            print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
476
            print '<input type="hidden" name="action" value="list">';
477
            print '<input type="hidden" name="sortfield" value="' . $sortfield . '">';
478
            print '<input type="hidden" name="sortorder" value="' . $sortorder . '">';
479
            print '<input type="hidden" name="contextpage" value="' . $contextpage . '">';
480
481
            // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
482
            print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'accounting_account', 0, $newcardbutton, '', $limit, 0, 0, 1);
483
484
            include DOL_DOCUMENT_ROOT . '/core/tpl/massactions_pre.tpl.php';
485
486
            // Box to select active chart of account
487
            print $langs->trans("Selectchartofaccounts") . " : ";
488
            print '<select class="flat minwidth200" name="chartofaccounts" id="chartofaccounts">';
489
            $sql = "SELECT a.rowid, a.pcg_version, a.label, a.active, c.code as country_code";
490
            $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_system as a";
491
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_country as c ON a.fk_country = c.rowid AND c.active = 1";
492
            $sql .= " WHERE a.active = 1";
493
            dol_syslog('accountancy/admin/account.php $sql=' . $sql);
494
495
            $resqlchart = $db->query($sql);
496
            if ($resqlchart) {
497
                $numbis = $db->num_rows($resqlchart);
498
                $i = 0;
499
                print '<option value="-1">&nbsp;</option>';
500
                while ($i < $numbis) {
501
                    $obj = $db->fetch_object($resqlchart);
502
                    if ($obj) {
503
                        print '<option value="' . $obj->rowid . '"';
504
                        print ($pcgver == $obj->rowid) ? ' selected' : '';
505
                        print '>' . $obj->pcg_version . ' - ' . $obj->label . ' - (' . $obj->country_code . ')</option>';
506
                    }
507
                    $i++;
508
                }
509
            } else {
510
                dol_print_error($db);
511
            }
512
            print "</select>";
513
            print ajax_combobox("chartofaccounts");
514
            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")) . '">';
515
516
            print '<br>';
517
518
            $parameters = [];
519
            $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
520
            print $hookmanager->resPrint;
521
522
            print '<br>';
523
524
            $varpage = empty($contextpage) ? $_SERVER['PHP_SELF'] : $contextpage;
525
            $selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) : ''); // This also change content of $arrayfields
526
            $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
527
528
            $moreforfilter = '';
529
            if ($moreforfilter) {
530
                print '<div class="liste_titre liste_titre_bydiv centpercent">';
531
                print $moreforfilter;
532
                print '</div>';
533
            }
534
535
            $accountstatic = new AccountingAccount($db);
536
            $accountparent = new AccountingAccount($db);
537
            $totalarray = [];
538
            $totalarray['nbfield'] = 0;
539
540
            print '<div class="div-table-responsive">';
541
            print '<table class="tagtable liste' . ($moreforfilter ? " listwithfilterbefore" : "") . '">' . "\n";
542
543
            // Fields title search
544
            // --------------------------------------------------------------------
545
            print '<tr class="liste_titre_filter">';
546
547
            // Action column
548
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
549
                print '<td class="liste_titre center maxwidthsearch">';
550
                $searchpicto = $form->showFilterButtons('left');
551
                print $searchpicto;
552
                print '</td>';
553
            }
554
            if (!empty($arrayfields['aa.account_number']['checked'])) {
555
                print '<td class="liste_titre"><input type="text" class="flat width100" name="search_account" value="' . $search_account . '"></td>';
556
            }
557
            if (!empty($arrayfields['aa.label']['checked'])) {
558
                print '<td class="liste_titre"><input type="text" class="flat width150" name="search_label" value="' . $search_label . '"></td>';
559
            }
560
            if (!empty($arrayfields['aa.labelshort']['checked'])) {
561
                print '<td class="liste_titre"><input type="text" class="flat width100" name="search_labelshort" value="' . $search_labelshort . '"></td>';
562
            }
563
            if (!empty($arrayfields['aa.account_parent']['checked'])) {
564
                print '<td class="liste_titre">';
565
                print $formaccounting->select_account($search_accountparent, 'search_accountparent', 2, [], 0, 0, 'maxwidth150');
566
                print '</td>';
567
            }
568
            // Predefined group
569
            if (!empty($arrayfields['aa.pcg_type']['checked'])) {
570
                print '<td class="liste_titre"><input type="text" class="flat width75" name="search_pcgtype" value="' . $search_pcgtype . '"></td>';
571
            }
572
            // Custom groups
573
            if (!empty($arrayfields['categories']['checked'])) {
574
                print '<td class="liste_titre"></td>';
575
            }
576
577
            // Fields from hook
578
            $parameters = ['arrayfields' => $arrayfields];
579
            $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
580
            print $hookmanager->resPrint;
581
582
            // Import key
583
            if (!empty($arrayfields['aa.import_key']['checked'])) {
584
                print '<td class="liste_titre"><input type="text" class="flat width75" name="search_import_key" value="' . $search_import_key . '"></td>';
585
            }
586
            if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
587
                if (!empty($arrayfields['aa.reconcilable']['checked'])) {
588
                    print '<td class="liste_titre">&nbsp;</td>';
589
                }
590
            }
591
            if (!empty($arrayfields['aa.active']['checked'])) {
592
                print '<td class="liste_titre">&nbsp;</td>';
593
            }
594
            // Action column
595
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
596
                print '<td class="liste_titre center maxwidthsearch">';
597
                $searchpicto = $form->showFilterButtons();
598
                print $searchpicto;
599
                print '</td>';
600
            }
601
            print '</tr>' . "\n";
602
603
            $totalarray = [];
604
            $totalarray['nbfield'] = 0;
605
606
            // Fields title label
607
            // --------------------------------------------------------------------
608
            print '<tr class="liste_titre">';
609
            // Action column
610
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
611
                print_liste_field_titre($selectedfields, $_SERVER['PHP_SELF'], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch actioncolumn ');
612
                $totalarray['nbfield']++;
613
            }
614
            if (!empty($arrayfields['aa.account_number']['checked'])) {
615
                print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER['PHP_SELF'], "aa.account_number", "", $param, '', $sortfield, $sortorder);
616
                $totalarray['nbfield']++;
617
            }
618
            if (!empty($arrayfields['aa.label']['checked'])) {
619
                print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER['PHP_SELF'], "aa.label", "", $param, '', $sortfield, $sortorder);
620
                $totalarray['nbfield']++;
621
            }
622
            if (!empty($arrayfields['aa.labelshort']['checked'])) {
623
                print_liste_field_titre($arrayfields['aa.labelshort']['label'], $_SERVER['PHP_SELF'], "aa.labelshort", "", $param, '', $sortfield, $sortorder);
624
                $totalarray['nbfield']++;
625
            }
626
            if (!empty($arrayfields['aa.account_parent']['checked'])) {
627
                print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER['PHP_SELF'], "aa.account_parent", "", $param, '', $sortfield, $sortorder, 'left ');
628
                $totalarray['nbfield']++;
629
            }
630
            if (!empty($arrayfields['aa.pcg_type']['checked'])) {
631
                print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER['PHP_SELF'], 'aa.pcg_type,aa.account_number', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_type']['help'], 1);
632
                $totalarray['nbfield']++;
633
            }
634
            if (!empty($arrayfields['categories']['checked'])) {
635
                print_liste_field_titre($arrayfields['categories']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, '', $arrayfields['categories']['help'], 1);
636
                $totalarray['nbfield']++;
637
            }
638
639
            // Hook fields
640
            $parameters = ['arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder];
641
            $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
642
            print $hookmanager->resPrint;
643
644
            if (!empty($arrayfields['aa.import_key']['checked'])) {
645
                print_liste_field_titre($arrayfields['aa.import_key']['label'], $_SERVER['PHP_SELF'], 'aa.import_key', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.import_key']['help'], 1);
646
                $totalarray['nbfield']++;
647
            }
648
            if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
649
                if (!empty($arrayfields['aa.reconcilable']['checked'])) {
650
                    print_liste_field_titre($arrayfields['aa.reconcilable']['label'], $_SERVER['PHP_SELF'], 'aa.reconcilable', '', $param, '', $sortfield, $sortorder);
651
                    $totalarray['nbfield']++;
652
                }
653
            }
654
            if (!empty($arrayfields['aa.active']['checked'])) {
655
                print_liste_field_titre($arrayfields['aa.active']['label'], $_SERVER['PHP_SELF'], 'aa.active', '', $param, '', $sortfield, $sortorder);
656
                $totalarray['nbfield']++;
657
            }
658
            // Action column
659
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
660
                print_liste_field_titre($selectedfields, $_SERVER['PHP_SELF'], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
661
                $totalarray['nbfield']++;
662
            }
663
            print "</tr>\n";
664
665
            // Loop on record
666
            // --------------------------------------------------------------------
667
            $i = 0;
668
            while ($i < min($num, $limit)) {
669
                $obj = $db->fetch_object($resql);
670
671
                $accountstatic->id = $obj->rowid;
672
                $accountstatic->label = $obj->label;
673
                $accountstatic->account_number = $obj->account_number;
674
675
                print '<tr class="oddeven">';
676
677
                // Action column
678
                if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
679
                    print '<td class="center nowraponall">';
680
                    if ($user->hasRight('accounting', 'chartofaccount')) {
681
                        print '<a class="editfielda" href="./card.php?action=update&token=' . newToken() . '&id=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF'] . '?' . $param) . '">';
682
                        print img_edit();
683
                        print '</a>';
684
                        print '&nbsp;';
685
                        print '<a class="marginleftonly" href="./card.php?action=delete&token=' . newToken() . '&id=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF'] . '?' . $param) . '">';
686
                        print img_delete();
687
                        print '</a>';
688
                        print '&nbsp;';
689
                        if ($massactionbutton || $massaction) {   // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
690
                            $selected = 0;
691
                            if (in_array($obj->rowid, $arrayofselected)) {
692
                                $selected = 1;
693
                            }
694
                            print '<input id="cb' . $obj->rowid . '" class="flat checkforselect marginleftonly" type="checkbox" name="toselect[]" value="' . $obj->rowid . '"' . ($selected ? ' checked="checked"' : '') . '>';
695
                        }
696
                    }
697
                    print '</td>' . "\n";
698
                    if (!$i) {
699
                        $totalarray['nbfield']++;
700
                    }
701
                }
702
703
                // Account number
704
                if (!empty($arrayfields['aa.account_number']['checked'])) {
705
                    print "<td>";
706
                    print $accountstatic->getNomUrl(1, 0, 0, '', 0, 1, 0, 'accountcard');
707
                    print "</td>\n";
708
                    if (!$i) {
709
                        $totalarray['nbfield']++;
710
                    }
711
                }
712
713
                // Account label
714
                if (!empty($arrayfields['aa.label']['checked'])) {
715
                    print '<td class="tdoverflowmax150" title="' . dol_escape_htmltag($obj->label) . '">';
716
                    print dol_escape_htmltag($obj->label);
717
                    print "</td>\n";
718
                    if (!$i) {
719
                        $totalarray['nbfield']++;
720
                    }
721
                }
722
723
                // Account label to show (label short)
724
                if (!empty($arrayfields['aa.labelshort']['checked'])) {
725
                    print "<td>";
726
                    print dol_escape_htmltag($obj->labelshort);
727
                    print "</td>\n";
728
                    if (!$i) {
729
                        $totalarray['nbfield']++;
730
                    }
731
                }
732
733
                // Account parent
734
                if (!empty($arrayfields['aa.account_parent']['checked'])) {
735
                    // 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.
736
                    // So for orphans, obj->account_parent is set but not obj->rowid2
737
                    if (!empty($obj->account_parent) && !empty($obj->rowid2)) {
738
                        print "<td>";
739
                        print '<!-- obj->account_parent = ' . $obj->account_parent . ' obj->rowid2 = ' . $obj->rowid2 . ' -->';
740
                        $accountparent->id = $obj->rowid2;
741
                        $accountparent->label = $obj->label2;
742
                        $accountparent->account_number = $obj->account_number2; // Store an account number for output
743
                        print $accountparent->getNomUrl(1);
744
                        print "</td>\n";
745
                        if (!$i) {
746
                            $totalarray['nbfield']++;
747
                        }
748
                    } else {
749
                        print '<td>';
750
                        if (!empty($obj->account_parent)) {
751
                            print '<!-- Bad value for obj->account_parent = ' . $obj->account_parent . ': is a rowid that does not exists -->';
752
                        }
753
                        print '</td>';
754
                        if (!$i) {
755
                            $totalarray['nbfield']++;
756
                        }
757
                    }
758
                }
759
760
                // Predefined group (deprecated)
761
                if (!empty($arrayfields['aa.pcg_type']['checked'])) {
762
                    print "<td>";
763
                    print dol_escape_htmltag($obj->pcg_type);
764
                    print "</td>\n";
765
                    if (!$i) {
766
                        $totalarray['nbfield']++;
767
                    }
768
                }
769
                // Custom accounts
770
                if (!empty($arrayfields['categories']['checked'])) {
771
                    print "<td>";
772
                    // TODO Get all custom groups labels the account is in
773
                    print dol_escape_htmltag($obj->fk_accounting_category);
774
                    print "</td>\n";
775
                    if (!$i) {
776
                        $totalarray['nbfield']++;
777
                    }
778
                }
779
780
                // Fields from hook
781
                $parameters = ['arrayfields' => $arrayfields, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray];
782
                $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
783
                print $hookmanager->resPrint;
784
785
                // Import id
786
                if (!empty($arrayfields['aa.import_key']['checked'])) {
787
                    print "<td>";
788
                    print dol_escape_htmltag($obj->import_key);
789
                    print "</td>\n";
790
                    if (!$i) {
791
                        $totalarray['nbfield']++;
792
                    }
793
                }
794
795
                if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
796
                    // Activated or not reconciliation on an accounting account
797
                    if (!empty($arrayfields['aa.reconcilable']['checked'])) {
798
                        print '<td class="center">';
799
                        if (empty($obj->reconcilable)) {
800
                            print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=enable&mode=1&token=' . newToken() . '">';
801
                            print img_picto($langs->trans("Disabled"), 'switch_off');
802
                            print '</a>';
803
                        } else {
804
                            print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=disable&mode=1&token=' . newToken() . '">';
805
                            print img_picto($langs->trans("Activated"), 'switch_on');
806
                            print '</a>';
807
                        }
808
                        print '</td>';
809
                        if (!$i) {
810
                            $totalarray['nbfield']++;
811
                        }
812
                    }
813
                }
814
815
                // Activated or not
816
                if (!empty($arrayfields['aa.active']['checked'])) {
817
                    print '<td class="center">';
818
                    if (empty($obj->active)) {
819
                        print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=enable&mode=0&token=' . newToken() . '">';
820
                        print img_picto($langs->trans("Disabled"), 'switch_off');
821
                        print '</a>';
822
                    } else {
823
                        print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=disable&mode=0&token=' . newToken() . '">';
824
                        print img_picto($langs->trans("Activated"), 'switch_on');
825
                        print '</a>';
826
                    }
827
                    print '</td>';
828
                    if (!$i) {
829
                        $totalarray['nbfield']++;
830
                    }
831
                }
832
833
                // Action column
834
                if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
835
                    print '<td class="center nowraponall">';
836
                    if ($user->hasRight('accounting', 'chartofaccount')) {
837
                        print '<a class="editfielda" href="./card.php?action=update&token=' . newToken() . '&id=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF'] . '?' . $param) . '">';
838
                        print img_edit();
839
                        print '</a>';
840
                        print '&nbsp;';
841
                        print '<a class="marginleftonly" href="./card.php?action=delete&token=' . newToken() . '&id=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF'] . '?' . $param) . '">';
842
                        print img_delete();
843
                        print '</a>';
844
                        print '&nbsp;';
845
                        if ($massactionbutton || $massaction) {   // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
846
                            $selected = 0;
847
                            if (in_array($obj->rowid, $arrayofselected)) {
848
                                $selected = 1;
849
                            }
850
                            print '<input id="cb' . $obj->rowid . '" class="flat checkforselect marginleftonly" type="checkbox" name="toselect[]" value="' . $obj->rowid . '"' . ($selected ? ' checked="checked"' : '') . '>';
851
                        }
852
                    }
853
                    print '</td>' . "\n";
854
                    if (!$i) {
855
                        $totalarray['nbfield']++;
856
                    }
857
                }
858
859
                print "</tr>\n";
860
                $i++;
861
            }
862
863
            if ($num == 0) {
864
                $colspan = 1;
865
                foreach ($arrayfields as $key => $val) {
866
                    if (!empty($val['checked'])) {
867
                        $colspan++;
868
                    }
869
                }
870
                print '<tr><td colspan="' . $colspan . '"><span class="opacitymedium">' . $langs->trans("None") . '</span></td></tr>';
871
            }
872
873
            $db->free($resql);
874
875
            $parameters = ['arrayfields' => $arrayfields, 'sql' => $sql];
876
            $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
877
            print $hookmanager->resPrint;
878
879
            print '</table>' . "\n";
880
            print '</div>' . "\n";
881
882
            print '</form>' . "\n";
883
        } else {
884
            dol_print_error($db);
885
        }
886
887
// End of page
888
        llxFooter();
889
        $db->close();
890
    }
891
892
    /**
893
     *      \file       htdocs/accountancy/admin/accountmodel.php
894
     *      \ingroup    Accountancy (Double entries)
895
     *      \brief      Page to administer model of chart of accounts
896
     */
897
    public function accountmodel()
898
    {
899
        global $conf;
900
        global $db;
901
        global $user;
902
        global $hookmanager;
903
        global $user;
904
        global $menumanager;
905
        global $langs;
906
907
        if (isModEnabled('accounting')) {
908
            require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
909
        }
910
911
// Load translation files required by the page
912
        $langs->loadLangs(['accountancy', 'admin', 'companies', 'compta', 'errors', 'holiday', 'hrm', 'resource']);
913
914
        $action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view';
915
        $confirm = GETPOST('confirm', 'alpha');
916
        $id = 31;
917
        $rowid = GETPOST('rowid', 'alpha');
918
        $code = GETPOST('code', 'alpha');
919
920
        $acts = [];
921
        $actl = [];
922
        $acts[0] = "activate";
923
        $acts[1] = "disable";
924
        $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
925
        $actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"');
926
927
        $listoffset = GETPOST('listoffset', 'alpha');
928
        $listlimit = GETPOSTINT('listlimit') > 0 ? GETPOSTINT('listlimit') : 1000;
929
        $active = 1;
930
931
        $sortfield = GETPOST("sortfield", 'aZ09comma');
932
        $sortorder = GETPOST("sortorder", 'aZ09comma');
933
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
934
        if (empty($page) || $page == -1) {
935
            $page = 0;
936
        }     // If $page is not defined, or '' or -1
937
        $offset = $listlimit * $page;
938
        $pageprev = $page - 1;
939
        $pagenext = $page + 1;
940
941
        $search_country_id = GETPOSTINT('search_country_id');
942
943
944
// Security check
945
        if ($user->socid > 0) {
946
            accessforbidden();
947
        }
948
        if (!$user->hasRight('accounting', 'chartofaccount')) {
949
            accessforbidden();
950
        }
951
952
953
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
954
        $hookmanager->initHooks(['admin']);
955
956
// This page is a generic page to edit dictionaries
957
// Put here declaration of dictionaries properties
958
959
// Name of SQL tables of dictionaries
960
        $tabname = [];
961
962
        $tabname[31] = MAIN_DB_PREFIX . "accounting_system";
963
964
// Dictionary labels
965
        $tablib = [];
966
        $tablib[31] = "Pcg_version";
967
968
// Requests to extract data
969
        $tabsql = [];
970
        $tabsql[31] = "SELECT s.rowid as rowid, pcg_version, s.label, s.fk_country as country_id, c.code as country_code, c.label as country, s.active FROM " . MAIN_DB_PREFIX . "accounting_system as s, " . MAIN_DB_PREFIX . "c_country as c WHERE s.fk_country=c.rowid and c.active=1";
971
972
// Criteria to sort dictionaries
973
        $tabsqlsort = [];
974
        $tabsqlsort[31] = "pcg_version ASC";
975
976
// Nom des champs en resultat de select pour affichage du dictionnaire
977
        $tabfield = [];
978
        $tabfield[31] = "pcg_version,label,country_id,country";
979
980
// Nom des champs d'edition pour modification d'un enregistrement
981
        $tabfieldvalue = [];
982
        $tabfieldvalue[31] = "pcg_version,label,country";
983
984
// Nom des champs dans la table pour insertion d'un enregistrement
985
        $tabfieldinsert = [];
986
        $tabfieldinsert[31] = "pcg_version,label,fk_country";
987
988
// Nom du rowid si le champ n'est pas de type autoincrement
989
// Example: "" if id field is "rowid" and has autoincrement on
990
//          "nameoffield" if id field is not "rowid" or has not autoincrement on
991
        $tabrowid = [];
992
        $tabrowid[31] = "";
993
994
// List of help for fields
995
        $tabhelp = [];
996
        $tabhelp[31] = ['pcg_version' => $langs->trans("EnterAnyCode")];
997
998
999
// Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact")
1000
        $elementList = [];
1001
        $sourceList = [];
1002
1003
1004
        /*
1005
         * Actions
1006
         */
1007
1008
        if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) {
1009
            $search_country_id = '';
1010
        }
1011
1012
// Actions add or modify an entry into a dictionary
1013
        if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
1014
            $listfield = explode(',', str_replace(' ', '', $tabfield[$id]));
1015
            $listfieldinsert = explode(',', $tabfieldinsert[$id]);
1016
            $listfieldmodify = explode(',', $tabfieldinsert[$id]);
1017
            $listfieldvalue = explode(',', $tabfieldvalue[$id]);
1018
1019
            // Check that all fields are filled
1020
            $ok = 1;
1021
            foreach ($listfield as $f => $value) {
1022
                if ($value == 'country_id' && in_array($tablib[$id], ['Pcg_version'])) {
1023
                    continue; // For some pages, country is not mandatory
1024
                }
1025
                if ((!GETPOSTISSET($value)) || GETPOST($value) == '') {
1026
                    $ok = 0;
1027
                    $fieldnamekey = $listfield[$f];
1028
                    // We take translate key of field
1029
1030
                    if ($fieldnamekey == 'pcg_version') {
1031
                        $fieldnamekey = 'Pcg_version';
1032
                    }
1033
                    if ($fieldnamekey == 'label') {
1034
                        $fieldnamekey = 'Label';
1035
                    }
1036
                    if ($fieldnamekey == 'country') {
1037
                        $fieldnamekey = "Country";
1038
                    }
1039
1040
                    setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors');
1041
                }
1042
            }
1043
            // Other checks
1044
            if (GETPOSTISSET("pcg_version")) {
1045
                if (GETPOST("pcg_version") == '0') {
1046
                    $ok = 0;
1047
                    setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
1048
                }
1049
            }
1050
            if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) {
1051
                $ok = 0;
1052
                setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Country")), null, 'errors');
1053
            }
1054
1055
            // Si verif ok et action add, on ajoute la ligne
1056
            if ($ok && GETPOST('actionadd', 'alpha')) {
1057
                $newid = 0;
1058
                if ($tabrowid[$id]) {
1059
                    // Get free id for insert
1060
                    $sql = "SELECT MAX(" . $db->sanitize($tabrowid[$id]) . ") as newid FROM " . $db->sanitize($tabname[$id]);
1061
                    $result = $db->query($sql);
1062
                    if ($result) {
1063
                        $obj = $db->fetch_object($result);
1064
                        $newid = ($obj->newid + 1);
1065
                    } else {
1066
                        dol_print_error($db);
1067
                    }
1068
                }
1069
1070
                // Add new entry
1071
                $sql = "INSERT INTO " . $db->sanitize($tabname[$id]) . " (";
1072
                // List of fields
1073
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
1074
                    $sql .= $db->sanitize($tabrowid[$id]) . ",";
1075
                }
1076
                $sql .= $db->sanitize($tabfieldinsert[$id]);
1077
                $sql .= ",active)";
1078
                $sql .= " VALUES(";
1079
1080
                // List of values
1081
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
1082
                    $sql .= $newid . ",";
1083
                }
1084
                $i = 0;
1085
                foreach ($listfieldinsert as $f => $value) {
1086
                    if ($value == 'price' || preg_match('/^amount/i', $value) || $value == 'taux') {
1087
                        $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU');
1088
                    } elseif ($value == 'entity') {
1089
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
1090
                    }
1091
                    if ($i) {
1092
                        $sql .= ",";
1093
                    }
1094
                    if (GETPOST($listfieldvalue[$i]) == '') {
1095
                        $sql .= "null";
1096
                    } else {
1097
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
1098
                    }
1099
                    $i++;
1100
                }
1101
                $sql .= ",1)";
1102
1103
                dol_syslog("actionadd", LOG_DEBUG);
1104
                $result = $db->query($sql);
1105
                if ($result) {  // Add is ok
1106
                    setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
1107
                    $_POST = ['id' => $id]; // Clean $_POST array, we keep only
1108
                } else {
1109
                    if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1110
                        setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
1111
                    } else {
1112
                        dol_print_error($db);
1113
                    }
1114
                }
1115
            }
1116
1117
            // Si verif ok et action modify, on modifie la ligne
1118
            if ($ok && GETPOST('actionmodify', 'alpha')) {
1119
                if ($tabrowid[$id]) {
1120
                    $rowidcol = $tabrowid[$id];
1121
                } else {
1122
                    $rowidcol = "rowid";
1123
                }
1124
1125
                // Modify entry
1126
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET ";
1127
                // Modifie valeur des champs
1128
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) {
1129
                    $sql .= $db->sanitize($tabrowid[$id]) . " = ";
1130
                    $sql .= "'" . $db->escape($rowid) . "', ";
1131
                }
1132
                $i = 0;
1133
                foreach ($listfieldmodify as $field) {
1134
                    if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') {
1135
                        $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU');
1136
                    } elseif ($field == 'entity') {
1137
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
1138
                    }
1139
                    if ($i) {
1140
                        $sql .= ",";
1141
                    }
1142
                    $sql .= $field . "=";
1143
                    if (GETPOST($listfieldvalue[$i]) == '') {
1144
                        $sql .= "null";
1145
                    } else {
1146
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
1147
                    }
1148
                    $i++;
1149
                }
1150
                $sql .= " WHERE " . $rowidcol . " = " . ((int) $rowid);
1151
1152
                dol_syslog("actionmodify", LOG_DEBUG);
1153
                //print $sql;
1154
                $resql = $db->query($sql);
1155
                if (!$resql) {
1156
                    setEventMessages($db->error(), null, 'errors');
1157
                }
1158
            }
1159
        }
1160
1161
        if ($action == 'confirm_delete' && $confirm == 'yes') {       // delete
1162
            if ($tabrowid[$id]) {
1163
                $rowidcol = $tabrowid[$id];
1164
            } else {
1165
                $rowidcol = "rowid";
1166
            }
1167
1168
            $sql = "DELETE from " . $db->sanitize($tabname[$id]) . " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
1169
1170
            dol_syslog("delete", LOG_DEBUG);
1171
            $result = $db->query($sql);
1172
            if (!$result) {
1173
                if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') {
1174
                    setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors');
1175
                } else {
1176
                    dol_print_error($db);
1177
                }
1178
            }
1179
        }
1180
1181
// activate
1182
        if ($action == 'activate') {
1183
            $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE rowid = " . ((int) $rowid);
1184
            $result = $db->query($sql);
1185
            if (!$result) {
1186
                dol_print_error($db);
1187
            }
1188
        }
1189
1190
// disable
1191
        if ($action == $acts[1]) {
1192
            $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE rowid = " . ((int) $rowid);
1193
            $result = $db->query($sql);
1194
            if (!$result) {
1195
                dol_print_error($db);
1196
            }
1197
        }
1198
1199
1200
        /*
1201
         * View
1202
         */
1203
1204
        $form = new Form($db);
1205
        $formadmin = new FormAdmin($db);
1206
1207
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
1208
1209
        llxHeader('', $langs->trans("Pcg_version"), $help_url);
1210
1211
        $titre = $langs->trans($tablib[$id]);
1212
        $linkback = '';
1213
1214
        print load_fiche_titre($titre, $linkback, 'title_accountancy');
1215
1216
1217
// Confirmation de la suppression de la ligne
1218
        if ($action == 'delete') {
1219
            print $form->formconfirm($_SERVER['PHP_SELF'] . '?' . ($page ? 'page=' . urlencode((string) ($page)) . '&' : '') . 'sortfield=' . urlencode((string) ($sortfield)) . '&sortorder=' . urlencode((string) ($sortorder)) . '&rowid=' . urlencode((string) ($rowid)) . '&code=' . urlencode((string) ($code)) . '&id=' . urlencode((string) ($id)), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1);
1220
        }
1221
//var_dump($elementList);
1222
1223
        /*
1224
         * Show a dictionary
1225
         */
1226
        if ($id) {
1227
            // Complete requete recherche valeurs avec critere de tri
1228
            $sql = $tabsql[$id];
1229
1230
            if ($search_country_id > 0) {
1231
                if (preg_match('/ WHERE /', $sql)) {
1232
                    $sql .= " AND ";
1233
                } else {
1234
                    $sql .= " WHERE ";
1235
                }
1236
                $sql .= " c.rowid = " . ((int) $search_country_id);
1237
            }
1238
1239
            // If sort order is "country", we use country_code instead
1240
            if ($sortfield == 'country') {
1241
                $sortfield = 'country_code';
1242
            }
1243
            $sql .= $db->order($sortfield, $sortorder);
1244
            $sql .= $db->plimit($listlimit + 1, $offset);
1245
            //print $sql;
1246
1247
            $fieldlist = explode(',', $tabfield[$id]);
1248
1249
            print '<form action="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '" method="POST">';
1250
            print '<input type="hidden" name="token" value="' . newToken() . '">';
1251
1252
            print '<div class="div-table-responsive">';
1253
            print '<table class="noborder centpercent">';
1254
1255
            // Form to add a new line
1256
1257
            if ($tabname[$id]) {
1258
                $fieldlist = explode(',', $tabfield[$id]);
1259
1260
                // Line for title
1261
                print '<tr class="liste_titre">';
1262
                foreach ($fieldlist as $field => $value) {
1263
                    // Determine le nom du champ par rapport aux noms possibles
1264
                    // dans les dictionnaires de donnees
1265
                    $valuetoshow = ucfirst($fieldlist[$field]); // By default
1266
                    $valuetoshow = $langs->trans($valuetoshow); // try to translate
1267
                    $class = "left";
1268
                    if ($fieldlist[$field] == 'code') {
1269
                        $valuetoshow = $langs->trans("Code");
1270
                    }
1271
                    if ($fieldlist[$field] == 'label') {
1272
                        $valuetoshow = $langs->trans("Label");
1273
                        $class = 'minwidth300';
1274
                    }
1275
                    if ($fieldlist[$field] == 'country') {
1276
                        if (in_array('region_id', $fieldlist)) {
1277
                            print '<td>&nbsp;</td>';
1278
                            continue;
1279
                        }       // For region page, we do not show the country input
1280
                        $valuetoshow = $langs->trans("Country");
1281
                    }
1282
                    if ($fieldlist[$field] == 'country_id') {
1283
                        $valuetoshow = '';
1284
                    }
1285
                    if ($fieldlist[$field] == 'pcg_version' || $fieldlist[$field] == 'fk_pcg_version') {
1286
                        $valuetoshow = $langs->trans("Pcg_version");
1287
                    }
1288
                    //var_dump($value);
1289
1290
                    if ($valuetoshow != '') {
1291
                        print '<td class="' . $class . '">';
1292
                        if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) {
1293
                            print '<a href="' . $tabhelp[$id][$value] . '">' . $valuetoshow . ' ' . img_help(1, $valuetoshow) . '</a>';
1294
                        } elseif (!empty($tabhelp[$id][$value])) {
1295
                            print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]);
1296
                        } else {
1297
                            print $valuetoshow;
1298
                        }
1299
                        print '</td>';
1300
                    }
1301
                }
1302
1303
                print '<td>';
1304
                print '<input type="hidden" name="id" value="' . $id . '">';
1305
                print '</td>';
1306
                print '<td></td>';
1307
                print '<td></td>';
1308
                print '</tr>';
1309
1310
                // Line to enter new values
1311
                print '<tr class="oddeven">';
1312
1313
                $obj = new stdClass();
1314
                // If data was already input, we define them in obj to populate input fields.
1315
                if (GETPOST('actionadd', 'alpha')) {
1316
                    foreach ($fieldlist as $key => $val) {
1317
                        if (GETPOST($val)) {
1318
                            $obj->$val = GETPOST($val);
1319
                        }
1320
                    }
1321
                }
1322
1323
                $tmpaction = 'create';
1324
                $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
1325
                $reshook = $hookmanager->executeHooks('createDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
1326
                $error = $hookmanager->error;
1327
                $errors = $hookmanager->errors;
1328
1329
                if (empty($reshook)) {
1330
                    $this->fieldListAccountModel($fieldlist, $obj, $tabname[$id], 'add');
1331
                }
1332
1333
                print '<td colspan="3" class="right">';
1334
                print '<input type="submit" class="button button-add" name="actionadd" value="' . $langs->trans("Add") . '">';
1335
                print '</td>';
1336
                print "</tr>";
1337
1338
                $colspan = count($fieldlist) + 3;
1339
1340
                print '<tr><td colspan="' . $colspan . '">&nbsp;</td></tr>'; // Keep &nbsp; to have a line with enough height
1341
            }
1342
1343
1344
            // List of available values in database
1345
            dol_syslog("htdocs/admin/dict", LOG_DEBUG);
1346
            $resql = $db->query($sql);
1347
            if ($resql) {
1348
                $num = $db->num_rows($resql);
1349
                $i = 0;
1350
1351
                $param = '&id=' . urlencode((string) ($id));
1352
                if ($search_country_id > 0) {
1353
                    $param .= '&search_country_id=' . urlencode((string) ($search_country_id));
1354
                }
1355
                $paramwithsearch = $param;
1356
                if ($sortorder) {
1357
                    $paramwithsearch .= '&sortorder=' . urlencode($sortorder);
1358
                }
1359
                if ($sortfield) {
1360
                    $paramwithsearch .= '&sortfield=' . urlencode($sortfield);
1361
                }
1362
1363
                // There is several pages
1364
                if ($num > $listlimit) {
1365
                    print '<tr class="none"><td class="right" colspan="' . (3 + count($fieldlist)) . '">';
1366
                    print_fleche_navigation($page, $_SERVER['PHP_SELF'], $paramwithsearch, ($num > $listlimit), '<li class="pagination"><span>' . $langs->trans("Page") . ' ' . ($page + 1) . '</span></li>');
1367
                    print '</td></tr>';
1368
                }
1369
1370
                // Title line with search boxes
1371
                print '<tr class="liste_titre liste_titre_add">';
1372
                foreach ($fieldlist as $field => $value) {
1373
                    $showfield = 1; // By default
1374
1375
                    if ($fieldlist[$field] == 'region_id' || $fieldlist[$field] == 'country_id') {
1376
                        $showfield = 0;
1377
                    }
1378
1379
                    if ($showfield) {
1380
                        if ($value == 'country') {
1381
                            print '<td class="liste_titre">';
1382
                            print $form->select_country($search_country_id, 'search_country_id', '', 28, 'maxwidth200 maxwidthonsmartphone');
1383
                            print '</td>';
1384
                        } else {
1385
                            print '<td class="liste_titre"></td>';
1386
                        }
1387
                    }
1388
                }
1389
                print '<td class="liste_titre"></td>';
1390
                print '<td class="liste_titre right" colspan="2">';
1391
                $searchpicto = $form->showFilterAndCheckAddButtons(0);
1392
                print $searchpicto;
1393
                print '</td>';
1394
                print '</tr>';
1395
1396
                // Title of lines
1397
                print '<tr class="liste_titre">';
1398
                print getTitleFieldOfList($langs->trans("Pcg_version"), 0, $_SERVER['PHP_SELF'], "pcg_version", ($page ? 'page=' . $page . '&' : ''), $param, '', $sortfield, $sortorder, '');
1399
                print getTitleFieldOfList($langs->trans("Label"), 0, $_SERVER['PHP_SELF'], "label", ($page ? 'page=' . $page . '&' : ''), $param, '', $sortfield, $sortorder, '');
1400
                print getTitleFieldOfList($langs->trans("Country"), 0, $_SERVER['PHP_SELF'], "country_code", ($page ? 'page=' . $page . '&' : ''), $param, '', $sortfield, $sortorder, '');
1401
                print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER['PHP_SELF'], "active", ($page ? 'page=' . $page . '&' : ''), $param, '', $sortfield, $sortorder, 'center ');
1402
                print getTitleFieldOfList('');
1403
                print getTitleFieldOfList('');
1404
                print '</tr>';
1405
1406
                if ($num) {
1407
                    $i = 0;
1408
                    // Lines with values
1409
                    while ($i < $num) {
1410
                        $obj = $db->fetch_object($resql);
1411
                        //print_r($obj);
1412
1413
                        print '<tr class="oddeven" id="rowid-' . $obj->rowid . '">';
1414
                        if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) {
1415
                            print '<form action="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '" method="POST">';
1416
                            print '<input type="hidden" name="token" value="' . newToken() . '">';
1417
                            print '<input type="hidden" name="page" value="' . $page . '">';
1418
                            print '<input type="hidden" name="rowid" value="' . $rowid . '">';
1419
1420
                            $tmpaction = 'edit';
1421
                            $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
1422
                            $reshook = $hookmanager->executeHooks('editDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
1423
                            $error = $hookmanager->error;
1424
                            $errors = $hookmanager->errors;
1425
1426
                            if (empty($reshook)) {
1427
                                $this->fieldListAccountModel($fieldlist, $obj, $tabname[$id], 'edit');
1428
                            }
1429
1430
                            print '<td colspan="3" class="right">';
1431
                            print '<a name="' . (!empty($obj->rowid) ? $obj->rowid : $obj->code) . '">&nbsp;</a><input type="submit" class="button button-edit" name="actionmodify" value="' . $langs->trans("Modify") . '">';
1432
                            print '&nbsp;<input type="submit" class="button button-cancel" name="actioncancel" value="' . $langs->trans("Cancel") . '">';
1433
                            print '</td>';
1434
                        } else {
1435
                            $tmpaction = 'view';
1436
                            $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
1437
                            $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
1438
1439
                            $error = $hookmanager->error;
1440
                            $errors = $hookmanager->errors;
1441
1442
                            if (empty($reshook)) {
1443
                                foreach ($fieldlist as $field => $value) {
1444
                                    $showfield = 1;
1445
                                    $class = "left";
1446
                                    $tmpvar = $fieldlist[$field];
1447
                                    $valuetoshow = $obj->$tmpvar;
1448
                                    if ($value == 'type_template') {
1449
                                        $valuetoshow = isset($elementList[$valuetoshow]) ? $elementList[$valuetoshow] : $valuetoshow;
1450
                                    }
1451
                                    if ($value == 'element') {
1452
                                        $valuetoshow = isset($elementList[$valuetoshow]) ? $elementList[$valuetoshow] : $valuetoshow;
1453
                                    } elseif ($value == 'source') {
1454
                                        $valuetoshow = isset($sourceList[$valuetoshow]) ? $sourceList[$valuetoshow] : $valuetoshow;
1455
                                    } elseif ($valuetoshow == 'all') {
1456
                                        $valuetoshow = $langs->trans('All');
1457
                                    } elseif ($fieldlist[$field] == 'country') {
1458
                                        if (empty($obj->country_code)) {
1459
                                            $valuetoshow = '-';
1460
                                        } else {
1461
                                            $key = $langs->trans("Country" . strtoupper($obj->country_code));
1462
                                            $valuetoshow = ($key != "Country" . strtoupper($obj->country_code) ? $obj->country_code . " - " . $key : $obj->country);
1463
                                        }
1464
                                    } elseif ($fieldlist[$field] == 'country_id') {
1465
                                        $showfield = 0;
1466
                                    }
1467
1468
                                    $class = 'tddict';
1469
                                    if ($fieldlist[$field] == 'tracking') {
1470
                                        $class .= ' tdoverflowauto';
1471
                                    }
1472
                                    // Show value for field
1473
                                    if ($showfield) {
1474
                                        print '<!-- ' . $fieldlist[$field] . ' --><td class="' . $class . '">' . $valuetoshow . '</td>';
1475
                                    }
1476
                                }
1477
                            }
1478
1479
                            // Can an entry be erased or disabled ?
1480
                            $iserasable = 1;
1481
                            $canbedisabled = 1;
1482
                            $canbemodified = 1; // true by default
1483
1484
                            $url = $_SERVER['PHP_SELF'] . '?token=' . newToken() . ($page ? '&page=' . $page : '') . '&sortfield=' . $sortfield . '&sortorder=' . $sortorder . '&rowid=' . (!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')) . '&code=' . (!empty($obj->code) ? urlencode($obj->code) : '');
1485
                            if ($param) {
1486
                                $url .= '&' . $param;
1487
                            }
1488
                            $url .= '&';
1489
1490
                            // Active
1491
                            print '<td class="center nowrap">';
1492
                            if ($canbedisabled) {
1493
                                print '<a href="' . $url . 'action=' . $acts[$obj->active] . '">' . $actl[$obj->active] . '</a>';
1494
                            } else {
1495
                                print $langs->trans("AlwaysActive");
1496
                            }
1497
                            print "</td>";
1498
1499
                            // Modify link
1500
                            if ($canbemodified) {
1501
                                print '<td class="center"><a class="reposition editfielda" href="' . $url . 'action=edit&token=' . newToken() . '">' . img_edit() . '</a></td>';
1502
                            } else {
1503
                                print '<td>&nbsp;</td>';
1504
                            }
1505
1506
                            // Delete link
1507
                            if ($iserasable) {
1508
                                print '<td class="center"><a href="' . $url . 'action=delete&token=' . newToken() . '">' . img_delete() . '</a></td>';
1509
                            } else {
1510
                                print '<td>&nbsp;</td>';
1511
                            }
1512
1513
                            print "</tr>\n";
1514
                        }
1515
1516
                        $i++;
1517
                    }
1518
                } else {
1519
                    print '<tr><td colspan="6"><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
1520
                }
1521
            } else {
1522
                dol_print_error($db);
1523
            }
1524
1525
            print '</table>';
1526
            print '</div>';
1527
1528
            print '</form>';
1529
        }
1530
1531
        print '<br>';
1532
1533
// End of page
1534
        llxFooter();
1535
        $db->close();
1536
    }
1537
1538
    /**
1539
     *  \file       htdocs/accountancy/admin/card.php
1540
     *  \ingroup    Accountancy (Double entries)
1541
     *  \brief      Card of accounting account
1542
     */
1543
    public function card()
1544
    {
1545
        global $conf;
1546
        global $db;
1547
        global $user;
1548
        global $hookmanager;
1549
        global $user;
1550
        global $menumanager;
1551
        global $langs;
1552
1553
        $error = 0;
1554
1555
// Load translation files required by the page
1556
        $langs->loadLangs(['accountancy', 'bills', 'compta']);
1557
1558
        $action = GETPOST('action', 'aZ09');
1559
        $backtopage = GETPOST('backtopage', 'alpha');
1560
        $id = GETPOSTINT('id');
1561
        $ref = GETPOST('ref', 'alpha');
1562
        $rowid = GETPOSTINT('rowid');
1563
        $cancel = GETPOST('cancel', 'alpha');
1564
1565
        $account_number = GETPOST('account_number', 'alphanohtml');
1566
        $label = GETPOST('label', 'alpha');
1567
1568
// Security check
1569
        if ($user->socid > 0) {
1570
            accessforbidden();
1571
        }
1572
        if (!$user->hasRight('accounting', 'chartofaccount')) {
1573
            accessforbidden();
1574
        }
1575
1576
1577
        $object = new AccountingAccount($db);
1578
1579
1580
        /*
1581
         * Action
1582
         */
1583
1584
        if (GETPOST('cancel', 'alpha')) {
1585
            $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT . '/accountancy/admin/account.php';
1586
            header("Location: " . $urltogo);
1587
            exit;
1588
        }
1589
1590
        if ($action == 'add' && $user->hasRight('accounting', 'chartofaccount')) {
1591
            if (!$cancel) {
1592
                if (!$account_number) {
1593
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
1594
                    $action = 'create';
1595
                } elseif (!$label) {
1596
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
1597
                    $action = 'create';
1598
                } else {
1599
                    $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid = " . ((int) getDolGlobalInt('CHARTOFACCOUNTS'));
1600
1601
                    dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
1602
                    $result = $db->query($sql);
1603
                    $obj = $db->fetch_object($result);
1604
1605
                    // Clean code
1606
1607
                    // To manage zero or not at the end of the accounting account
1608
                    if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
1609
                        $account_number = clean_account($account_number);
1610
                    }
1611
1612
                    $account_parent = (GETPOSTINT('account_parent') > 0) ? GETPOSTINT('account_parent') : 0;
1613
1614
                    $object->fk_pcg_version = $obj->pcg_version;
1615
                    $object->pcg_type = GETPOST('pcg_type', 'alpha');
1616
                    $object->account_number = $account_number;
1617
                    $object->account_parent = $account_parent;
1618
                    $object->account_category = GETPOSTINT('account_category');
1619
                    $object->label = $label;
1620
                    $object->labelshort = GETPOST('labelshort', 'alpha');
1621
                    $object->active = 1;
1622
1623
                    $res = $object->create($user);
1624
                    if ($res == -3) {
1625
                        $error = 1;
1626
                        $action = "create";
1627
                        setEventMessages($object->error, $object->errors, 'errors');
1628
                    } elseif ($res == -4) {
1629
                        $error = 2;
1630
                        $action = "create";
1631
                        setEventMessages($object->error, $object->errors, 'errors');
1632
                    } elseif ($res < 0) {
1633
                        $error++;
1634
                        setEventMessages($object->error, $object->errors, 'errors');
1635
                        $action = "create";
1636
                    }
1637
                    if (!$error) {
1638
                        setEventMessages("RecordCreatedSuccessfully", null, 'mesgs');
1639
                        $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT . '/accountancy/admin/account.php';
1640
                        header("Location: " . $urltogo);
1641
                        exit;
1642
                    }
1643
                }
1644
            }
1645
        } elseif ($action == 'edit' && $user->hasRight('accounting', 'chartofaccount')) {
1646
            if (!$cancel) {
1647
                if (!$account_number) {
1648
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
1649
                    $action = 'update';
1650
                } elseif (!$label) {
1651
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
1652
                    $action = 'update';
1653
                } else {
1654
                    $result = $object->fetch($id);
1655
1656
                    $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid=" . ((int) getDolGlobalInt('CHARTOFACCOUNTS'));
1657
1658
                    dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
1659
                    $result2 = $db->query($sql);
1660
                    $obj = $db->fetch_object($result2);
1661
1662
                    // Clean code
1663
1664
                    // To manage zero or not at the end of the accounting account
1665
                    if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
1666
                        $account_number = clean_account($account_number);
1667
                    }
1668
1669
                    $account_parent = (GETPOSTINT('account_parent') > 0) ? GETPOSTINT('account_parent') : 0;
1670
1671
                    $object->fk_pcg_version = $obj->pcg_version;
1672
                    $object->pcg_type = GETPOST('pcg_type', 'alpha');
1673
                    $object->account_number = $account_number;
1674
                    $object->account_parent = $account_parent;
1675
                    $object->account_category = GETPOSTINT('account_category');
1676
                    $object->label = $label;
1677
                    $object->labelshort = GETPOST('labelshort', 'alpha');
1678
1679
                    $result = $object->update($user);
1680
1681
                    if ($result > 0) {
1682
                        $urltogo = $backtopage ? $backtopage : ($_SERVER['PHP_SELF'] . "?id=" . $id);
1683
                        header("Location: " . $urltogo);
1684
                        exit();
1685
                    } elseif ($result == -2) {
1686
                        setEventMessages($langs->trans("ErrorAccountNumberAlreadyExists", $object->account_number), null, 'errors');
1687
                    } else {
1688
                        setEventMessages($object->error, null, 'errors');
1689
                    }
1690
                }
1691
            } else {
1692
                $urltogo = $backtopage ? $backtopage : ($_SERVER['PHP_SELF'] . "?id=" . $id);
1693
                header("Location: " . $urltogo);
1694
                exit();
1695
            }
1696
        } elseif ($action == 'delete' && $user->hasRight('accounting', 'chartofaccount')) {
1697
            $result = $object->fetch($id);
1698
1699
            if (!empty($object->id)) {
1700
                $result = $object->delete($user);
1701
1702
                if ($result > 0) {
1703
                    header("Location: account.php");
1704
                    exit;
1705
                }
1706
            }
1707
1708
            if ($result < 0) {
1709
                setEventMessages($object->error, $object->errors, 'errors');
1710
            }
1711
        }
1712
1713
1714
        /*
1715
         * View
1716
         */
1717
1718
        $form = new Form($db);
1719
        $formaccounting = new FormAccounting($db);
1720
1721
        $accountsystem = new AccountancySystem($db);
1722
        $accountsystem->fetch(getDolGlobalInt('CHARTOFACCOUNTS'));
1723
1724
        $title = $langs->trans('AccountAccounting') . " - " . $langs->trans('Card');
1725
1726
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
1727
1728
        llxHeader('', $title, $help_url);
1729
1730
1731
// Create mode
1732
        if ($action == 'create') {
1733
            print load_fiche_titre($langs->trans('NewAccountingAccount'));
1734
1735
            print '<form name="add" action="' . $_SERVER['PHP_SELF'] . '" method="POST">' . "\n";
1736
            print '<input type="hidden" name="token" value="' . newToken() . '">';
1737
            print '<input type="hidden" name="action" value="add">';
1738
1739
            print dol_get_fiche_head();
1740
1741
            print '<table class="border centpercent">';
1742
1743
            // Chart of account
1744
            print '<tr><td class="titlefieldcreate"><span class="fieldrequired">' . $langs->trans("Chartofaccounts") . '</span></td>';
1745
            print '<td>';
1746
            print $accountsystem->ref;
1747
            print '</td></tr>';
1748
1749
            // Account number
1750
            print '<tr><td class="titlefieldcreate"><span class="fieldrequired">' . $langs->trans("AccountNumber") . '</span></td>';
1751
            print '<td><input name="account_number" size="30" value="' . $account_number . '"></td></tr>';
1752
1753
            // Label
1754
            print '<tr><td><span class="fieldrequired">' . $langs->trans("Label") . '</span></td>';
1755
            print '<td><input name="label" size="70" value="' . $object->label . '"></td></tr>';
1756
1757
            // Label short
1758
            print '<tr><td>' . $langs->trans("LabelToShow") . '</td>';
1759
            print '<td><input name="labelshort" size="70" value="' . $object->labelshort . '"></td></tr>';
1760
1761
            // Account parent
1762
            print '<tr><td>' . $langs->trans("Accountparent") . '</td>';
1763
            print '<td>';
1764
            print $formaccounting->select_account($object->account_parent, 'account_parent', 1, [], 0, 0, 'minwidth200');
1765
            print '</td></tr>';
1766
1767
            // Chart of accounts type
1768
            print '<tr><td>';
1769
            print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
1770
            print '</td>';
1771
            print '<td>';
1772
            print '<input type="text" name="pcg_type" list="pcg_type_datalist" value="' . dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type) . '">';
1773
            // autosuggest from existing account types if found
1774
            print '<datalist id="pcg_type_datalist">';
1775
            $sql = "SELECT DISTINCT pcg_type FROM " . MAIN_DB_PREFIX . "accounting_account";
1776
            $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
1777
            $sql .= ' AND entity in (' . getEntity('accounting_account', 0) . ')';      // Always limit to current entity. No sharing in accountancy.
1778
            $sql .= ' LIMIT 50000'; // just as a sanity check
1779
            $resql = $db->query($sql);
1780
            if ($resql) {
1781
                while ($obj = $db->fetch_object($resql)) {
1782
                    print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
1783
                }
1784
            }
1785
            print '</datalist>';
1786
            print '</td></tr>';
1787
1788
            // Category
1789
            print '<tr><td>';
1790
            print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
1791
            print '</td>';
1792
            print '<td>';
1793
            print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1, 0, 1);
1794
            print '</td></tr>';
1795
1796
            print '</table>';
1797
1798
            print dol_get_fiche_end();
1799
1800
            print '<div class="center">';
1801
            print '<input class="button button-save" type="submit" value="' . $langs->trans("Save") . '">';
1802
            print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
1803
            print '<input class="button button-cancel" type="submit" name="cancel" value="' . $langs->trans("Cancel") . '">';
1804
            print '</div>';
1805
1806
            print '</form>';
1807
        } elseif ($id > 0 || $ref) {
1808
            $result = $object->fetch($id, $ref, 1);
1809
1810
            if ($result > 0) {
1811
                $head = accounting_prepare_head($object);
1812
1813
                // Edit mode
1814
                if ($action == 'update') {
1815
                    print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'accounting_account');
1816
1817
                    print '<form name="update" action="' . $_SERVER['PHP_SELF'] . '" method="POST">' . "\n";
1818
                    print '<input type="hidden" name="token" value="' . newToken() . '">';
1819
                    print '<input type="hidden" name="action" value="edit">';
1820
                    print '<input type="hidden" name="id" value="' . $id . '">';
1821
                    print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
1822
1823
                    print '<table class="border centpercent">';
1824
1825
                    // Account number
1826
                    print '<tr><td class="titlefieldcreate"><span class="fieldrequired">' . $langs->trans("AccountNumber") . '</span></td>';
1827
                    print '<td><input name="account_number" size="30" value="' . $object->account_number . '"</td></tr>';
1828
1829
                    // Label
1830
                    print '<tr><td><span class="fieldrequired">' . $langs->trans("Label") . '</span></td>';
1831
                    print '<td><input name="label" size="70" value="' . $object->label . '"</td></tr>';
1832
1833
                    // Label short
1834
                    print '<tr><td>' . $langs->trans("LabelToShow") . '</td>';
1835
                    print '<td><input name="labelshort" size="70" value="' . $object->labelshort . '"</td></tr>';
1836
1837
                    // Account parent
1838
                    print '<tr><td>' . $langs->trans("Accountparent") . '</td>';
1839
                    print '<td>';
1840
                    // Note: We accept disabled account as parent account so we can build a hierarchy and use only children
1841
                    print $formaccounting->select_account($object->account_parent, 'account_parent', 1, [], 0, 0, 'minwidth100 maxwidth300 maxwidthonsmartphone', 1, '');
1842
                    print '</td></tr>';
1843
1844
                    // Chart of accounts type
1845
                    print '<tr><td>';
1846
                    print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
1847
                    print '</td>';
1848
                    print '<td>';
1849
                    print '<input type="text" name="pcg_type" list="pcg_type_datalist" value="' . dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type) . '">';
1850
                    // autosuggest from existing account types if found
1851
                    print '<datalist id="pcg_type_datalist">';
1852
                    $sql = 'SELECT DISTINCT pcg_type FROM ' . MAIN_DB_PREFIX . 'accounting_account';
1853
                    $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
1854
                    $sql .= ' AND entity in (' . getEntity('accounting_account', 0) . ')';      // Always limit to current entity. No sharing in accountancy.
1855
                    $sql .= ' LIMIT 50000'; // just as a sanity check
1856
                    $resql = $db->query($sql);
1857
                    if ($resql) {
1858
                        while ($obj = $db->fetch_object($resql)) {
1859
                            print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
1860
                        }
1861
                    }
1862
                    print '</datalist>';
1863
                    print '</td></tr>';
1864
1865
                    // Category
1866
                    print '<tr><td>';
1867
                    print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
1868
                    print '</td>';
1869
                    print '<td>';
1870
                    print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
1871
                    print '</td></tr>';
1872
1873
                    print '</table>';
1874
1875
                    print dol_get_fiche_end();
1876
1877
                    print $form->buttonsSaveCancel();
1878
1879
                    print '</form>';
1880
                } else {
1881
                    // View mode
1882
                    $linkback = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/account.php?restore_lastsearch_values=1">' . $langs->trans("BackToList") . '</a>';
1883
1884
                    print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'accounting_account');
1885
1886
                    dol_banner_tab($object, 'ref', $linkback, 1, 'account_number', 'ref');
1887
1888
1889
                    print '<div class="fichecenter">';
1890
                    print '<div class="underbanner clearboth"></div>';
1891
1892
                    print '<table class="border centpercent tableforfield">';
1893
1894
                    // Label
1895
                    print '<tr><td class="titlefield">' . $langs->trans("Label") . '</td>';
1896
                    print '<td colspan="2">' . $object->label . '</td></tr>';
1897
1898
                    // Label to show
1899
                    print '<tr><td class="titlefield">' . $langs->trans("LabelToShow") . '</td>';
1900
                    print '<td colspan="2">' . $object->labelshort . '</td></tr>';
1901
1902
                    // Account parent
1903
                    $accp = new AccountingAccount($db);
1904
                    if (!empty($object->account_parent)) {
1905
                        $accp->fetch($object->account_parent, '');
1906
                    }
1907
                    print '<tr><td>' . $langs->trans("Accountparent") . '</td>';
1908
                    print '<td colspan="2">' . $accp->account_number . ' - ' . $accp->label . '</td></tr>';
1909
1910
                    // Group of accounting account
1911
                    print '<tr><td>';
1912
                    print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
1913
                    print '</td>';
1914
                    print '<td colspan="2">' . $object->pcg_type . '</td></tr>';
1915
1916
                    // Custom group of accounting account
1917
                    print "<tr><td>";
1918
                    print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
1919
                    print "</td><td colspan='2'>" . $object->account_category_label . "</td>";
1920
1921
                    print '</table>';
1922
1923
                    print '</div>';
1924
1925
                    print dol_get_fiche_end();
1926
1927
                    /*
1928
                     * Actions buttons
1929
                     */
1930
                    print '<div class="tabsAction">';
1931
1932
                    if ($user->hasRight('accounting', 'chartofaccount')) {
1933
                        print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=update&token=' . newToken() . '&id=' . $object->id . '">' . $langs->trans('Modify') . '</a>';
1934
                    } else {
1935
                        print '<a class="butActionRefused classfortooltip" href="#" title="' . dol_escape_htmltag($langs->trans("NotAllowed")) . '">' . $langs->trans('Modify') . '</a>';
1936
                    }
1937
1938
                    // Delete
1939
                    $permissiontodelete = $user->hasRight('accounting', 'chartofaccount');
1940
                    print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=delete&token=' . newToken(), 'delete', $permissiontodelete);
1941
1942
                    print '</div>';
1943
                }
1944
            } else {
1945
                dol_print_error($db, $object->error, $object->errors);
1946
            }
1947
        }
1948
1949
// End of page
1950
        llxFooter();
1951
        $db->close();
1952
    }
1953
1954
    /**
1955
     * \file    htdocs/accountancy/admin/categories.php
1956
     * \ingroup Accountancy (Double entries)
1957
     * \brief   Page to assign mass categories to accounts
1958
     */
1959
    public function categories()
1960
    {
1961
        global $conf;
1962
        global $db;
1963
        global $user;
1964
        global $hookmanager;
1965
        global $user;
1966
        global $menumanager;
1967
        global $langs;
1968
1969
        $error = 0;
1970
1971
// Load translation files required by the page
1972
        $langs->loadLangs(["bills", "accountancy", "compta"]);
1973
1974
        $id = GETPOSTINT('id');
1975
        $cancel = GETPOST('cancel', 'alpha');
1976
        $action = GETPOST('action', 'aZ09');
1977
        $cat_id = GETPOSTINT('account_category');
1978
        $selectcpt = GETPOST('cpt_bk', 'array');
1979
        $cpt_id = GETPOSTINT('cptid');
1980
1981
        if ($cat_id == 0) {
1982
            $cat_id = null;
1983
        }
1984
1985
// Load variable for pagination
1986
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
1987
        $sortfield = GETPOST('sortfield', 'aZ09comma');
1988
        $sortorder = GETPOST('sortorder', 'aZ09comma');
1989
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
1990
        if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
1991
            // If $page is not defined, or '' or -1 or if we click on clear filters
1992
            $page = 0;
1993
        }
1994
        $offset = $limit * $page;
1995
        $pageprev = $page - 1;
1996
        $pagenext = $page + 1;
1997
1998
        if (empty($sortfield)) {
1999
            $sortfield = 'account_number';
2000
        }
2001
        if (empty($sortorder)) {
2002
            $sortorder = 'ASC';
2003
        }
2004
2005
// Security check
2006
        if (!$user->hasRight('accounting', 'chartofaccount')) {
2007
            accessforbidden();
2008
        }
2009
2010
        $accountingcategory = new AccountancyCategory($db);
2011
2012
2013
        /*
2014
         * Actions
2015
         */
2016
2017
// If we add account
2018
        if (!empty($selectcpt)) {
2019
            $cpts = [];
2020
            foreach ($selectcpt as $selectedoption) {
2021
                if (!array_key_exists($selectedoption, $cpts)) {
2022
                    $cpts[$selectedoption] = "'" . $selectedoption . "'";
2023
                }
2024
            }
2025
2026
            $return = $accountingcategory->updateAccAcc($cat_id, $cpts);
2027
2028
            if ($return < 0) {
2029
                setEventMessages($langs->trans('errors'), $accountingcategory->errors, 'errors');
2030
            } else {
2031
                setEventMessages($langs->trans('RecordModifiedSuccessfully'), null, 'mesgs');
2032
            }
2033
        }
2034
2035
        if ($action == 'delete') {
2036
            if ($cpt_id) {
2037
                if ($accountingcategory->deleteCptCat($cpt_id)) {
2038
                    setEventMessages($langs->trans('AccountRemovedFromGroup'), null, 'mesgs');
2039
                } else {
2040
                    setEventMessages($langs->trans('errors'), null, 'errors');
2041
                }
2042
            }
2043
        }
2044
2045
2046
        /*
2047
         * View
2048
         */
2049
2050
        $form = new Form($db);
2051
        $formaccounting = new FormAccounting($db);
2052
2053
        $title = $langs->trans('AccountingCategory');
2054
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
2055
2056
        llxHeader('', $title, $help_url);
2057
2058
        $linkback = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/categories_list.php?restore_lastsearch_values=1">' . $langs->trans("BackToList") . '</a>';
2059
        $titlepicto = 'setup';
2060
2061
        print load_fiche_titre($langs->trans('AccountingCategory'), $linkback, $titlepicto);
2062
2063
        print '<form name="add" action="' . $_SERVER['PHP_SELF'] . '" method="POST">' . "\n";
2064
        print '<input type="hidden" name="token" value="' . newToken() . '">';
2065
        print '<input type="hidden" name="action" value="display">';
2066
2067
        print dol_get_fiche_head();
2068
2069
        print '<table class="border centpercent">';
2070
2071
// Select the category
2072
        print '<tr><td class="titlefield">' . $langs->trans("AccountingCategory") . '</td>';
2073
        print '<td>';
2074
        $s = $formaccounting->select_accounting_category($cat_id, 'account_category', 1, 0, 0, 0);
2075
        if ($formaccounting->nbaccounts_category <= 0) {
2076
            print '<span class="opacitymedium">' . $s . '</span>';
2077
        } else {
2078
            print $s;
2079
            print '<input type="submit" class="button small" value="' . $langs->trans("Select") . '">';
2080
        }
2081
        print '</td></tr>';
2082
2083
        print '</table>';
2084
2085
        print dol_get_fiche_end();
2086
2087
2088
// Select the accounts
2089
        if (!empty($cat_id)) {
2090
            $return = $accountingcategory->getAccountsWithNoCategory($cat_id);
2091
            if ($return < 0) {
2092
                setEventMessages(null, $accountingcategory->errors, 'errors');
2093
            }
2094
            print '<br>';
2095
2096
            $arraykeyvalue = [];
2097
            foreach ($accountingcategory->lines_cptbk as $key => $val) {
2098
                $doc_ref = !empty($val->doc_ref) ? $val->doc_ref : '';
2099
                $arraykeyvalue[length_accountg($val->numero_compte)] = length_accountg($val->numero_compte) . ' - ' . $val->label_compte . ($doc_ref ? ' ' . $doc_ref : '');
2100
            }
2101
2102
            if (is_array($accountingcategory->lines_cptbk) && count($accountingcategory->lines_cptbk) > 0) {
2103
                print img_picto($langs->trans("AccountingAccount"), 'accounting_account', 'class="pictofixedwith"');
2104
                print $form->multiselectarray('cpt_bk', $arraykeyvalue, GETPOST('cpt_bk', 'array'), 0, 0, '', 0, "80%", '', '', $langs->transnoentitiesnoconv("AddAccountFromBookKeepingWithNoCategories"));
2105
                print '<input type="submit" class="button button-add small" id="" class="action-delete" value="' . $langs->trans("Add") . '"> ';
2106
            }
2107
        }
2108
2109
        print '</form>';
2110
2111
2112
        if ((empty($action) || $action == 'display' || $action == 'delete') && $cat_id > 0) {
2113
            $param = 'account_category=' . ((int) $cat_id);
2114
2115
            print '<br>';
2116
            print '<table class="noborder centpercent">' . "\n";
2117
            print '<tr class="liste_titre">';
2118
            print getTitleFieldOfList('AccountAccounting', 0, $_SERVER['PHP_SELF'], 'account_number', '', $param, '', $sortfield, $sortorder, '') . "\n";
2119
            print getTitleFieldOfList('Label', 0, $_SERVER['PHP_SELF'], 'label', '', $param, '', $sortfield, $sortorder, '') . "\n";
2120
            print getTitleFieldOfList('', 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, '') . "\n";
2121
            print '</tr>' . "\n";
2122
2123
            if (!empty($cat_id)) {
2124
                $return = $accountingcategory->display($cat_id); // This load ->lines_display
2125
                if ($return < 0) {
2126
                    setEventMessages(null, $accountingcategory->errors, 'errors');
2127
                }
2128
2129
                if (is_array($accountingcategory->lines_display) && count($accountingcategory->lines_display) > 0) {
2130
                    $accountingcategory->lines_display = dol_sort_array($accountingcategory->lines_display, $sortfield, $sortorder, -1, 0, 1);
2131
2132
                    foreach ($accountingcategory->lines_display as $cpt) {
2133
                        print '<tr class="oddeven">';
2134
                        print '<td>' . length_accountg($cpt->account_number) . '</td>';
2135
                        print '<td>' . $cpt->label . '</td>';
2136
                        print '<td class="right">';
2137
                        print '<a href="' . $_SERVER['PHP_SELF'] . '?action=delete&token=' . newToken() . '&account_category=' . $cat_id . '&cptid=' . $cpt->rowid . '">';
2138
                        print $langs->trans("DeleteFromCat");
2139
                        print img_picto($langs->trans("DeleteFromCat"), 'unlink', 'class="paddingleft"');
2140
                        print "</a>";
2141
                        print "</td>";
2142
                        print "</tr>\n";
2143
                    }
2144
                } else {
2145
                    print '<tr><td colspan="3"><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
2146
                }
2147
            }
2148
2149
            print "</table>";
2150
        }
2151
2152
// End of page
2153
        llxFooter();
2154
        $db->close();
2155
    }
2156
2157
    /**
2158
     *      \file       htdocs/accountancy/admin/categories_list.php
2159
     *      \ingroup    setup
2160
     *      \brief      Page to administer data tables
2161
     */
2162
    public function categories_list()
2163
    {
2164
        global $conf;
2165
        global $db;
2166
        global $user;
2167
        global $hookmanager;
2168
        global $user;
2169
        global $menumanager;
2170
        global $langs;
2171
2172
// Load translation files required by the page
2173
        $langs->loadLangs(["errors", "admin", "companies", "resource", "holiday", "accountancy", "hrm"]);
2174
2175
        $action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view';
2176
        $confirm = GETPOST('confirm', 'alpha');
2177
        $id = 32;
2178
        $rowid = GETPOST('rowid', 'alpha');
2179
        $code = GETPOST('code', 'alpha');
2180
2181
// Security access
2182
        if (!$user->hasRight('accounting', 'chartofaccount')) {
2183
            accessforbidden();
2184
        }
2185
2186
        $acts = [];
2187
        $acts[0] = "activate";
2188
        $acts[1] = "disable";
2189
        $actl = [];
2190
        $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
2191
        $actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"');
2192
2193
        $listoffset = GETPOST('listoffset', 'alpha');
2194
        $listlimit = GETPOSTINT('listlimit') > 0 ? GETPOSTINT('listlimit') : 1000;
2195
2196
        $sortfield = GETPOST("sortfield", 'aZ09comma');
2197
        $sortorder = GETPOST("sortorder", 'aZ09comma');
2198
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
2199
        if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
2200
            // If $page is not defined, or '' or -1 or if we click on clear filters
2201
            $page = 0;
2202
        }
2203
        $offset = $listlimit * $page;
2204
        $pageprev = $page - 1;
2205
        $pagenext = $page + 1;
2206
2207
        $search_country_id = GETPOSTINT('search_country_id');
2208
2209
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
2210
        $hookmanager->initHooks(['admin']);
2211
2212
// This page is a generic page to edit dictionaries
2213
// Put here declaration of dictionaries properties
2214
2215
// Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this.
2216
        $taborder = [32];
2217
2218
// Name of SQL tables of dictionaries
2219
        $tabname = [];
2220
        $tabname[32] = MAIN_DB_PREFIX . "c_accounting_category";
2221
2222
// Dictionary labels
2223
        $tablib = [];
2224
        $tablib[32] = "DictionaryAccountancyCategory";
2225
2226
// Requests to extract data
2227
        $tabsql = [];
2228
        $tabsql[32] = "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM " . MAIN_DB_PREFIX . "c_accounting_category as a, " . MAIN_DB_PREFIX . "c_country as c WHERE a.fk_country=c.rowid and c.active=1";
2229
2230
// Criteria to sort dictionaries
2231
        $tabsqlsort = [];
2232
        $tabsqlsort[32] = "position ASC";
2233
2234
// Name of the fields in the result of select to display the dictionary
2235
        $tabfield = [];
2236
        $tabfield[32] = "code,label,range_account,category_type,formula,position,country";
2237
2238
// Name of editing fields for record modification
2239
        $tabfieldvalue = [];
2240
        $tabfieldvalue[32] = "code,label,range_account,category_type,formula,position,country_id";
2241
2242
// Name of the fields in the table for inserting a record
2243
        $tabfieldinsert = [];
2244
        $tabfieldinsert[32] = "code,label,range_account,category_type,formula,position,fk_country";
2245
2246
// Name of the rowid if the field is not of type autoincrement
2247
// Example: "" if id field is "rowid" and has autoincrement on
2248
//          "nameoffield" if id field is not "rowid" or has not autoincrement on
2249
        $tabrowid = [];
2250
        $tabrowid[32] = "";
2251
2252
// Condition to show dictionary in setup page
2253
        $tabcond = [];
2254
        $tabcond[32] = isModEnabled('accounting');
2255
2256
// List of help for fields
2257
        $tabhelp = [];
2258
        $tabhelp[32] = ['code' => $langs->trans("EnterAnyCode"), 'category_type' => $langs->trans("SetToYesIfGroupIsComputationOfOtherGroups"), 'formula' => $langs->trans("EnterCalculationRuleIfPreviousFieldIsYes")];
2259
2260
// List of check for fields (NOT USED YET)
2261
        $tabfieldcheck = [];
2262
        $tabfieldcheck[32] = [];
2263
2264
// Complete all arrays with entries found into modules
2265
        complete_dictionary_with_modules($taborder, $tabname, $tablib, $tabsql, $tabsqlsort, $tabfield, $tabfieldvalue, $tabfieldinsert, $tabrowid, $tabcond, $tabhelp, $tabfieldcheck);
2266
2267
        $accountingcategory = new AccountancyCategory($db);
2268
2269
2270
        /*
2271
         * Actions
2272
         */
2273
2274
        if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) {
2275
            $search_country_id = '';
2276
        }
2277
2278
// Actions add or modify an entry into a dictionary
2279
        if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
2280
            $listfield = explode(',', str_replace(' ', '', $tabfield[$id]));
2281
            $listfieldinsert = explode(',', $tabfieldinsert[$id]);
2282
            $listfieldmodify = explode(',', $tabfieldinsert[$id]);
2283
            $listfieldvalue = explode(',', $tabfieldvalue[$id]);
2284
2285
            // Check that all fields are filled
2286
            $ok = 1;
2287
            foreach ($listfield as $f => $value) {
2288
                if ($value == 'formula' && !GETPOST('formula')) {
2289
                    continue;
2290
                }
2291
                if ($value == 'range_account' && !GETPOST('range_account')) {
2292
                    continue;
2293
                }
2294
                if (($value == 'country' || $value == 'country_id') && GETPOST('country_id')) {
2295
                    continue;
2296
                }
2297
                if (!GETPOSTISSET($value) || GETPOST($value) == '') {
2298
                    $ok = 0;
2299
                    $fieldnamekey = $listfield[$f];
2300
                    // We take translate key of field
2301
                    if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) {
2302
                        $fieldnamekey = 'Label';
2303
                    }
2304
                    if ($fieldnamekey == 'code') {
2305
                        $fieldnamekey = 'Code';
2306
                    }
2307
                    if ($fieldnamekey == 'note') {
2308
                        $fieldnamekey = 'Note';
2309
                    }
2310
                    if ($fieldnamekey == 'type') {
2311
                        $fieldnamekey = 'Type';
2312
                    }
2313
                    if ($fieldnamekey == 'position') {
2314
                        $fieldnamekey = 'Position';
2315
                    }
2316
                    if ($fieldnamekey == 'category_type') {
2317
                        $fieldnamekey = 'Calculated';
2318
                    }
2319
                    if ($fieldnamekey == 'country') {
2320
                        $fieldnamekey = 'Country';
2321
                    }
2322
2323
                    setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors');
2324
                }
2325
            }
2326
            if (GETPOSTISSET("code")) {
2327
                if (GETPOST("code") == '0') {
2328
                    $ok = 0;
2329
                    setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
2330
                }
2331
            }
2332
            if (GETPOST('position') && !is_numeric(GETPOST('position', 'alpha'))) {
2333
                $langs->loadLangs(["errors"]);
2334
                $ok = 0;
2335
                setEventMessages($langs->transnoentities('ErrorFieldMustBeANumeric', $langs->transnoentities("Position")), null, 'errors');
2336
            }
2337
2338
            // Si verif ok et action add, on ajoute la ligne
2339
            if ($ok && GETPOST('actionadd', 'alpha')) {
2340
                $newid = 0;
2341
2342
                if ($tabrowid[$id]) {
2343
                    // Get free id for insert
2344
                    $sql = "SELECT MAX(" . $db->sanitize($tabrowid[$id]) . ") newid FROM " . $db->sanitize($tabname[$id]);
2345
                    $result = $db->query($sql);
2346
                    if ($result) {
2347
                        $obj = $db->fetch_object($result);
2348
                        $newid = ($obj->newid + 1);
2349
                    } else {
2350
                        dol_print_error($db);
2351
                    }
2352
                }
2353
2354
                // Add new entry
2355
                $sql = "INSERT INTO " . $db->sanitize($tabname[$id]) . " (";
2356
                // List of fields
2357
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
2358
                    $sql .= $db->sanitize($tabrowid[$id]) . ",";
2359
                }
2360
                $sql .= $db->sanitize($tabfieldinsert[$id]);
2361
                $sql .= ",active)";
2362
                $sql .= " VALUES(";
2363
2364
                // List of values
2365
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
2366
                    $sql .= $newid . ",";
2367
                }
2368
                $i = 0;
2369
                foreach ($listfieldinsert as $f => $value) {
2370
                    if ($value == 'entity') {
2371
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
2372
                    }
2373
                    if ($i) {
2374
                        $sql .= ",";
2375
                    }
2376
                    if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'formula') {
2377
                        $sql .= "null"; // For vat, we want/accept code = ''
2378
                    } else {
2379
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
2380
                    }
2381
                    $i++;
2382
                }
2383
                $sql .= ",1)";
2384
2385
                dol_syslog("actionadd", LOG_DEBUG);
2386
                $result = $db->query($sql);
2387
                if ($result) {  // Add is ok
2388
                    setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
2389
                    $_POST = ['id' => $id]; // Clean $_POST array, we keep only
2390
                } else {
2391
                    if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2392
                        setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
2393
                    } else {
2394
                        dol_print_error($db);
2395
                    }
2396
                }
2397
            }
2398
2399
            // If check ok and action modify, we modify the line
2400
            if ($ok && GETPOST('actionmodify', 'alpha')) {
2401
                if ($tabrowid[$id]) {
2402
                    $rowidcol = $tabrowid[$id];
2403
                } else {
2404
                    $rowidcol = "rowid";
2405
                }
2406
2407
                // Modify entry
2408
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET ";
2409
                // Modifie valeur des champs
2410
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) {
2411
                    $sql .= $db->sanitize($tabrowid[$id]) . " = ";
2412
                    $sql .= "'" . $db->escape($rowid) . "', ";
2413
                }
2414
                $i = 0;
2415
                foreach ($listfieldmodify as $field) {
2416
                    if ($field == 'fk_country' && GETPOST('country') > 0) {
2417
                        $_POST[$listfieldvalue[$i]] = GETPOST('country');
2418
                    } elseif ($field == 'entity') {
2419
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
2420
                    }
2421
                    if ($i) {
2422
                        $sql .= ",";
2423
                    }
2424
                    $sql .= $field . "=";
2425
                    if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'range_account') {
2426
                        $sql .= "null"; // For range_account, we want/accept code = ''
2427
                    } else {
2428
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
2429
                    }
2430
                    $i++;
2431
                }
2432
                $sql .= " WHERE " . $rowidcol . " = " . ((int) $rowid);
2433
2434
                dol_syslog("actionmodify", LOG_DEBUG);
2435
                //print $sql;
2436
                $resql = $db->query($sql);
2437
                if (!$resql) {
2438
                    setEventMessages($db->error(), null, 'errors');
2439
                }
2440
            }
2441
            //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
2442
        }
2443
2444
// if (GETPOST('actioncancel', 'alpha')) {
2445
//  $_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
2446
// }
2447
2448
        if ($action == 'confirm_delete' && $confirm == 'yes') {       // delete
2449
            $rowidcol = "rowid";
2450
2451
            $sql = "DELETE from " . $db->sanitize($tabname[$id]) . " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2452
2453
            dol_syslog("delete", LOG_DEBUG);
2454
            $result = $db->query($sql);
2455
            if (!$result) {
2456
                if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') {
2457
                    setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors');
2458
                } else {
2459
                    dol_print_error($db);
2460
                }
2461
            }
2462
        }
2463
2464
// activate
2465
        if ($action == $acts[0]) {
2466
            $rowidcol = "rowid";
2467
2468
            if ($rowid) {
2469
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2470
            } elseif ($code) {
2471
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE code = '" . $db->escape($code) . "'";
2472
            }
2473
2474
            if ($sql) {
2475
                $result = $db->query($sql);
2476
                if (!$result) {
2477
                    dol_print_error($db);
2478
                }
2479
            }
2480
        }
2481
2482
// disable
2483
        if ($action == $acts[1]) {
2484
            $rowidcol = "rowid";
2485
2486
            if ($rowid) {
2487
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2488
            } elseif ($code) {
2489
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE code = '" . $db->escape($code) . "'";
2490
            }
2491
2492
            if ($sql) {
2493
                $result = $db->query($sql);
2494
                if (!$result) {
2495
                    dol_print_error($db);
2496
                }
2497
            }
2498
        }
2499
2500
// favorite
2501
        if ($action == 'activate_favorite') {
2502
            $rowidcol = "rowid";
2503
2504
            if ($rowid) {
2505
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 1 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2506
            } elseif ($code) {
2507
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 1 WHERE code = '" . $db->escape($code) . "'";
2508
            }
2509
2510
            if ($sql) {
2511
                $result = $db->query($sql);
2512
                if (!$result) {
2513
                    dol_print_error($db);
2514
                }
2515
            }
2516
        }
2517
2518
// disable favorite
2519
        if ($action == 'disable_favorite') {
2520
            $rowidcol = "rowid";
2521
2522
            if ($rowid) {
2523
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 0 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2524
            } elseif ($code) {
2525
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 0 WHERE code = '" . $db->escape($code) . "'";
2526
            }
2527
2528
            if ($sql) {
2529
                $result = $db->query($sql);
2530
                if (!$result) {
2531
                    dol_print_error($db);
2532
                }
2533
            }
2534
        }
2535
2536
2537
        /*
2538
         * View
2539
         */
2540
2541
        $form = new Form($db);
2542
        $formadmin = new FormAdmin($db);
2543
2544
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
2545
2546
        llxHeader('', $langs->trans('DictionaryAccountancyCategory'), $help_url);
2547
2548
        $titre = $langs->trans($tablib[$id]);
2549
        $linkback = '';
2550
        $titlepicto = 'setup';
2551
2552
        print load_fiche_titre($titre, $linkback, $titlepicto);
2553
2554
        print '<span class="opacitymedium">' . $langs->trans("AccountingAccountGroupsDesc", $langs->transnoentitiesnoconv("ByPersonalizedAccountGroups")) . '</span><br><br>';
2555
2556
// Confirmation of the deletion of the line
2557
        if ($action == 'delete') {
2558
            print $form->formconfirm($_SERVER['PHP_SELF'] . '?' . ($page ? 'page=' . $page . '&' : '') . 'sortfield=' . $sortfield . '&sortorder=' . $sortorder . '&rowid=' . $rowid . '&code=' . $code . '&id=' . $id . ($search_country_id > 0 ? '&search_country_id=' . $search_country_id : ''), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1);
2559
        }
2560
2561
// Complete search query with sorting criteria
2562
        $sql = $tabsql[$id];
2563
2564
        if ($search_country_id > 0) {
2565
            if (preg_match('/ WHERE /', $sql)) {
2566
                $sql .= " AND ";
2567
            } else {
2568
                $sql .= " WHERE ";
2569
            }
2570
            $sql .= " (a.fk_country = " . ((int) $search_country_id) . " OR a.fk_country = 0)";
2571
        }
2572
2573
// If sort order is "country", we use country_code instead
2574
        if ($sortfield == 'country') {
2575
            $sortfield = 'country_code';
2576
        }
2577
        if (empty($sortfield)) {
2578
            $sortfield = 'position';
2579
        }
2580
2581
        $sql .= $db->order($sortfield, $sortorder);
2582
        $sql .= $db->plimit($listlimit + 1, $offset);
2583
2584
2585
        $fieldlist = explode(',', $tabfield[$id]);
2586
2587
        $param = '&id=' . $id;
2588
        if ($search_country_id > 0) {
2589
            $param .= '&search_country_id=' . urlencode((string) ($search_country_id));
2590
        }
2591
        $paramwithsearch = $param;
2592
        if ($sortorder) {
2593
            $paramwithsearch .= '&sortorder=' . urlencode($sortorder);
2594
        }
2595
        if ($sortfield) {
2596
            $paramwithsearch .= '&sortfield=' . urlencode($sortfield);
2597
        }
2598
        if (GETPOST('from', 'alpha')) {
2599
            $paramwithsearch .= '&from=' . urlencode(GETPOST('from', 'alpha'));
2600
        }
2601
        if ($listlimit) {
2602
            $paramwithsearch .= '&listlimit=' . urlencode((string) (GETPOSTINT('listlimit')));
2603
        }
2604
        print '<form action="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '" method="POST">';
2605
        print '<input type="hidden" name="token" value="' . newToken() . '">';
2606
        print '<input type="hidden" name="from" value="' . dol_escape_htmltag(GETPOST('from', 'alpha')) . '">';
2607
        print '<input type="hidden" name="sortfield" value="' . dol_escape_htmltag($sortfield) . '">';
2608
        print '<input type="hidden" name="sortorder" value="' . dol_escape_htmltag($sortorder) . '">';
2609
2610
2611
        print '<div class="div-table-responsive-no-min">';
2612
        print '<table class="noborder centpercent">';
2613
2614
// Form to add a new line
2615
        if ($tabname[$id]) {
2616
            $fieldlist = explode(',', $tabfield[$id]);
2617
2618
            // Line for title
2619
            print '<tr class="liste_titre">';
2620
            // Action column
2621
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2622
                print '<td></td>';
2623
            }
2624
            foreach ($fieldlist as $field => $value) {
2625
                // Determine le nom du champ par rapport aux noms possibles
2626
                // dans les dictionnaires de donnees
2627
                $valuetoshow = ucfirst($fieldlist[$field]); // By default
2628
                $valuetoshow = $langs->trans($valuetoshow); // try to translate
2629
                $class = "left";
2630
                if ($fieldlist[$field] == 'type') {
2631
                    if ($tabname[$id] == MAIN_DB_PREFIX . "c_paiement") {
2632
                        $valuetoshow = $form->textwithtooltip($langs->trans("Type"), $langs->trans("TypePaymentDesc"), 2, 1, img_help(1, ''));
2633
                    } else {
2634
                        $valuetoshow = $langs->trans("Type");
2635
                    }
2636
                }
2637
                if ($fieldlist[$field] == 'code') {
2638
                    $valuetoshow = $langs->trans("Code");
2639
                    $class = 'width75';
2640
                }
2641
                if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') {
2642
                    $valuetoshow = $langs->trans("Label");
2643
                }
2644
                if ($fieldlist[$field] == 'libelle_facture') {
2645
                    $valuetoshow = $langs->trans("LabelOnDocuments");
2646
                }
2647
                if ($fieldlist[$field] == 'country') {
2648
                    $valuetoshow = $langs->trans("Country");
2649
                }
2650
                if ($fieldlist[$field] == 'accountancy_code') {
2651
                    $valuetoshow = $langs->trans("AccountancyCode");
2652
                }
2653
                if ($fieldlist[$field] == 'accountancy_code_sell') {
2654
                    $valuetoshow = $langs->trans("AccountancyCodeSell");
2655
                }
2656
                if ($fieldlist[$field] == 'accountancy_code_buy') {
2657
                    $valuetoshow = $langs->trans("AccountancyCodeBuy");
2658
                }
2659
                if ($fieldlist[$field] == 'pcg_version' || $fieldlist[$field] == 'fk_pcg_version') {
2660
                    $valuetoshow = $langs->trans("Pcg_version");
2661
                }
2662
                if ($fieldlist[$field] == 'range_account') {
2663
                    $valuetoshow = $langs->trans("Comment");
2664
                    $class = 'width75';
2665
                }
2666
                if ($fieldlist[$field] == 'category_type') {
2667
                    $valuetoshow = $langs->trans("Calculated");
2668
                }
2669
2670
                if ($valuetoshow != '') {
2671
                    print '<td class="' . $class . '">';
2672
                    if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) {
2673
                        print '<a href="' . $tabhelp[$id][$value] . '">' . $valuetoshow . ' ' . img_help(1, $valuetoshow) . '</a>';
2674
                    } elseif (!empty($tabhelp[$id][$value])) {
2675
                        print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]);
2676
                    } else {
2677
                        print $valuetoshow;
2678
                    }
2679
                    print '</td>';
2680
                }
2681
            }
2682
2683
            print '<td>';
2684
            print '<input type="hidden" name="id" value="' . $id . '">';
2685
            print '</td>';
2686
            print '<td></td>';
2687
            // Action column
2688
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2689
                print '<td></td>';
2690
            }
2691
            print '</tr>';
2692
2693
            // Line to enter new values
2694
            print '<tr class="oddeven nodrag nodrop nohover">';
2695
2696
            // Action column
2697
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2698
                print '<td></td>';
2699
            }
2700
2701
            $obj = new stdClass();
2702
            // If data was already input, we define them in obj to populate input fields.
2703
            if (GETPOST('actionadd', 'alpha')) {
2704
                foreach ($fieldlist as $key => $val) {
2705
                    if (GETPOST($val) != '') {
2706
                        $obj->$val = GETPOST($val);
2707
                    }
2708
                }
2709
            }
2710
2711
            $tmpaction = 'create';
2712
            $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
2713
            $reshook = $hookmanager->executeHooks('createDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
2714
            $error = $hookmanager->error;
2715
            $errors = $hookmanager->errors;
2716
2717
            if (empty($reshook)) {
2718
                fieldListAccountingCategories($fieldlist, $obj, $tabname[$id], 'add');
2719
            }
2720
2721
            print '<td colspan="2" class="right">';
2722
            print '<input type="submit" class="button button-add" name="actionadd" value="' . $langs->trans("Add") . '">';
2723
            print '</td>';
2724
2725
            // Action column
2726
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2727
                print '<td></td>';
2728
            }
2729
2730
            print "</tr>";
2731
2732
            $colspan = count($fieldlist) + 3;
2733
            if ($id == 32) {
2734
                $colspan++;
2735
            }
2736
        }
2737
2738
        print '</table>';
2739
        print '</div>';
2740
2741
        print '<div class="div-table-responsive">';
2742
        print '<table class="noborder centpercent">';
2743
2744
// List of available record in database
2745
        dol_syslog("htdocs/accountancy/admin/categories_list.php", LOG_DEBUG);
2746
2747
        $resql = $db->query($sql);
2748
        if ($resql) {
2749
            $num = $db->num_rows($resql);
2750
            $i = 0;
2751
2752
            // There is several pages
2753
            if ($num > $listlimit) {
2754
                print '<tr class="none"><td class="right" colspan="' . (2 + count($fieldlist)) . '">';
2755
                print_fleche_navigation($page, $_SERVER['PHP_SELF'], $paramwithsearch, ($num > $listlimit), '<li class="pagination"><span>' . $langs->trans("Page") . ' ' . ($page + 1) . '</span></li>');
2756
                print '</td></tr>';
2757
            }
2758
2759
            $filterfound = 0;
2760
            foreach ($fieldlist as $field => $value) {
2761
                $showfield = 1; // By default
2762
                if ($fieldlist[$field] == 'region_id' || $fieldlist[$field] == 'country_id') {
2763
                    $showfield = 0;
2764
                }
2765
                if ($showfield) {
2766
                    if ($value == 'country') {
2767
                        $filterfound++;
2768
                    }
2769
                }
2770
            }
2771
2772
            // Title line with search boxes
2773
            print '<tr class="liste_titre liste_titre_add liste_titre_filter">';
2774
2775
            // Action column
2776
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2777
                print '<td class="liste_titre center">';
2778
                if ($filterfound) {
2779
                    $searchpicto = $form->showFilterAndCheckAddButtons(0);
2780
                    print $searchpicto;
2781
                }
2782
                print '</td>';
2783
            }
2784
2785
            $filterfound = 0;
2786
            foreach ($fieldlist as $field => $value) {
2787
                $showfield = 1; // By default
2788
2789
                if ($fieldlist[$field] == 'region_id' || $fieldlist[$field] == 'country_id') {
2790
                    $showfield = 0;
2791
                }
2792
2793
                if ($showfield) {
2794
                    if ($value == 'country') {
2795
                        print '<td class="liste_titre">';
2796
                        print $form->select_country($search_country_id, 'search_country_id', '', 28, 'maxwidth150 maxwidthonsmartphone');
2797
                        print '</td>';
2798
                        $filterfound++;
2799
                    } else {
2800
                        print '<td class="liste_titre"></td>';
2801
                    }
2802
                }
2803
            }
2804
            print '<td class="liste_titre"></td>';
2805
            print '<td class="liste_titre"></td>';
2806
            // Action column
2807
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2808
                print '<td class="liste_titre center">';
2809
                if ($filterfound) {
2810
                    $searchpicto = $form->showFilterAndCheckAddButtons(0);
2811
                    print $searchpicto;
2812
                }
2813
                print '</td>';
2814
            }
2815
            print '</tr>';
2816
2817
            // Title of lines
2818
            print '<tr class="liste_titre">';
2819
            // Action column
2820
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2821
                print getTitleFieldOfList('');
2822
            }
2823
            foreach ($fieldlist as $field => $value) {
2824
                // Determines the name of the field in relation to the possible names
2825
                // in data dictionaries
2826
                $showfield = 1; // By default
2827
                $class = "left";
2828
                $sortable = 1;
2829
                $valuetoshow = '';
2830
2831
                $valuetoshow = ucfirst($fieldlist[$field]); // By default
2832
                $valuetoshow = $langs->trans($valuetoshow); // try to translate
2833
                if ($fieldlist[$field] == 'source') {
2834
                    $valuetoshow = $langs->trans("Contact");
2835
                }
2836
                if ($fieldlist[$field] == 'price') {
2837
                    $valuetoshow = $langs->trans("PriceUHT");
2838
                }
2839
                if ($fieldlist[$field] == 'taux') {
2840
                    if ($tabname[$id] != MAIN_DB_PREFIX . "c_revenuestamp") {
2841
                        $valuetoshow = $langs->trans("Rate");
2842
                    } else {
2843
                        $valuetoshow = $langs->trans("Amount");
2844
                    }
2845
                    $class = 'center';
2846
                }
2847
                if ($fieldlist[$field] == 'type') {
2848
                    $valuetoshow = $langs->trans("Type");
2849
                }
2850
                if ($fieldlist[$field] == 'code') {
2851
                    $valuetoshow = $langs->trans("Code");
2852
                }
2853
                if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') {
2854
                    $valuetoshow = $langs->trans("Label");
2855
                }
2856
                if ($fieldlist[$field] == 'country') {
2857
                    $valuetoshow = $langs->trans("Country");
2858
                }
2859
                if ($fieldlist[$field] == 'region_id' || $fieldlist[$field] == 'country_id') {
2860
                    $showfield = 0;
2861
                }
2862
                if ($fieldlist[$field] == 'accountancy_code') {
2863
                    $valuetoshow = $langs->trans("AccountancyCode");
2864
                }
2865
                if ($fieldlist[$field] == 'accountancy_code_sell') {
2866
                    $valuetoshow = $langs->trans("AccountancyCodeSell");
2867
                    $sortable = 0;
2868
                }
2869
                if ($fieldlist[$field] == 'accountancy_code_buy') {
2870
                    $valuetoshow = $langs->trans("AccountancyCodeBuy");
2871
                    $sortable = 0;
2872
                }
2873
                if ($fieldlist[$field] == 'fk_pcg_version') {
2874
                    $valuetoshow = $langs->trans("Pcg_version");
2875
                }
2876
                if ($fieldlist[$field] == 'account_parent') {
2877
                    $valuetoshow = $langs->trans("Accountsparent");
2878
                }
2879
                if ($fieldlist[$field] == 'pcg_type') {
2880
                    $valuetoshow = $langs->trans("Pcg_type");
2881
                }
2882
                if ($fieldlist[$field] == 'type_template') {
2883
                    $valuetoshow = $langs->trans("TypeOfTemplate");
2884
                }
2885
                if ($fieldlist[$field] == 'range_account') {
2886
                    $valuetoshow = $langs->trans("Comment");
2887
                }
2888
                if ($fieldlist[$field] == 'category_type') {
2889
                    $valuetoshow = $langs->trans("Calculated");
2890
                }
2891
                // Affiche nom du champ
2892
                if ($showfield) {
2893
                    print getTitleFieldOfList($valuetoshow, 0, $_SERVER['PHP_SELF'], ($sortable ? $fieldlist[$field] : ''), ($page ? 'page=' . $page . '&' : ''), $param, "", $sortfield, $sortorder, $class . ' ');
2894
                }
2895
            }
2896
            print getTitleFieldOfList($langs->trans("ListOfAccounts"), 0, $_SERVER['PHP_SELF'], "", ($page ? 'page=' . $page . '&' : ''), $param, '', $sortfield, $sortorder, '');
2897
            print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER['PHP_SELF'], "active", ($page ? 'page=' . $page . '&' : ''), $param, '', $sortfield, $sortorder, 'center ');
2898
            // Action column
2899
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2900
                print getTitleFieldOfList('');
2901
            }
2902
            print '</tr>';
2903
2904
2905
            if ($num) {
2906
                $imaxinloop = ($listlimit ? min($num, $listlimit) : $num);
2907
2908
                // Lines with values
2909
                while ($i < $imaxinloop) {
2910
                    $obj = $db->fetch_object($resql);
2911
2912
                    //print_r($obj);
2913
                    print '<tr class="oddeven" id="rowid-' . $obj->rowid . '">';
2914
                    if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) {
2915
                        $tmpaction = 'edit';
2916
                        $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
2917
                        $reshook = $hookmanager->executeHooks('editDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
2918
                        $error = $hookmanager->error;
2919
                        $errors = $hookmanager->errors;
2920
2921
                        // Actions
2922
                        if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2923
                            print '<td></td>';
2924
                        }
2925
2926
                        // Show fields
2927
                        if (empty($reshook)) {
2928
                            fieldListAccountingCategories($fieldlist, $obj, $tabname[$id], 'edit');
2929
                        }
2930
2931
                        print '<td></td>';
2932
                        print '<td class="center">';
2933
                        print '<div name="' . (!empty($obj->rowid) ? $obj->rowid : $obj->code) . '"></div>';
2934
                        print '<input type="hidden" name="page" value="' . $page . '">';
2935
                        print '<input type="hidden" name="rowid" value="' . $rowid . '">';
2936
                        print '<input type="submit" class="button button-edit smallpaddingimp" name="actionmodify" value="' . $langs->trans("Modify") . '">';
2937
                        print '<input type="submit" class="button button-cancel smallpaddingimp" name="actioncancel" value="' . $langs->trans("Cancel") . '">';
2938
                        print '</td>';
2939
                        // Actions
2940
                        if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2941
                            print '<td></td>';
2942
                        }
2943
                    } else {
2944
                        // Can an entry be erased or disabled ?
2945
                        $iserasable = 1;
2946
                        $canbedisabled = 1;
2947
                        $canbemodified = 1; // true by default
2948
                        if (isset($obj->code)) {
2949
                            if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i', $obj->code))) {
2950
                                $iserasable = 0;
2951
                                $canbedisabled = 0;
2952
                            }
2953
                        }
2954
                        $url = $_SERVER['PHP_SELF'] . '?' . ($page ? 'page=' . $page . '&' : '') . 'sortfield=' . $sortfield . '&sortorder=' . $sortorder . '&rowid=' . (!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')) . '&code=' . (!empty($obj->code) ? urlencode($obj->code) : '');
2955
                        if ($param) {
2956
                            $url .= '&' . $param;
2957
                        }
2958
                        $url .= '&';
2959
2960
                        $canbemodified = $iserasable;
2961
2962
                        $tmpaction = 'view';
2963
                        $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
2964
                        $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
2965
2966
                        $error = $hookmanager->error;
2967
                        $errors = $hookmanager->errors;
2968
2969
                        // Actions
2970
                        if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
2971
                            print '<td class="center">';
2972
                            if ($canbemodified) {
2973
                                print '<a class="reposition editfielda marginleftonly marginrightonly" href="' . $url . 'action=edit&token=' . newToken() . '">' . img_edit() . '</a>';
2974
                            }
2975
                            if ($iserasable) {
2976
                                if ($user->admin) {
2977
                                    print '<a class="marginleftonly marginrightonly" href="' . $url . 'action=delete&token=' . newToken() . '">' . img_delete() . '</a>';
2978
                                }
2979
                            }
2980
                            print '</td>';
2981
                        }
2982
2983
                        if (empty($reshook)) {
2984
                            foreach ($fieldlist as $field => $value) {
2985
                                $showfield = 1;
2986
                                $title = '';
2987
                                $class = 'tddict';
2988
2989
                                $tmpvar = $fieldlist[$field];
2990
                                $valuetoshow = $obj->$tmpvar;
2991
                                if ($value == 'category_type') {
2992
                                    $valuetoshow = yn($valuetoshow);
2993
                                } elseif ($valuetoshow == 'all') {
2994
                                    $valuetoshow = $langs->trans('All');
2995
                                } elseif ($fieldlist[$field] == 'country') {
2996
                                    if (empty($obj->country_code)) {
2997
                                        $valuetoshow = '-';
2998
                                    } else {
2999
                                        $key = $langs->trans("Country" . strtoupper($obj->country_code));
3000
                                        $valuetoshow = ($key != "Country" . strtoupper($obj->country_code) ? $obj->country_code . " - " . $key : $obj->country);
3001
                                    }
3002
                                } elseif (in_array($fieldlist[$field], ['label', 'formula'])) {
3003
                                    $class = "tdoverflowmax250";
3004
                                    $title = $valuetoshow;
3005
                                } elseif (in_array($fieldlist[$field], ['range_account'])) {
3006
                                    $class = "tdoverflowmax250 small";
3007
                                    $title = $valuetoshow;
3008
                                } elseif ($fieldlist[$field] == 'region_id' || $fieldlist[$field] == 'country_id') {
3009
                                    $showfield = 0;
3010
                                }
3011
3012
                                // Show value for field
3013
                                if ($showfield) {
3014
                                    print '<!-- ' . $fieldlist[$field] . ' --><td class="' . $class . '"' . ($title ? ' title="' . dol_escape_htmltag($title) . '"' : '') . '>' . dol_escape_htmltag($valuetoshow) . '</td>';
3015
                                }
3016
                            }
3017
                        }
3018
3019
                        // Link to setup the group
3020
                        print '<td>';
3021
                        if (empty($obj->formula)) {
3022
                            // Count number of accounts into group
3023
                            $nbofaccountintogroup = 0;
3024
                            $listofaccountintogroup = $accountingcategory->getCptsCat($obj->rowid);
3025
                            $nbofaccountintogroup = count($listofaccountintogroup);
3026
3027
                            print '<a href="' . DOL_URL_ROOT . '/accountancy/admin/categories.php?action=display&save_lastsearch_values=1&account_category=' . $obj->rowid . '">';
3028
                            print $langs->trans("NAccounts", $nbofaccountintogroup);
3029
                            print '</a>';
3030
                        } else {
3031
                            print '<span class="opacitymedium">' . $langs->trans("Formula") . '</span>';
3032
                        }
3033
                        print '</td>';
3034
3035
                        // Active
3036
                        print '<td class="center" class="nowrap">';
3037
                        if ($canbedisabled) {
3038
                            print '<a href="' . $url . 'action=' . $acts[$obj->active] . '">' . $actl[$obj->active] . '</a>';
3039
                        } else {
3040
                            print $langs->trans("AlwaysActive");
3041
                        }
3042
                        print "</td>";
3043
3044
                        // Actions
3045
                        if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
3046
                            print '<td class="center">';
3047
                            if ($canbemodified) {
3048
                                print '<a class="reposition editfielda paddingleft marginleftonly marginrightonly paddingright" href="' . $url . 'action=edit&token=' . newToken() . '">' . img_edit() . '</a>';
3049
                            }
3050
                            if ($iserasable) {
3051
                                if ($user->admin) {
3052
                                    print '<a class="paddingleft marginleftonly marginrightonly paddingright" href="' . $url . 'action=delete&token=' . newToken() . '">' . img_delete() . '</a>';
3053
                                }
3054
                            }
3055
                            print '</td>';
3056
                        }
3057
                    }
3058
                    print "</tr>\n";
3059
                    $i++;
3060
                }
3061
            } else {
3062
                $colspan = 10;
3063
                print '<tr><td colspan="' . $colspan . '"><span class="opacitymedium">' . $langs->trans("None") . '</td></tr>';
3064
            }
3065
        } else {
3066
            dol_print_error($db);
3067
        }
3068
3069
        print '</table>';
3070
        print '</div>';
3071
3072
        print '</form>';
3073
3074
        print '<br>';
3075
3076
// End of page
3077
        llxFooter();
3078
        $db->close();
3079
3080
3081
        /**
3082
         *  Show fields in insert/edit mode
3083
         *
3084
         * @param array  $fieldlist Array of fields
3085
         * @param Object $obj       If we show a particular record, obj is filled with record fields
3086
         * @param string $tabname   Name of SQL table
3087
         * @param string $context   'add'=Output field for the "add form", 'edit'=Output field for the "edit form", 'hide'=Output field for the "add form" but we don't want it to be rendered
3088
         *
3089
         * @return     void
3090
         */
3091
        function fieldListAccountingCategories($fieldlist, $obj = null, $tabname = '', $context = '')
3092
        {
3093
            global $conf, $langs, $db;
3094
            global $form, $mysoc;
3095
3096
            $formadmin = new FormAdmin($db);
3097
            $formcompany = new FormCompany($db);
3098
            if (isModEnabled('accounting')) {
3099
                $formaccounting = new FormAccounting($db);
3100
            }
3101
3102
            foreach ($fieldlist as $field => $value) {
3103
                if ($fieldlist[$field] == 'country') {
3104
                    print '<td>';
3105
                    $fieldname = 'country';
3106
                    if ($context == 'add') {
3107
                        $fieldname = 'country_id';
3108
                        $preselectcountrycode = GETPOSTISSET('country_id') ? GETPOSTINT('country_id') : $mysoc->country_code;
3109
                        print $form->select_country($preselectcountrycode, $fieldname, '', 28, 'maxwidth150 maxwidthonsmartphone');
3110
                    } else {
3111
                        $preselectcountrycode = (empty($obj->country_code) ? (empty($obj->country) ? $mysoc->country_code : $obj->country) : $obj->country_code);
3112
                        print $form->select_country($preselectcountrycode, $fieldname, '', 28, 'maxwidth150 maxwidthonsmartphone');
3113
                    }
3114
                    print '</td>';
3115
                } elseif ($fieldlist[$field] == 'country_id') {
3116
                    if (!in_array('country', $fieldlist)) { // If there is already a field country, we don't show country_id (avoid duplicate)
3117
                        $country_id = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0);
3118
                        print '<td>';
3119
                        print '<input type="hidden" name="' . $fieldlist[$field] . '" value="' . $country_id . '">';
3120
                        print '</td>';
3121
                    }
3122
                } elseif ($fieldlist[$field] == 'category_type') {
3123
                    print '<td>';
3124
                    print $form->selectyesno($fieldlist[$field], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''), 1);
3125
                    print '</td>';
3126
                } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
3127
                    print '<td><input type="text" class="flat minwidth100" value="' . (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '"></td>';
3128
                } else {
3129
                    print '<td>';
3130
                    $class = '';
3131
                    if (in_array($fieldlist[$field], ['code', 'formula'])) {
3132
                        $class = 'maxwidth75';
3133
                    }
3134
                    if (in_array($fieldlist[$field], ['label', 'range_account'])) {
3135
                        $class = 'maxwidth150';
3136
                    }
3137
                    if ($fieldlist[$field] == 'position') {
3138
                        $class = 'maxwidth50';
3139
                    }
3140
                    print '<input type="text" class="flat' . ($class ? ' ' . $class : '') . '" value="' . (isset($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '">';
3141
                    print '</td>';
3142
                }
3143
            }
3144
        }
3145
    }
3146
3147
    /**
3148
     * \file        htdocs/accountancy/admin/closure.php
3149
     * \ingroup     Accountancy (Double entries)
3150
     * \brief       Setup page to configure accounting expert module
3151
     */
3152
    public function closure()
3153
    {
3154
        global $conf;
3155
        global $db;
3156
        global $user;
3157
        global $hookmanager;
3158
        global $user;
3159
        global $menumanager;
3160
        global $langs;
3161
3162
// Load translation files required by the page
3163
        $langs->loadLangs(["compta", "admin", "accountancy"]);
3164
3165
// Security check
3166
        if (!$user->hasRight('accounting', 'chartofaccount')) {
3167
            accessforbidden();
3168
        }
3169
3170
        $action = GETPOST('action', 'aZ09');
3171
3172
3173
        $list_account_main = [
3174
            'ACCOUNTING_RESULT_PROFIT',
3175
            'ACCOUNTING_RESULT_LOSS',
3176
        ];
3177
3178
        /*
3179
         * Actions
3180
         */
3181
3182
        if ($action == 'update') {
3183
            $error = 0;
3184
3185
            $defaultjournal = GETPOST('ACCOUNTING_CLOSURE_DEFAULT_JOURNAL', 'alpha');
3186
3187
            if (!empty($defaultjournal)) {
3188
                if (!dolibarr_set_const($db, 'ACCOUNTING_CLOSURE_DEFAULT_JOURNAL', $defaultjournal, 'chaine', 0, '', $conf->entity)) {
3189
                    $error++;
3190
                }
3191
            } else {
3192
                $error++;
3193
            }
3194
3195
            $accountinggroupsusedforbalancesheetaccount = GETPOST('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT', 'alphanohtml');
3196
            if (!empty($accountinggroupsusedforbalancesheetaccount)) {
3197
                if (!dolibarr_set_const($db, 'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT', $accountinggroupsusedforbalancesheetaccount, 'chaine', 0, '', $conf->entity)) {
3198
                    $error++;
3199
                }
3200
            } else {
3201
                $error++;
3202
            }
3203
3204
            $accountinggroupsusedforincomestatement = GETPOST('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT', 'alpha');
3205
            if (!empty($accountinggroupsusedforincomestatement)) {
3206
                if (!dolibarr_set_const($db, 'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT', $accountinggroupsusedforincomestatement, 'chaine', 0, '', $conf->entity)) {
3207
                    $error++;
3208
                }
3209
            } else {
3210
                $error++;
3211
            }
3212
3213
            foreach ($list_account_main as $constname) {
3214
                $constvalue = GETPOST($constname, 'alpha');
3215
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
3216
                    $error++;
3217
                }
3218
            }
3219
3220
            if (!$error) {
3221
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
3222
            } else {
3223
                setEventMessages($langs->trans("Error"), null, 'errors');
3224
            }
3225
        }
3226
3227
3228
        /*
3229
         * View
3230
         */
3231
3232
        $form = new Form($db);
3233
        $formaccounting = new FormAccounting($db);
3234
3235
        $title = $langs->trans('Closure');
3236
3237
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
3238
3239
        llxHeader('', $title, $help_url);
3240
3241
        $linkback = '';
3242
        print load_fiche_titre($langs->trans('MenuClosureAccounts'), $linkback, 'title_accountancy');
3243
3244
        print '<span class="opacitymedium">' . $langs->trans("DefaultClosureDesc") . '</span><br>';
3245
        print '<br>';
3246
3247
        print '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">';
3248
        print '<input type="hidden" name="token" value="' . newToken() . '">';
3249
        print '<input type="hidden" name="action" value="update">';
3250
3251
// Define main accounts for closure
3252
        print '<table class="noborder centpercent">';
3253
3254
        foreach ($list_account_main as $key) {
3255
            print '<tr class="oddeven value">';
3256
            // Param
3257
            $label = $langs->trans($key);
3258
            $keydesc = $key . '_Desc';
3259
3260
            $htmltext = $langs->trans($keydesc);
3261
            print '<td class="fieldrequired" width="50%">';
3262
            print $form->textwithpicto($label, $htmltext);
3263
            print '</td>';
3264
            // Value
3265
            print '<td>'; // Do not force class=right, or it align also the content of the select box
3266
            print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1);
3267
            print '</td>';
3268
            print '</tr>';
3269
        }
3270
3271
// Journal
3272
        print '<tr class="oddeven">';
3273
        print '<td class="fieldrequired">' . $langs->trans("ACCOUNTING_CLOSURE_DEFAULT_JOURNAL") . '</td>';
3274
        print '<td>';
3275
        $defaultjournal = getDolGlobalString('ACCOUNTING_CLOSURE_DEFAULT_JOURNAL');
3276
        print $formaccounting->select_journal($defaultjournal, "ACCOUNTING_CLOSURE_DEFAULT_JOURNAL", 9, 1, 0, 0);
3277
        print '</td></tr>';
3278
3279
// Accounting groups used for the balance sheet account
3280
        print '<tr class="oddeven">';
3281
        print '<td class="fieldrequired">' . $langs->trans("ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT") . '</td>';
3282
        print '<td>';
3283
        print '<input type="text" size="100" id="ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT" name="ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT" value="' . dol_escape_htmltag(getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT')) . '">';
3284
        print '</td></tr>';
3285
3286
// Accounting groups used for the income statement
3287
        print '<tr class="oddeven">';
3288
        print '<td class="fieldrequired">' . $langs->trans("ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT") . '</td>';
3289
        print '<td>';
3290
        print '<input type="text" size="100" id="ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT" name="ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT" value="' . dol_escape_htmltag(getDolGlobalString('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT')) . '">';
3291
        print '</td></tr>';
3292
3293
        print "</table>\n";
3294
3295
        print '<div class="center"><input type="submit" class="button button-edit" name="button" value="' . $langs->trans('Modify') . '"></div>';
3296
3297
        print '</form>';
3298
3299
// End of page
3300
        llxFooter();
3301
        $db->close();
3302
    }
3303
3304
    /**
3305
     * \file        htdocs/accountancy/admin/defaultaccounts.php
3306
     * \ingroup     Accountancy (Double entries)
3307
     * \brief       Setup page to configure accounting expert module
3308
     */
3309
    public function defaultaccounts()
3310
    {
3311
        global $conf;
3312
        global $db;
3313
        global $user;
3314
        global $hookmanager;
3315
        global $user;
3316
        global $menumanager;
3317
        global $langs;
3318
        global $mysoc;
3319
3320
// Load translation files required by the page
3321
        $langs->loadLangs(["compta", "bills", "admin", "accountancy", "salaries", "loan"]);
3322
3323
// Security check
3324
        if (!$user->hasRight('accounting', 'chartofaccount')) {
3325
            accessforbidden();
3326
        }
3327
3328
        $action = GETPOST('action', 'aZ09');
3329
3330
3331
        $list_account_main = [
3332
            'ACCOUNTING_ACCOUNT_CUSTOMER',
3333
            'ACCOUNTING_ACCOUNT_SUPPLIER',
3334
            'SALARIES_ACCOUNTING_ACCOUNT_PAYMENT',
3335
        ];
3336
3337
        $list_account = [];
3338
3339
        $list_account[] = '---Product---';
3340
        $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_ACCOUNT';
3341
        if ($mysoc->isInEEC()) {
3342
            $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT';
3343
        }
3344
        $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT';
3345
        $list_account[] = 'ACCOUNTING_PRODUCT_BUY_ACCOUNT';
3346
        if ($mysoc->isInEEC()) {
3347
            $list_account[] = 'ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT';
3348
        }
3349
        $list_account[] = 'ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT';
3350
3351
        $list_account[] = '---Service---';
3352
        $list_account[] = 'ACCOUNTING_SERVICE_SOLD_ACCOUNT';
3353
        if ($mysoc->isInEEC()) {
3354
            $list_account[] = 'ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT';
3355
        }
3356
        $list_account[] = 'ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT';
3357
        $list_account[] = 'ACCOUNTING_SERVICE_BUY_ACCOUNT';
3358
        if ($mysoc->isInEEC()) {
3359
            $list_account[] = 'ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT';
3360
        }
3361
        $list_account[] = 'ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT';
3362
3363
        $list_account[] = '---Others---';
3364
        $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT';
3365
        $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT';
3366
3367
        /*if ($mysoc->useRevenueStamp()) {
3368
            $list_account[] = 'ACCOUNTING_REVENUESTAMP_SOLD_ACCOUNT';
3369
            $list_account[] = 'ACCOUNTING_REVENUESTAMP_BUY_ACCOUNT';
3370
        }*/
3371
3372
        $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT';
3373
3374
        if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
3375
            $list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT';
3376
            $list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT';
3377
        }
3378
        if (isModEnabled('bank')) {
3379
            $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH';
3380
        }
3381
        if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY')) {
3382
            $list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY';
3383
        }
3384
        if (isModEnabled('don')) {
3385
            $list_account[] = 'DONATION_ACCOUNTINGACCOUNT';
3386
        }
3387
        if (isModEnabled('member')) {
3388
            $list_account[] = 'ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT';
3389
        }
3390
        if (isModEnabled('loan')) {
3391
            $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL';
3392
            $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INTEREST';
3393
            $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE';
3394
        }
3395
        $list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE';
3396
        if (isModEnabled('societe')) {
3397
            $list_account[] = '---Deposits---';
3398
        }
3399
3400
        /*
3401
         * Actions
3402
         */
3403
3404
        if ($action == 'update') {
3405
            $error = 0;
3406
            // Process $list_account_main
3407
            foreach ($list_account_main as $constname) {
3408
                $constvalue = GETPOST($constname, 'alpha');
3409
3410
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
3411
                    $error++;
3412
                }
3413
            }
3414
            // Process $list_account
3415
            foreach ($list_account as $constname) {
3416
                $reg = [];
3417
                if (preg_match('/---(.*)---/', $constname, $reg)) { // This is a separator
3418
                    continue;
3419
                }
3420
3421
                $constvalue = GETPOST($constname, 'alpha');
3422
3423
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
3424
                    $error++;
3425
                }
3426
            }
3427
3428
            $constname = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT';
3429
            $constvalue = GETPOSTINT($constname);
3430
            if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
3431
                $error++;
3432
            }
3433
3434
            $constname = 'ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT';
3435
            $constvalue = GETPOSTINT($constname);
3436
            if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
3437
                $error++;
3438
            }
3439
3440
3441
            if (!$error) {
3442
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
3443
            } else {
3444
                setEventMessages($langs->trans("Error"), null, 'errors');
3445
            }
3446
        }
3447
3448
        if ($action == 'setACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT') {
3449
            $setDisableAuxiliaryAccountOnCustomerDeposit = GETPOSTINT('value');
3450
            $res = dolibarr_set_const($db, "ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT", $setDisableAuxiliaryAccountOnCustomerDeposit, 'yesno', 0, '', $conf->entity);
3451
            if (!($res > 0)) {
3452
                $error++;
3453
            }
3454
3455
            if (!$error) {
3456
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
3457
            } else {
3458
                setEventMessages($langs->trans("Error"), null, 'mesgs');
3459
            }
3460
        }
3461
3462
        if ($action == 'setACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT') {
3463
            $setDisableAuxiliaryAccountOnSupplierDeposit = GETPOSTINT('value');
3464
            $res = dolibarr_set_const($db, "ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT", $setDisableAuxiliaryAccountOnSupplierDeposit, 'yesno', 0, '', $conf->entity);
3465
            if (!($res > 0)) {
3466
                $error++;
3467
            }
3468
3469
            if (!$error) {
3470
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
3471
            } else {
3472
                setEventMessages($langs->trans("Error"), null, 'mesgs');
3473
            }
3474
        }
3475
3476
3477
        /*
3478
         * View
3479
         */
3480
3481
        $form = new Form($db);
3482
        $formaccounting = new FormAccounting($db);
3483
3484
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
3485
3486
        llxHeader('', $langs->trans('MenuDefaultAccounts'), $help_url);
3487
3488
        $linkback = '';
3489
        print load_fiche_titre($langs->trans('MenuDefaultAccounts'), $linkback, 'title_accountancy');
3490
3491
        print '<span class="opacitymedium">' . $langs->trans("DefaultBindingDesc") . '</span><br>';
3492
        print '<br>';
3493
3494
        print '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">';
3495
        print '<input type="hidden" name="token" value="' . newToken() . '">';
3496
        print '<input type="hidden" name="action" value="update">';
3497
3498
3499
// Define main accounts for thirdparty
3500
3501
        print '<div class="div-table-responsive-no-min">';
3502
        print '<table class="noborder centpercent">';
3503
        print '<tr class="liste_titre"><td>' . $langs->trans("ThirdParties") . ' | ' . $langs->trans("Users") . '</td><td></td></tr>';
3504
3505
        foreach ($list_account_main as $key) {
3506
            print '<tr class="oddeven value">';
3507
            // Param
3508
            $label = $langs->trans($key);
3509
            $keydesc = $key . '_Desc';
3510
3511
            $htmltext = $langs->trans($keydesc);
3512
            print '<td class="fieldrequired">';
3513
            if ($key == 'ACCOUNTING_ACCOUNT_CUSTOMER') {
3514
                print img_picto('', 'company', 'class="pictofixedwidth"');
3515
            } elseif ($key == 'ACCOUNTING_ACCOUNT_SUPPLIER') {
3516
                print img_picto('', 'company', 'class="pictofixedwidth"');
3517
            } else {
3518
                print img_picto('', 'user', 'class="pictofixedwidth"');
3519
            }
3520
            print $form->textwithpicto($label, $htmltext);
3521
            print '</td>';
3522
            // Value
3523
            print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
3524
            $key_value = getDolGlobalString($key);
3525
            print $formaccounting->select_account($key_value, $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accountsmain');
3526
            print '</td>';
3527
            print '</tr>';
3528
        }
3529
        print "</table>\n";
3530
        print "</div>\n";
3531
3532
3533
        print '<div class="div-table-responsive-no-min">';
3534
        print '<table class="noborder centpercent">';
3535
3536
        foreach ($list_account as $key) {
3537
            $reg = [];
3538
            if (preg_match('/---(.*)---/', $key, $reg)) {
3539
                print '<tr class="liste_titre"><td>' . $langs->trans($reg[1]) . '</td><td></td></tr>';
3540
            } else {
3541
                print '<tr class="oddeven value">';
3542
                // Param
3543
                $label = $langs->trans($key);
3544
                print '<td>';
3545
                if (preg_match('/^ACCOUNTING_PRODUCT/', $key)) {
3546
                    print img_picto('', 'product', 'class="pictofixedwidth"');
3547
                } elseif (preg_match('/^ACCOUNTING_SERVICE/', $key)) {
3548
                    print img_picto('', 'service', 'class="pictofixedwidth"');
3549
                } elseif (preg_match('/^ACCOUNTING_VAT_PAY_ACCOUNT/', $key)) {
3550
                    print img_picto('', 'payment_vat', 'class="pictofixedwidth"');
3551
                } elseif (preg_match('/^ACCOUNTING_VAT/', $key)) {
3552
                    print img_picto('', 'vat', 'class="pictofixedwidth"');
3553
                } elseif (preg_match('/^ACCOUNTING_ACCOUNT_CUSTOMER/', $key)) {
3554
                    print img_picto('', 'bill', 'class="pictofixedwidth"');
3555
                } elseif (preg_match('/^LOAN_ACCOUNTING_ACCOUNT/', $key)) {
3556
                    print img_picto('', 'loan', 'class="pictofixedwidth"');
3557
                } elseif (preg_match('/^DONATION_ACCOUNTING/', $key)) {
3558
                    print img_picto('', 'donation', 'class="pictofixedwidth"');
3559
                } elseif (preg_match('/^ADHERENT_SUBSCRIPTION/', $key)) {
3560
                    print img_picto('', 'member', 'class="pictofixedwidth"');
3561
                } elseif (preg_match('/^ACCOUNTING_ACCOUNT_TRANSFER/', $key)) {
3562
                    print img_picto('', 'bank_account', 'class="pictofixedwidth"');
3563
                } elseif (preg_match('/^ACCOUNTING_ACCOUNT_SUSPENSE/', $key)) {
3564
                    print img_picto('', 'question', 'class="pictofixedwidth"');
3565
                }
3566
                // Note: account for revenue stamp are store into dictionary of revenue stamp. There is no default value.
3567
                print $label;
3568
                print '</td>';
3569
                // Value
3570
                print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
3571
                print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts');
3572
                print '</td>';
3573
                print '</tr>';
3574
            }
3575
        }
3576
3577
3578
// Customer deposit account
3579
        print '<tr class="oddeven value">';
3580
// Param
3581
        print '<td>';
3582
        print img_picto('', 'bill', 'class="pictofixedwidth"') . $langs->trans('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT');
3583
        print '</td>';
3584
// Value
3585
        print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
3586
        print $formaccounting->select_account(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT'), 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT', 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts');
3587
        print '</td>';
3588
        print '</tr>';
3589
3590
        if (isModEnabled('societe') && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') != '-1') {
3591
            print '<tr class="oddeven">';
3592
            print '<td>' . img_picto('', 'bill', 'class="pictofixedwidth"') . $langs->trans("UseAuxiliaryAccountOnCustomerDeposit") . '</td>';
3593
            if (getDolGlobalInt('ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT')) {
3594
                print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT&value=0">';
3595
                print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning');
3596
                print '</a></td>';
3597
            } else {
3598
                print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT&value=1">';
3599
                print img_picto($langs->trans("Disabled"), 'switch_off');
3600
                print '</a></td>';
3601
            }
3602
            print '</tr>';
3603
        }
3604
3605
// Supplier deposit account
3606
        print '<tr class="oddeven value">';
3607
// Param
3608
        print '<td>';
3609
        print img_picto('', 'supplier_invoice', 'class="pictofixedwidth"') . $langs->trans('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT');
3610
        print '</td>';
3611
// Value
3612
        print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
3613
        print $formaccounting->select_account(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT'), 'ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT', 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts');
3614
        print '</td>';
3615
        print '</tr>';
3616
3617
        if (isModEnabled('societe') && getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT') && getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT') != '-1') {
3618
            print '<tr class="oddeven">';
3619
            print '<td>' . img_picto('', 'supplier_invoice', 'class="pictofixedwidth"') . $langs->trans("UseAuxiliaryAccountOnSupplierDeposit") . '</td>';
3620
            if (getDolGlobalInt('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
3621
                print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT&value=0">';
3622
                print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning');
3623
                print '</a></td>';
3624
            } else {
3625
                print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT&value=1">';
3626
                print img_picto($langs->trans("Disabled"), 'switch_off');
3627
                print '</a></td>';
3628
            }
3629
            print '</tr>';
3630
        }
3631
3632
        print "</table>\n";
3633
        print "</div>\n";
3634
3635
        print '<div class="center"><input type="submit" class="button button-edit" name="button" value="' . $langs->trans('Save') . '"></div>';
3636
3637
        print '</form>';
3638
3639
// End of page
3640
        llxFooter();
3641
        $db->close();
3642
    }
3643
3644
    /**
3645
     * \file        htdocs/accountancy/admin/export.php
3646
     * \ingroup     Accountancy (Double entries)
3647
     * \brief       Setup page to configure accounting export module
3648
     */
3649
    public function export()
3650
    {
3651
        global $conf;
3652
        global $db;
3653
        global $user;
3654
        global $hookmanager;
3655
        global $user;
3656
        global $menumanager;
3657
        global $langs;
3658
3659
// Load translation files required by the page
3660
        $langs->loadLangs(["compta", "bills", "admin", "accountancy"]);
3661
3662
// Security access
3663
        if (!$user->hasRight('accounting', 'chartofaccount')) {
3664
            accessforbidden();
3665
        }
3666
3667
        $action = GETPOST('action', 'aZ09');
3668
3669
// Parameters ACCOUNTING_EXPORT_*
3670
        $main_option = [
3671
            'ACCOUNTING_EXPORT_PREFIX_SPEC',
3672
        ];
3673
3674
        $accountancyexport = new AccountancyExport($db);
3675
        $configuration = $accountancyexport->getTypeConfig();
3676
3677
        $listparam = $configuration['param'];
3678
3679
        $listformat = $configuration['format'];
3680
3681
        $listcr = $configuration['cr'];
3682
3683
3684
        $model_option = [
3685
            '1' => [
3686
                'label' => 'ACCOUNTING_EXPORT_FORMAT',
3687
                'param' => $listformat,
3688
            ],
3689
            '2' => [
3690
                'label' => 'ACCOUNTING_EXPORT_SEPARATORCSV',
3691
                'param' => '',
3692
            ],
3693
            '3' => [
3694
                'label' => 'ACCOUNTING_EXPORT_ENDLINE',
3695
                'param' => $listcr,
3696
            ],
3697
            '4' => [
3698
                'label' => 'ACCOUNTING_EXPORT_DATE',
3699
                'param' => '',
3700
            ],
3701
        ];
3702
3703
3704
        /*
3705
         * Actions
3706
         */
3707
3708
        if ($action == 'update') {
3709
            $error = 0;
3710
3711
            $modelcsv = GETPOSTINT('ACCOUNTING_EXPORT_MODELCSV');
3712
3713
            if (!empty($modelcsv)) {
3714
                if (!dolibarr_set_const($db, 'ACCOUNTING_EXPORT_MODELCSV', $modelcsv, 'chaine', 0, '', $conf->entity)) {
3715
                    $error++;
3716
                }
3717
                //if ($modelcsv==AccountancyExport::$EXPORT_TYPE_QUADRATUS || $modelcsv==AccountancyExport::$EXPORT_TYPE_CIEL) {
3718
                //  dolibarr_set_const($db, 'ACCOUNTING_EXPORT_FORMAT', 'txt', 'chaine', 0, '', $conf->entity);
3719
                //}
3720
            } else {
3721
                $error++;
3722
            }
3723
3724
            foreach ($main_option as $constname) {
3725
                $constvalue = GETPOST($constname, 'alpha');
3726
3727
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
3728
                    $error++;
3729
                }
3730
            }
3731
3732
            foreach ($listparam[$modelcsv] as $key => $value) {
3733
                $constante = $key;
3734
3735
                if (strpos($constante, 'ACCOUNTING') !== false) {
3736
                    $constvalue = GETPOST($key, 'alpha');
3737
                    if (!dolibarr_set_const($db, $constante, $constvalue, 'chaine', 0, '', $conf->entity)) {
3738
                        $error++;
3739
                    }
3740
                }
3741
            }
3742
3743
            if (!$error) {
3744
                // reload
3745
                $configuration = $accountancyexport->getTypeConfig();
3746
                $listparam = $configuration['param'];
3747
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
3748
            } else {
3749
                setEventMessages($langs->trans("Error"), null, 'errors');
3750
            }
3751
        }
3752
3753
3754
        /*
3755
         * View
3756
         */
3757
3758
        $form = new Form($db);
3759
3760
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
3761
        $title = $langs->trans('ExportOptions');
3762
        llxHeader('', $title, $help_url);
3763
3764
        $linkback = '';
3765
// $linkback = '<a href="' . DOL_URL_ROOT . '/admin/modules.php?restore_lastsearch_values=1">' . $langs->trans("BackToModuleList") . '</a>';
3766
        print load_fiche_titre($langs->trans('ExportOptions'), $linkback, 'accountancy');
3767
3768
3769
        print "\n" . '<script type="text/javascript">' . "\n";
3770
        print 'jQuery(document).ready(function () {' . "\n";
3771
        print '    function initfields()' . "\n";
3772
        print '    {' . "\n";
3773
        foreach ($listparam as $key => $param) {
3774
            print '        if (jQuery("#ACCOUNTING_EXPORT_MODELCSV").val()=="' . $key . '")' . "\n";
3775
            print '        {' . "\n";
3776
            print '            //console.log("' . $param['label'] . '");' . "\n";
3777
            if (empty($param['ACCOUNTING_EXPORT_FORMAT'])) {
3778
                print '            jQuery("#ACCOUNTING_EXPORT_FORMAT").val("' . getDolGlobalString('ACCOUNTING_EXPORT_FORMAT') . '");' . "\n";
3779
                print '            jQuery("#ACCOUNTING_EXPORT_FORMAT").prop("disabled", true);' . "\n";
3780
            } else {
3781
                print '            jQuery("#ACCOUNTING_EXPORT_FORMAT").val("' . $param['ACCOUNTING_EXPORT_FORMAT'] . '");' . "\n";
3782
                print '            jQuery("#ACCOUNTING_EXPORT_FORMAT").removeAttr("disabled");' . "\n";
3783
            }
3784
            if (empty($param['ACCOUNTING_EXPORT_SEPARATORCSV'])) {
3785
                print '            jQuery("#ACCOUNTING_EXPORT_SEPARATORCSV").val("");' . "\n";
3786
                print '            jQuery("#ACCOUNTING_EXPORT_SEPARATORCSV").prop("disabled", true);' . "\n";
3787
            } else {
3788
                print '            jQuery("#ACCOUNTING_EXPORT_SEPARATORCSV").val("' . getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV') . '");' . "\n";
3789
                print '            jQuery("#ACCOUNTING_EXPORT_SEPARATORCSV").removeAttr("disabled");' . "\n";
3790
            }
3791
            if (empty($param['ACCOUNTING_EXPORT_ENDLINE'])) {
3792
                print '            jQuery("#ACCOUNTING_EXPORT_ENDLINE").prop("disabled", true);' . "\n";
3793
            } else {
3794
                print '            jQuery("#ACCOUNTING_EXPORT_ENDLINE").removeAttr("disabled");' . "\n";
3795
            }
3796
            if (empty($param['ACCOUNTING_EXPORT_DATE'])) {
3797
                print '            jQuery("#ACCOUNTING_EXPORT_DATE").val("");' . "\n";
3798
                print '            jQuery("#ACCOUNTING_EXPORT_DATE").prop("disabled", true);' . "\n";
3799
            } else {
3800
                print '            jQuery("#ACCOUNTING_EXPORT_DATE").val("' . getDolGlobalString('ACCOUNTING_EXPORT_DATE') . '");' . "\n";
3801
                print '            jQuery("#ACCOUNTING_EXPORT_DATE").removeAttr("disabled");' . "\n";
3802
            }
3803
            print '        }' . "\n";
3804
        }
3805
        print '    }' . "\n";
3806
        print '    initfields();' . "\n";
3807
        print '    jQuery("#ACCOUNTING_EXPORT_MODELCSV").change(function() {' . "\n";
3808
        print '        initfields();' . "\n";
3809
        print '    });' . "\n";
3810
        print '})' . "\n";
3811
        print '</script>' . "\n";
3812
3813
        print '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">';
3814
        print '<input type="hidden" name="token" value="' . newToken() . '">';
3815
        print '<input type="hidden" name="action" value="update">';
3816
3817
        /*
3818
         * Main Options
3819
         */
3820
3821
        print '<table class="noborder centpercent">';
3822
        print '<tr class="liste_titre">';
3823
        print '<td colspan="3">' . $langs->trans('Options') . '</td>';
3824
        print "</tr>\n";
3825
3826
        $num = count($main_option);
3827
        if ($num) {
3828
            foreach ($main_option as $key) {
3829
                print '<tr class="oddeven value">';
3830
3831
                // Param
3832
                $label = $langs->trans($key);
3833
                print '<td width="50%">' . $label . '</td>';
3834
3835
                // Value
3836
                print '<td>';
3837
                print '<input type="text" size="20" id="' . $key . '" name="' . $key . '" value="' . getDolGlobalString($key) . '">';
3838
                print '</td></tr>';
3839
            }
3840
        }
3841
3842
        print "</table>\n";
3843
3844
        print "<br>\n";
3845
3846
        /*
3847
         * Export model
3848
         */
3849
        print '<table class="noborder centpercent">';
3850
3851
        print '<tr class="liste_titre">';
3852
        print '<td colspan="2">' . $langs->trans("Modelcsv") . '</td>';
3853
        print '</tr>';
3854
3855
3856
        print '<tr class="oddeven">';
3857
        print '<td width="50%">' . $langs->trans("Selectmodelcsv") . '</td>';
3858
        if (!$conf->use_javascript_ajax) {
3859
            print '<td class="nowrap">';
3860
            print $langs->trans("NotAvailableWhenAjaxDisabled");
3861
            print "</td>";
3862
        } else {
3863
            print '<td>';
3864
            $listmodelcsv = $accountancyexport->getType();
3865
            print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listmodelcsv, getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV'), 0, 0, 0, '', 0, 0, 0, '', '', 1);
3866
3867
            print '</td>';
3868
        }
3869
        print "</td></tr>";
3870
        print "</table>";
3871
3872
        print "<br>\n";
3873
3874
        /*
3875
         *  Parameters
3876
         */
3877
3878
        $num2 = count($model_option);
3879
        if ($num2) {
3880
            print '<table class="noborder centpercent">';
3881
            print '<tr class="liste_titre">';
3882
            print '<td colspan="3">' . $langs->trans('OtherOptions') . '</td>';
3883
            print "</tr>\n";
3884
3885
            foreach ($model_option as $key) {
3886
                print '<tr class="oddeven value">';
3887
3888
                // Param
3889
                $label = $key['label'];
3890
                print '<td width="50%">' . $langs->trans($label) . '</td>';
3891
3892
                // Value
3893
                print '<td>';
3894
                if (is_array($key['param'])) {
3895
                    print $form->selectarray($label, $key['param'], getDolGlobalString($label), 0);
3896
                } else {
3897
                    print '<input type="text" size="20" id="' . $label . '" name="' . $key['label'] . '" value="' . getDolGlobalString($label) . '">';
3898
                }
3899
3900
                print '</td></tr>';
3901
            }
3902
3903
            print "</table>\n";
3904
        }
3905
3906
        print '<div class="center"><input type="submit" class="button" value="' . dol_escape_htmltag($langs->trans('Modify')) . '" name="button"></div>';
3907
3908
        print '</form>';
3909
3910
// End of page
3911
        llxFooter();
3912
        $db->close();
3913
    }
3914
3915
    /**
3916
     *  \file       htdocs/accountancy/admin/fiscalyear.php
3917
     *  \ingroup    Accountancy (Double entries)
3918
     *  \brief      Setup page to configure fiscal year
3919
     */
3920
    public function fiscalyear()
3921
    {
3922
        global $conf;
3923
        global $db;
3924
        global $user;
3925
        global $hookmanager;
3926
        global $user;
3927
        global $menumanager;
3928
        global $langs;
3929
3930
        $action = GETPOST('action', 'aZ09');
3931
3932
// Load variable for pagination
3933
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
3934
        $sortfield = GETPOST('sortfield', 'aZ09comma');
3935
        $sortorder = GETPOST('sortorder', 'aZ09comma');
3936
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
3937
        if (empty($page) || $page == -1) {
3938
            $page = 0;
3939
        }     // If $page is not defined, or '' or -1
3940
        $offset = $limit * $page;
3941
        $pageprev = $page - 1;
3942
        $pagenext = $page + 1;
3943
        if (!$sortfield) {
3944
            $sortfield = "f.rowid"; // Set here default search field
3945
        }
3946
        if (!$sortorder) {
3947
            $sortorder = "ASC";
3948
        }
3949
3950
// Load translation files required by the page
3951
        $langs->loadLangs(["admin", "compta"]);
3952
3953
        $error = 0;
3954
        $errors = [];
3955
3956
// List of status
3957
        static $tmpstatut2label = [
3958
            '0' => 'OpenFiscalYear',
3959
            '1' => 'CloseFiscalYear',
3960
        ];
3961
3962
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
3963
        $object = new Fiscalyear($db);
3964
        $hookmanager->initHooks(['fiscalyearlist']);
3965
3966
// Security check
3967
        if ($user->socid > 0) {
3968
            accessforbidden();
3969
        }
3970
        if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {              // If we can read accounting records, we should be able to see fiscal year.
3971
            accessforbidden();
3972
        }
3973
3974
        /*
3975
         * Actions
3976
         */
3977
3978
3979
        /*
3980
         * View
3981
         */
3982
3983
        $max = 100;
3984
3985
        $form = new Form($db);
3986
        $fiscalyearstatic = new Fiscalyear($db);
3987
3988
        $title = $langs->trans('AccountingPeriods');
3989
3990
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
3991
3992
        llxHeader('', $title, $help_url);
3993
3994
        $sql = "SELECT f.rowid, f.label, f.date_start, f.date_end, f.statut as status, f.entity";
3995
        $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_fiscalyear as f";
3996
        $sql .= " WHERE f.entity = " . $conf->entity;
3997
        $sql .= $db->order($sortfield, $sortorder);
3998
3999
// Count total nb of records
4000
        $nbtotalofrecords = '';
4001
        if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
4002
            $result = $db->query($sql);
4003
            $nbtotalofrecords = $db->num_rows($result);
4004
            if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
4005
                $page = 0;
4006
                $offset = 0;
4007
            }
4008
        }
4009
4010
        $sql .= $db->plimit($limit + 1, $offset);
4011
4012
        $result = $db->query($sql);
4013
        if ($result) {
4014
            $num = $db->num_rows($result);
4015
            $param = '';
4016
4017
            $parameters = ['param' => $param];
4018
            $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
4019
            if ($reshook < 0) {
4020
                setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
4021
            }
4022
4023
            $newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint;
4024
4025
            if (empty($reshook)) {
4026
                $newcardbutton .= dolGetButtonTitle($langs->trans('NewFiscalYear'), '', 'fa fa-plus-circle', 'fiscalyear_card.php?action=create', '', $user->hasRight('accounting', 'fiscalyear', 'write'));
4027
            }
4028
4029
            $title = $langs->trans('AccountingPeriods');
4030
            print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'calendar', 0, $newcardbutton, '', $limit, 1);
4031
4032
            print '<div class="div-table-responsive">';
4033
            print '<table class="tagtable liste centpercent">';
4034
            print '<tr class="liste_titre">';
4035
            print '<td>' . $langs->trans("Ref") . '</td>';
4036
            print '<td>' . $langs->trans("Label") . '</td>';
4037
            print '<td>' . $langs->trans("DateStart") . '</td>';
4038
            print '<td>' . $langs->trans("DateEnd") . '</td>';
4039
            print '<td class="center">' . $langs->trans("NumberOfAccountancyEntries") . '</td>';
4040
            print '<td class="center">' . $langs->trans("NumberOfAccountancyMovements") . '</td>';
4041
            print '<td class="right">' . $langs->trans("Status") . '</td>';
4042
            print '</tr>';
4043
4044
            // Loop on record
4045
            // --------------------------------------------------------------------
4046
            $i = 0;
4047
            if ($num) {
4048
                while ($i < $num && $i < $max) {
4049
                    $obj = $db->fetch_object($result);
4050
4051
                    $fiscalyearstatic->ref = $obj->rowid;
4052
                    $fiscalyearstatic->id = $obj->rowid;
4053
                    $fiscalyearstatic->date_start = $obj->date_start;
4054
                    $fiscalyearstatic->date_end = $obj->date_end;
4055
                    $fiscalyearstatic->statut = $obj->status;
4056
                    $fiscalyearstatic->status = $obj->status;
4057
4058
                    print '<tr class="oddeven">';
4059
                    print '<td>';
4060
                    print $fiscalyearstatic->getNomUrl(1);
4061
                    print '</td>';
4062
                    print '<td class="left">' . $obj->label . '</td>';
4063
                    print '<td class="left">' . dol_print_date($db->jdate($obj->date_start), 'day') . '</td>';
4064
                    print '<td class="left">' . dol_print_date($db->jdate($obj->date_end), 'day') . '</td>';
4065
                    print '<td class="center">' . $object->getAccountancyEntriesByFiscalYear($obj->date_start, $obj->date_end) . '</td>';
4066
                    print '<td class="center">' . $object->getAccountancyMovementsByFiscalYear($obj->date_start, $obj->date_end) . '</td>';
4067
                    print '<td class="right">' . $fiscalyearstatic->LibStatut($obj->status, 5) . '</td>';
4068
                    print '</tr>';
4069
                    $i++;
4070
                }
4071
            } else {
4072
                print '<tr class="oddeven"><td colspan="7"><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
4073
            }
4074
            print '</table>';
4075
            print '</div>';
4076
        } else {
4077
            dol_print_error($db);
4078
        }
4079
4080
// End of page
4081
        llxFooter();
4082
        $db->close();
4083
    }
4084
4085
    /**
4086
     * \file        htdocs/accountancy/admin/fiscalyear_card.php
4087
     * \ingroup     Accountancy (Double entries)
4088
     * \brief       Page to show a fiscal year
4089
     */
4090
    public function fiscalyear_card()
4091
    {
4092
        global $conf;
4093
        global $db;
4094
        global $user;
4095
        global $hookmanager;
4096
        global $user;
4097
        global $menumanager;
4098
        global $langs;
4099
4100
// Load translation files required by the page
4101
        $langs->loadLangs(["admin", "compta"]);
4102
4103
// Get parameters
4104
        $id = GETPOSTINT('id');
4105
        $ref = GETPOST('ref', 'alpha');
4106
4107
        $action = GETPOST('action', 'aZ09');
4108
        $confirm = GETPOST('confirm', 'alpha');
4109
        $cancel = GETPOST('cancel', 'aZ09');
4110
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)) . basename(__FILE__, '.php')); // To manage different context of search
4111
        $backtopage = GETPOST('backtopage', 'alpha');                   // if not set, a default page will be used
4112
        $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
4113
        $backtopagejsfields = GETPOST('backtopagejsfields', 'alpha');
4114
        $dol_openinpopup = GETPOST('dol_openinpopup', 'aZ09');
4115
4116
        if (!empty($backtopagejsfields)) {
4117
            $tmpbacktopagejsfields = explode(':', $backtopagejsfields);
4118
            $dol_openinpopup = $tmpbacktopagejsfields[0];
4119
        }
4120
4121
        $error = 0;
4122
4123
// Initialize technical objects
4124
        $object = new Fiscalyear($db);
4125
        $extrafields = new ExtraFields($db);
0 ignored issues
show
Bug introduced by
The type DoliModules\Accounting\Controller\ExtraFields was not found. Did you mean ExtraFields? If so, make sure to prefix the type with \.
Loading history...
4126
4127
// Load object
4128
        include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
4129
4130
// List of status
4131
        static $tmpstatus2label = [
4132
            '0' => 'OpenFiscalYear',
4133
            '1' => 'CloseFiscalYear',
4134
        ];
4135
        $status2label = [
4136
            '',
4137
        ];
4138
        foreach ($tmpstatus2label as $key => $val) {
4139
            $status2label[$key] = $langs->trans($val);
4140
        }
4141
4142
        $date_start = dol_mktime(0, 0, 0, GETPOSTINT('fiscalyearmonth'), GETPOSTINT('fiscalyearday'), GETPOSTINT('fiscalyearyear'));
4143
        $date_end = dol_mktime(0, 0, 0, GETPOSTINT('fiscalyearendmonth'), GETPOSTINT('fiscalyearendday'), GETPOSTINT('fiscalyearendyear'));
4144
4145
        $permissiontoadd = $user->hasRight('accounting', 'fiscalyear', 'write');
4146
4147
// Security check
4148
        if ($user->socid > 0) {
4149
            accessforbidden();
4150
        }
4151
        if (!$permissiontoadd) {
4152
            accessforbidden();
4153
        }
4154
4155
4156
        /*
4157
         * Actions
4158
         */
4159
4160
        $parameters = [];
4161
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
4162
        if ($reshook < 0) {
4163
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
4164
        }
4165
4166
        if ($action == 'confirm_delete' && $confirm == "yes") {
4167
            $result = $object->delete($user);
4168
            if ($result >= 0) {
4169
                header("Location: fiscalyear.php");
4170
                exit();
4171
            } else {
4172
                setEventMessages($object->error, $object->errors, 'errors');
4173
            }
4174
        } elseif ($action == 'add') {
4175
            if (!GETPOST('cancel', 'alpha')) {
4176
                $error = 0;
4177
4178
                $object->date_start = $date_start;
0 ignored issues
show
Documentation Bug introduced by
It seems like $date_start can also be of type string. However, the property $date_start is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
4179
                $object->date_end = $date_end;
0 ignored issues
show
Documentation Bug introduced by
It seems like $date_end can also be of type string. However, the property $date_end is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
4180
                $object->label = GETPOST('label', 'alpha');
0 ignored issues
show
Documentation Bug introduced by
It seems like GETPOST('label', 'alpha') can also be of type array or array or array. However, the property $label is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
4181
                $object->status = GETPOSTINT('status');
4182
                $object->datec = dol_now();
4183
4184
                if (empty($object->date_start) && empty($object->date_end)) {
4185
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
4186
                    $error++;
4187
                }
4188
                if (empty($object->label)) {
4189
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
4190
                    $error++;
4191
                }
4192
4193
                if (!$error) {
4194
                    $db->begin();
4195
4196
                    $id = $object->create($user);
4197
4198
                    if ($id > 0) {
4199
                        $db->commit();
4200
4201
                        header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
4202
                        exit();
4203
                    } else {
4204
                        $db->rollback();
4205
4206
                        setEventMessages($object->error, $object->errors, 'errors');
4207
                        $action = 'create';
4208
                    }
4209
                } else {
4210
                    $action = 'create';
4211
                }
4212
            } else {
4213
                header("Location: ./fiscalyear.php");
4214
                exit();
4215
            }
4216
        } elseif ($action == 'update') {
4217
            // Update record
4218
            if (!GETPOST('cancel', 'alpha')) {
4219
                $result = $object->fetch($id);
4220
4221
                $object->date_start = GETPOST("fiscalyear") ? $date_start : '';
4222
                $object->date_end = GETPOST("fiscalyearend") ? $date_end : '';
4223
                $object->label = GETPOST('label', 'alpha');
4224
                $object->status = GETPOSTINT('status');
4225
4226
                $result = $object->update($user);
4227
4228
                if ($result > 0) {
4229
                    header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
4230
                    exit();
4231
                } else {
4232
                    setEventMessages($object->error, $object->errors, 'errors');
4233
                }
4234
            } else {
4235
                header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
4236
                exit();
4237
            }
4238
        }
4239
4240
4241
        /*
4242
         * View
4243
         */
4244
4245
        $form = new Form($db);
4246
4247
        $title = $langs->trans("Fiscalyear") . " - " . $langs->trans("Card");
4248
        if ($action == 'create') {
4249
            $title = $langs->trans("NewFiscalYear");
4250
        }
4251
4252
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
4253
4254
        llxHeader('', $title, $help_url);
4255
4256
        if ($action == 'create') {
4257
            print load_fiche_titre($title, '', 'object_' . $object->picto);
4258
4259
            print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '">';
4260
            print '<input type="hidden" name="token" value="' . newToken() . '">';
4261
            print '<input type="hidden" name="action" value="add">';
4262
4263
            print dol_get_fiche_head();
4264
4265
            print '<table class="border centpercent">';
4266
4267
            // Label
4268
            print '<tr><td class="titlefieldcreate fieldrequired">' . $langs->trans("Label") . '</td><td><input name="label" size="32" value="' . GETPOST('label', 'alpha') . '"></td></tr>';
4269
4270
            // Date start
4271
            print '<tr><td class="fieldrequired">' . $langs->trans("DateStart") . '</td><td>';
4272
            print $form->selectDate(($date_start ? $date_start : ''), 'fiscalyear');
4273
            print '</td></tr>';
4274
4275
            // Date end
4276
            print '<tr><td class="fieldrequired">' . $langs->trans("DateEnd") . '</td><td>';
4277
            print $form->selectDate(($date_end ? $date_end : -1), 'fiscalyearend');
4278
            print '</td></tr>';
4279
4280
            /*
4281
            // Status
4282
            print '<tr>';
4283
            print '<td class="fieldrequired">' . $langs->trans("Status") . '</td>';
4284
            print '<td class="valeur">';
4285
            print $form->selectarray('status', $status2label, GETPOST('status', 'int'));
4286
            print '</td></tr>';
4287
            */
4288
4289
            print '</table>';
4290
4291
            print dol_get_fiche_end();
4292
4293
            print $form->buttonsSaveCancel("Create");
4294
4295
            print '</form>';
4296
        }
4297
4298
4299
// Part to edit record
4300
        if (($id || $ref) && $action == 'edit') {
4301
            print load_fiche_titre($langs->trans("Fiscalyear"), '', 'object_' . $object->picto);
4302
4303
            print '<form method="POST" name="update" action="' . $_SERVER['PHP_SELF'] . '">' . "\n";
4304
            print '<input type="hidden" name="token" value="' . newToken() . '">';
4305
            print '<input type="hidden" name="action" value="update">';
4306
            print '<input type="hidden" name="id" value="' . $object->id . '">';
4307
            if ($backtopage) {
4308
                print '<input type="hidden" name="backtopage" value="' . $backtopage . '">';
4309
            }
4310
            if ($backtopageforcancel) {
4311
                print '<input type="hidden" name="backtopageforcancel" value="' . $backtopageforcancel . '">';
4312
            }
4313
4314
            print dol_get_fiche_head();
4315
4316
            print '<table class="border centpercent tableforfieldedit">' . "\n";
4317
4318
            // Ref
4319
            print "<tr>";
4320
            print '<td class="titlefieldcreate titlefield">' . $langs->trans("Ref") . '</td><td>';
4321
            print $object->ref;
4322
            print '</td></tr>';
4323
4324
            // Label
4325
            print '<tr><td class="fieldrequired">' . $langs->trans("Label") . '</td><td>';
4326
            print '<input name="label" class="flat" size="32" value="' . $object->label . '">';
4327
            print '</td></tr>';
4328
4329
            // Date start
4330
            print '<tr><td class="fieldrequired">' . $langs->trans("DateStart") . '</td><td>';
4331
            print $form->selectDate($object->date_start ? $object->date_start : -1, 'fiscalyear');
4332
            print '</td></tr>';
4333
4334
            // Date end
4335
            print '<tr><td class="fieldrequired">' . $langs->trans("DateEnd") . '</td><td>';
4336
            print $form->selectDate($object->date_end ? $object->date_end : -1, 'fiscalyearend');
4337
            print '</td></tr>';
4338
4339
            // Status
4340
            print '<tr><td>' . $langs->trans("Status") . '</td><td>';
4341
            print $object->getLibStatut(4);
4342
            print '</td></tr>';
4343
4344
            print '</table>';
4345
4346
            print dol_get_fiche_end();
4347
4348
            print $form->buttonsSaveCancel();
4349
4350
            print '</form>';
4351
        }
4352
4353
// Part to show record
4354
        if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
4355
            $head = fiscalyear_prepare_head($object);
4356
4357
            print dol_get_fiche_head($head, 'card', $langs->trans("Fiscalyear"), 0, 'calendar');
4358
4359
            $formconfirm = '';
4360
4361
            // Confirmation to delete
4362
            if ($action == 'delete') {
4363
                $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . "?id=" . $object->id, $langs->trans("DeleteFiscalYear"), $langs->trans("ConfirmDeleteFiscalYear"), "confirm_delete", '', 0, 1);
4364
            }
4365
4366
            // Print form confirm
4367
            print $formconfirm;
4368
4369
            // Object card
4370
            // ------------------------------------------------------------
4371
            $linkback = '<a href="' . DOL_URL_ROOT . '/accountancy/admin/fiscalyear.php">' . $langs->trans("BackToList") . '</a>';
4372
4373
            print '<table class="border centpercent">';
4374
4375
            // Ref
4376
            print '<tr><td class="titlefield">' . $langs->trans("Ref") . '</td><td width="50%">';
4377
            print $object->ref;
4378
            print '</td><td>';
4379
            print $linkback;
4380
            print '</td></tr>';
4381
4382
            // Label
4383
            print '<tr><td class="tdtop">';
4384
            print $form->editfieldkey("Label", 'label', $object->label, $object, 1, 'alpha:32');
4385
            print '</td><td colspan="2">';
4386
            print $form->editfieldval("Label", 'label', $object->label, $object, 1, 'alpha:32');
4387
            print "</td></tr>";
4388
4389
            // Date start
4390
            print '<tr><td>';
4391
            print $form->editfieldkey("DateStart", 'date_start', $object->date_start, $object, 1, 'datepicker');
4392
            print '</td><td colspan="2">';
4393
            print $form->editfieldval("DateStart", 'date_start', $object->date_start, $object, 1, 'datepicker');
4394
            print '</td></tr>';
4395
4396
            // Date end
4397
            print '<tr><td>';
4398
            print $form->editfieldkey("DateEnd", 'date_end', $object->date_end, $object, 1, 'datepicker');
4399
            print '</td><td colspan="2">';
4400
            print $form->editfieldval("DateEnd", 'date_end', $object->date_end, $object, 1, 'datepicker');
4401
            print '</td></tr>';
4402
4403
            // Status
4404
            print '<tr><td>' . $langs->trans("Status") . '</td><td colspan="2">' . $object->getLibStatut(4) . '</td></tr>';
4405
4406
            print "</table>";
4407
4408
            print dol_get_fiche_end();
4409
4410
            /*
4411
             * Action bar
4412
             */
4413
            if ($user->hasRight('accounting', 'fiscalyear', 'write')) {
4414
                print '<div class="tabsAction">';
4415
4416
                print '<a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?action=edit&token=' . newToken() . '&id=' . $id . '">' . $langs->trans('Modify') . '</a>';
4417
4418
                //print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
4419
4420
                print '</div>';
4421
            }
4422
        }
4423
4424
// End of page
4425
        llxFooter();
4426
        $db->close();
4427
    }
4428
4429
    /**
4430
     * \file        htdocs/accountancy/admin/fiscalyear_info.php
4431
     * \ingroup     Accountancy (Double entries)
4432
     * \brief       Page to show info of a fiscal year
4433
     */
4434
    public function fiscalyear_info()
4435
    {
4436
        global $conf;
4437
        global $db;
4438
        global $user;
4439
        global $hookmanager;
4440
        global $user;
4441
        global $menumanager;
4442
        global $langs;
4443
4444
// Load translation files required by the page
4445
        $langs->loadLangs(["admin", "compta"]);
4446
4447
// Security check
4448
        if ($user->socid > 0) {
4449
            accessforbidden();
4450
        }
4451
        if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {
4452
            accessforbidden();
4453
        }
4454
4455
        $id = GETPOSTINT('id');
4456
4457
4458
// View
4459
4460
        $title = $langs->trans("Fiscalyear") . " - " . $langs->trans("Info");
4461
4462
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
4463
4464
        llxHeader('', $title, $help_url);
4465
4466
        if ($id) {
4467
            $object = new Fiscalyear($db);
4468
            $object->fetch($id);
4469
            $object->info($id);
4470
4471
            $head = fiscalyear_prepare_head($object);
4472
4473
            print dol_get_fiche_head($head, 'info', $langs->trans("Fiscalyear"), 0, 'calendar');
4474
4475
            print '<table width="100%"><tr><td>';
4476
            dol_print_object_info($object);
4477
            print '</td></tr></table>';
4478
4479
            print '</div>';
4480
        }
4481
4482
// End of page
4483
        llxFooter();
4484
        $db->close();
4485
    }
4486
4487
    /**
4488
     * \file        htdocs/accountancy/admin/index.php
4489
     * \ingroup     Accountancy (Double entries)
4490
     * \brief       Setup page to configure accounting expert module
4491
     */
4492
    public function index()
4493
    {
4494
        global $conf;
4495
        global $db;
4496
        global $user;
4497
        global $hookmanager;
4498
        global $user;
4499
        global $menumanager;
4500
        global $langs;
4501
4502
// Load translation files required by the page
4503
        $langs->loadLangs(["compta", "bills", "admin", "accountancy", "other"]);
4504
4505
// Security access
4506
        if (!$user->hasRight('accounting', 'chartofaccount')) {
4507
            accessforbidden();
4508
        }
4509
4510
        $action = GETPOST('action', 'aZ09');
4511
4512
        $nbletter = GETPOSTINT('ACCOUNTING_LETTERING_NBLETTERS');
4513
4514
// Parameters ACCOUNTING_* and others
4515
        $list = [
4516
            'ACCOUNTING_LENGTH_GACCOUNT',
4517
            'ACCOUNTING_LENGTH_AACCOUNT',
4518
//  'ACCOUNTING_LIMIT_LIST_VENTILATION'        // there is already a global parameter to define the nb of records in lists, we must use it in priority. Having one parameter for nb of record for each page is deprecated.
4519
//  'ACCOUNTING_LENGTH_DESCRIPTION',         // adjust size displayed for lines description for dol_trunc
4520
//  'ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT', // adjust size displayed for select account description for dol_trunc
4521
        ];
4522
4523
        $list_binding = [
4524
            'ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER',
4525
            'ACCOUNTING_DATE_START_BINDING',
4526
        ];
4527
4528
        $error = 0;
4529
4530
4531
        /*
4532
         * Actions
4533
         */
4534
4535
        if (in_array($action, ['setBANK_DISABLE_DIRECT_INPUT', 'setACCOUNTANCY_COMBO_FOR_AUX', 'setACCOUNTING_MANAGE_ZERO'])) {
4536
            $constname = preg_replace('/^set/', '', $action);
4537
            $constvalue = GETPOSTINT('value');
4538
            $res = dolibarr_set_const($db, $constname, $constvalue, 'yesno', 0, '', $conf->entity);
4539
            if (!($res > 0)) {
4540
                $error++;
4541
            }
4542
4543
            if (!$error) {
4544
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4545
            } else {
4546
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4547
            }
4548
        }
4549
4550
        if ($action == 'update') {
4551
            $error = 0;
4552
4553
            if (!$error) {
4554
                foreach ($list as $constname) {
4555
                    $constvalue = GETPOST($constname, 'alpha');
4556
                    if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
4557
                        $error++;
4558
                    }
4559
                }
4560
                if ($error) {
4561
                    setEventMessages($langs->trans("Error"), null, 'errors');
4562
                }
4563
4564
                // option in section binding
4565
                foreach ($list_binding as $constname) {
4566
                    $constvalue = GETPOST($constname, 'alpha');
4567
4568
                    if ($constname == 'ACCOUNTING_DATE_START_BINDING') {
4569
                        $constvalue = dol_mktime(0, 0, 0, GETPOSTINT($constname . 'month'), GETPOSTINT($constname . 'day'), GETPOSTINT($constname . 'year'));
4570
                    }
4571
4572
                    if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
4573
                        $error++;
4574
                    }
4575
                }
4576
4577
                // options in section other
4578
                if (GETPOSTISSET('ACCOUNTING_LETTERING_NBLETTERS')) {
4579
                    if (!dolibarr_set_const($db, 'ACCOUNTING_LETTERING_NBLETTERS', GETPOST('ACCOUNTING_LETTERING_NBLETTERS'), 'chaine', 0, '', $conf->entity)) {
4580
                        $error++;
4581
                    }
4582
                }
4583
4584
                if ($error) {
4585
                    setEventMessages($langs->trans("Error"), null, 'errors');
4586
                }
4587
            }
4588
4589
            if (!$error) {
4590
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4591
            }
4592
        }
4593
4594
        if ($action == 'setmanagezero') {
4595
            $setmanagezero = GETPOSTINT('value');
4596
            $res = dolibarr_set_const($db, "ACCOUNTING_MANAGE_ZERO", $setmanagezero, 'yesno', 0, '', $conf->entity);
4597
            if (!($res > 0)) {
4598
                $error++;
4599
            }
4600
4601
            if (!$error) {
4602
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4603
            } else {
4604
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4605
            }
4606
        }
4607
4608
        if ($action == 'setdisabledirectinput') {
4609
            $setdisabledirectinput = GETPOSTINT('value');
4610
            $res = dolibarr_set_const($db, "BANK_DISABLE_DIRECT_INPUT", $setdisabledirectinput, 'yesno', 0, '', $conf->entity);
4611
            if (!($res > 0)) {
4612
                $error++;
4613
            }
4614
4615
            if (!$error) {
4616
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4617
            } else {
4618
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4619
            }
4620
        }
4621
4622
        if ($action == 'setenabledraftexport') {
4623
            $setenabledraftexport = GETPOSTINT('value');
4624
            $res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL", $setenabledraftexport, 'yesno', 0, '', $conf->entity);
4625
            if (!($res > 0)) {
4626
                $error++;
4627
            }
4628
4629
            if (!$error) {
4630
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4631
            } else {
4632
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4633
            }
4634
        }
4635
4636
        if ($action == 'setenablesubsidiarylist') {
4637
            $setenablesubsidiarylist = GETPOSTINT('value');
4638
            $res = dolibarr_set_const($db, "ACCOUNTANCY_COMBO_FOR_AUX", $setenablesubsidiarylist, 'yesno', 0, '', $conf->entity);
4639
            if (!($res > 0)) {
4640
                $error++;
4641
            }
4642
4643
            if (!$error) {
4644
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4645
            } else {
4646
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4647
            }
4648
        }
4649
4650
        if ($action == 'setdisablebindingonsales') {
4651
            $setdisablebindingonsales = GETPOSTINT('value');
4652
            $res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_BINDING_ON_SALES", $setdisablebindingonsales, 'yesno', 0, '', $conf->entity);
4653
            if (!($res > 0)) {
4654
                $error++;
4655
            }
4656
4657
            if (!$error) {
4658
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4659
            } else {
4660
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4661
            }
4662
        }
4663
4664
        if ($action == 'setdisablebindingonpurchases') {
4665
            $setdisablebindingonpurchases = GETPOSTINT('value');
4666
            $res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_BINDING_ON_PURCHASES", $setdisablebindingonpurchases, 'yesno', 0, '', $conf->entity);
4667
            if (!($res > 0)) {
4668
                $error++;
4669
            }
4670
4671
            if (!$error) {
4672
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4673
            } else {
4674
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4675
            }
4676
        }
4677
4678
        if ($action == 'setdisablebindingonexpensereports') {
4679
            $setdisablebindingonexpensereports = GETPOSTINT('value');
4680
            $res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS", $setdisablebindingonexpensereports, 'yesno', 0, '', $conf->entity);
4681
            if (!($res > 0)) {
4682
                $error++;
4683
            }
4684
4685
            if (!$error) {
4686
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4687
            } else {
4688
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4689
            }
4690
        }
4691
4692
        if ($action == 'setenablelettering') {
4693
            $setenablelettering = GETPOSTINT('value');
4694
            $res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_LETTERING", $setenablelettering, 'yesno', 0, '', $conf->entity);
4695
            if (!($res > 0)) {
4696
                $error++;
4697
            }
4698
4699
            if (!$error) {
4700
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4701
            } else {
4702
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4703
            }
4704
        }
4705
4706
        if ($action == 'setenableautolettering') {
4707
            $setenableautolettering = GETPOSTINT('value');
4708
            $res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_AUTOLETTERING", $setenableautolettering, 'yesno', 0, '', $conf->entity);
4709
            if (!($res > 0)) {
4710
                $error++;
4711
            }
4712
4713
            if (!$error) {
4714
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4715
            } else {
4716
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4717
            }
4718
        }
4719
4720
        if ($action == 'setenablevatreversecharge') {
4721
            $setenablevatreversecharge = GETPOSTINT('value');
4722
            $res = dolibarr_set_const($db, "ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE", $setenablevatreversecharge, 'yesno', 0, '', $conf->entity);
4723
            if (!($res > 0)) {
4724
                $error++;
4725
            }
4726
4727
            if (!$error) {
4728
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
4729
            } else {
4730
                setEventMessages($langs->trans("Error"), null, 'mesgs');
4731
            }
4732
        }
4733
4734
4735
        /*
4736
         * View
4737
         */
4738
4739
        $form = new Form($db);
4740
4741
        $title = $langs->trans('ConfigAccountingExpert');
4742
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
4743
        llxHeader('', $title, $help_url);
4744
4745
4746
        $linkback = '';
4747
//$linkback = '<a href="' . DOL_URL_ROOT . '/admin/modules.php?restore_lastsearch_values=1">' . $langs->trans("BackToModuleList") . '</a>';
4748
        print load_fiche_titre($title, $linkback, 'accountancy');
4749
4750
        print '<br>';
4751
4752
// Show message if accountancy hidden options are activated to help to resolve some problems
4753
        if (!$user->admin) {
4754
            if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
4755
                print '<div class="info">' . $langs->trans("ConstantIsOn", "FACTURE_DEPOSITS_ARE_JUST_PAYMENTS") . '</div>';
4756
            }
4757
            if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
4758
                print '<div class="info">' . $langs->trans("ConstantIsOn", "FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS") . '</div>';
4759
            }
4760
            if (getDolGlobalString('ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY')) {
4761
                print '<div class="info">' . $langs->trans("ConstantIsOn", "ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY") . '</div>';
4762
            }
4763
            if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
4764
                print '<div class="info">' . $langs->trans("ConstantIsOn", "MAIN_COMPANY_PERENTITY_SHARED") . '</div>';
4765
            }
4766
            if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
4767
                print '<div class="info">' . $langs->trans("ConstantIsOn", "MAIN_PRODUCT_PERENTITY_SHARED") . '</div>';
4768
            }
4769
        }
4770
4771
        print '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">';
4772
        print '<input type="hidden" name="token" value="' . newToken() . '">';
4773
        print '<input type="hidden" name="action" value="update">';
4774
4775
// Params
4776
        print '<div class="div-table-responsive-no-min">';
4777
        print '<table class="noborder centpercent">';
4778
        print '<tr class="liste_titre">';
4779
        print '<td colspan="2">' . $langs->trans('Options') . '</td>';
4780
        print "</tr>\n";
4781
4782
// TO DO Mutualize code for yes/no constants
4783
4784
        /* Set this option as a hidden option but keep it for some needs.
4785
        print '<tr>';
4786
        print '<td>'.$langs->trans("ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL").'</td>';
4787
        if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL')) {
4788
            print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&enabledraftexport&value=0">';
4789
            print img_picto($langs->trans("Activated"), 'switch_on');
4790
            print '</a></td>';
4791
        } else {
4792
            print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&enabledraftexport&value=1">';
4793
            print img_picto($langs->trans("Disabled"), 'switch_off');
4794
            print '</a></td>';
4795
        }
4796
        print '</tr>';
4797
        */
4798
4799
        print '<tr class="oddeven">';
4800
        print '<td>' . $langs->trans("BANK_DISABLE_DIRECT_INPUT") . '</td>';
4801
        if (getDolGlobalString('BANK_DISABLE_DIRECT_INPUT')) {
4802
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setBANK_DISABLE_DIRECT_INPUT&value=0">';
4803
            print img_picto($langs->trans("Activated"), 'switch_on');
4804
            print '</a></td>';
4805
        } else {
4806
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setBANK_DISABLE_DIRECT_INPUT&value=1">';
4807
            print img_picto($langs->trans("Disabled"), 'switch_off');
4808
            print '</a></td>';
4809
        }
4810
        print '</tr>';
4811
4812
        print '<tr class="oddeven">';
4813
        print '<td>' . $langs->trans("ACCOUNTANCY_COMBO_FOR_AUX");
4814
        print ' - <span class="opacitymedium">' . $langs->trans("NotRecommended") . '</span>';
4815
        print '</td>';
4816
4817
        if (getDolGlobalString('ACCOUNTANCY_COMBO_FOR_AUX')) {
4818
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTANCY_COMBO_FOR_AUX&value=0">';
4819
            print img_picto($langs->trans("Activated"), 'switch_on');
4820
            print '</a></td>';
4821
        } else {
4822
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTANCY_COMBO_FOR_AUX&value=1">';
4823
            print img_picto($langs->trans("Disabled"), 'switch_off');
4824
            print '</a></td>';
4825
        }
4826
        print '</tr>';
4827
4828
        print '<tr class="oddeven">';
4829
        print '<td>' . $langs->trans("ACCOUNTING_MANAGE_ZERO") . '</td>';
4830
        if (getDolGlobalInt('ACCOUNTING_MANAGE_ZERO')) {
4831
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_MANAGE_ZERO&value=0">';
4832
            print img_picto($langs->trans("Activated"), 'switch_on');
4833
            print '</a></td>';
4834
        } else {
4835
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_MANAGE_ZERO&value=1">';
4836
            print img_picto($langs->trans("Disabled"), 'switch_off');
4837
            print '</a></td>';
4838
        }
4839
        print '</tr>';
4840
4841
// Param a user $user->hasRights('accounting', 'chartofaccount') can access
4842
        foreach ($list as $key) {
4843
            print '<tr class="oddeven value">';
4844
4845
            if (getDolGlobalInt('ACCOUNTING_MANAGE_ZERO') && ($key == 'ACCOUNTING_LENGTH_GACCOUNT' || $key == 'ACCOUNTING_LENGTH_AACCOUNT')) {
4846
                continue;
4847
            }
4848
4849
            // Param
4850
            $label = $langs->trans($key);
4851
            print '<td>' . $label . '</td>';
4852
            // Value
4853
            print '<td class="right">';
4854
            print '<input type="text" class="maxwidth50 right" id="' . $key . '" name="' . $key . '" value="' . getDolGlobalString($key) . '">';
4855
4856
            print '</td>';
4857
            print '</tr>';
4858
        }
4859
        print '</table>';
4860
        print '</div>';
4861
4862
        print '<br>';
4863
4864
// Binding params
4865
        print '<div class="div-table-responsive-no-min">';
4866
        print '<table class="noborder centpercent">';
4867
        print '<tr class="liste_titre">';
4868
        print '<td colspan="2">' . $langs->trans('BindingOptions') . '</td>';
4869
        print "</tr>\n";
4870
4871
// Param a user $user->hasRights('accounting', 'chartofaccount') can access
4872
        foreach ($list_binding as $key) {
4873
            print '<tr class="oddeven value">';
4874
4875
            // Param
4876
            $label = $langs->trans($key);
4877
            print '<td>' . $label . '</td>';
4878
            // Value
4879
            print '<td class="right minwidth75imp parentonrightofpage">';
4880
            if ($key == 'ACCOUNTING_DATE_START_BINDING') {
4881
                print $form->selectDate((getDolGlobalInt($key) ? (int) getDolGlobalInt($key) : -1), $key, 0, 0, 1);
4882
            } elseif ($key == 'ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER') {
4883
                $array = [0 => $langs->trans("PreviousMonth"), 1 => $langs->trans("CurrentMonth"), 2 => $langs->trans("Fiscalyear")];
4884
                print $form->selectarray($key, $array, getDolGlobalInt('ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER', 0), 0, 0, 0, '', 0, 0, 0, '', 'onrightofpage width200');
4885
            } else {
4886
                print '<input type="text" class="maxwidth100" id="' . $key . '" name="' . $key . '" value="' . getDolGlobalString($key) . '">';
4887
            }
4888
4889
            print '</td>';
4890
            print '</tr>';
4891
        }
4892
4893
        print '<tr class="oddeven">';
4894
        print '<td>' . $langs->trans("ACCOUNTING_DISABLE_BINDING_ON_SALES") . '</td>';
4895
        if (getDolGlobalString('ACCOUNTING_DISABLE_BINDING_ON_SALES')) {
4896
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setdisablebindingonsales&value=0">';
4897
            print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning');
4898
            print '</a></td>';
4899
        } else {
4900
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setdisablebindingonsales&value=1">';
4901
            print img_picto($langs->trans("Disabled"), 'switch_off');
4902
            print '</a></td>';
4903
        }
4904
        print '</tr>';
4905
4906
        print '<tr class="oddeven">';
4907
        print '<td>' . $langs->trans("ACCOUNTING_DISABLE_BINDING_ON_PURCHASES") . '</td>';
4908
        if (getDolGlobalString('ACCOUNTING_DISABLE_BINDING_ON_PURCHASES')) {
4909
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setdisablebindingonpurchases&value=0">';
4910
            print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning');
4911
            print '</a></td>';
4912
        } else {
4913
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setdisablebindingonpurchases&value=1">';
4914
            print img_picto($langs->trans("Disabled"), 'switch_off');
4915
            print '</a></td>';
4916
        }
4917
        print '</tr>';
4918
4919
        print '<tr class="oddeven">';
4920
        print '<td>' . $langs->trans("ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS") . '</td>';
4921
        if (getDolGlobalString('ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS')) {
4922
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setdisablebindingonexpensereports&value=0">';
4923
            print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning');
4924
            print '</a></td>';
4925
        } else {
4926
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setdisablebindingonexpensereports&value=1">';
4927
            print img_picto($langs->trans("Disabled"), 'switch_off');
4928
            print '</a></td>';
4929
        }
4930
        print '</tr>';
4931
4932
        print '</table>';
4933
        print '</div>';
4934
4935
4936
// Show advanced options
4937
        print '<br>';
4938
4939
4940
// Advanced params
4941
        print '<div class="div-table-responsive-no-min">';
4942
        print '<table class="noborder centpercent">';
4943
        print '<tr class="liste_titre">';
4944
        print '<td colspan="2">' . $langs->trans('OptionsAdvanced') . '</td>';
4945
        print "</tr>\n";
4946
4947
        print '<tr class="oddeven">';
4948
        print '<td>';
4949
        print $form->textwithpicto($langs->trans("ACCOUNTING_ENABLE_LETTERING"), $langs->trans("ACCOUNTING_ENABLE_LETTERING_DESC", $langs->transnoentitiesnoconv("NumMvts")) . '<br>' . $langs->trans("EnablingThisFeatureIsNotNecessary")) . '</td>';
4950
        if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
4951
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenablelettering&value=0">';
4952
            print img_picto($langs->trans("Activated"), 'switch_on');
4953
            print '</a></td>';
4954
        } else {
4955
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenablelettering&value=1">';
4956
            print img_picto($langs->trans("Disabled"), 'switch_off');
4957
            print '</a></td>';
4958
        }
4959
        print '</tr>';
4960
4961
        if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
4962
            // Number of letters for lettering (3 by default (AAA), min 2 (AA))
4963
            print '<tr class="oddeven">';
4964
            print '<td>';
4965
            print $form->textwithpicto($langs->trans("ACCOUNTING_LETTERING_NBLETTERS"), $langs->trans("ACCOUNTING_LETTERING_NBLETTERS_DESC")) . '</td>';
4966
            print '<td class="right">';
4967
4968
            if (empty($letter)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $letter does not exist. Did you maybe mean $setenableautolettering?
Loading history...
4969
                if (getDolGlobalInt('ACCOUNTING_LETTERING_NBLETTERS')) {
4970
                    $nbletter = getDolGlobalInt('ACCOUNTING_LETTERING_NBLETTERS');
4971
                } else {
4972
                    $nbletter = 3;
4973
                }
4974
            }
4975
4976
            print '<input class="flat right" name="ACCOUNTING_LETTERING_NBLETTERS" id="ACCOUNTING_LETTERING_NBLETTERS" value="' . $nbletter . '" type="number" step="1" min="2" max="3" >' . "\n";
4977
            print '</tr>';
4978
4979
            // Auto Lettering when transfer in accountancy is realized
4980
            print '<tr class="oddeven">';
4981
            print '<td>';
4982
            print $form->textwithpicto($langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING"), $langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING_DESC")) . '</td>';
4983
            if (getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
4984
                print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenableautolettering&value=0">';
4985
                print img_picto($langs->trans("Activated"), 'switch_on');
4986
                print '</a></td>';
4987
            } else {
4988
                print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenableautolettering&value=1">';
4989
                print img_picto($langs->trans("Disabled"), 'switch_off');
4990
                print '</a></td>';
4991
            }
4992
            print '</tr>';
4993
        }
4994
4995
        print '<tr class="oddeven">';
4996
        print '<td>';
4997
        print $form->textwithpicto($langs->trans("ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE"), $langs->trans("ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE_DESC", $langs->transnoentities("MenuDefaultAccounts"))) . '</td>';
4998
        if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
4999
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenablevatreversecharge&value=0">';
5000
            print img_picto($langs->trans("Activated"), 'switch_on');
5001
            print '</a></td>';
5002
        } else {
5003
            print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenablevatreversecharge&value=1">';
5004
            print img_picto($langs->trans("Disabled"), 'switch_off');
5005
            print '</a></td>';
5006
        }
5007
        print '</tr>';
5008
5009
        print '</table>';
5010
        print '</div>';
5011
5012
5013
        print '<div class="center"><input type="submit" class="button button-edit" name="button" value="' . $langs->trans('Modify') . '"></div>';
5014
5015
        print '</form>';
5016
5017
// End of page
5018
        llxFooter();
5019
        $db->close();
5020
    }
5021
5022
    /**
5023
     * \file        htdocs/accountancy/admin/journals_list.php
5024
     * \ingroup     Accountancy (Double entries)
5025
     * \brief       Setup page to configure journals
5026
     */
5027
    public function journals_list()
5028
    {
5029
        global $conf;
5030
        global $db;
5031
        global $user;
5032
        global $hookmanager;
5033
        global $user;
5034
        global $menumanager;
5035
        global $langs;
5036
5037
        global $sourceList;
5038
5039
        if (!defined('CSRFCHECK_WITH_TOKEN')) {
5040
            define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
5041
        }
5042
5043
// Load translation files required by the page
5044
        $langs->loadLangs(["admin", "compta", "accountancy"]);
5045
5046
        $action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view';
5047
        $confirm = GETPOST('confirm', 'alpha');
5048
        $id = 35;
5049
        $rowid = GETPOST('rowid', 'alpha');
5050
        $code = GETPOST('code', 'alpha');
5051
5052
// Security access
5053
        if (!$user->hasRight('accounting', 'chartofaccount')) {
5054
            accessforbidden();
5055
        }
5056
5057
        $acts = [];
5058
        $acts[0] = "activate";
5059
        $acts[1] = "disable";
5060
        $actl = [];
5061
        $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
5062
        $actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"');
5063
5064
        $listoffset = GETPOST('listoffset', 'alpha');
5065
        $listlimit = GETPOSTINT('listlimit') > 0 ? GETPOSTINT('listlimit') : 1000;
5066
        $active = 1;
5067
5068
        $sortfield = GETPOST('sortfield', 'aZ09comma');
5069
        $sortorder = GETPOST('sortorder', 'aZ09comma');
5070
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
5071
        if (empty($page) || $page == -1) {
5072
            $page = 0;
5073
        }     // If $page is not defined, or '' or -1
5074
        $offset = $listlimit * $page;
5075
        $pageprev = $page - 1;
5076
        $pagenext = $page + 1;
5077
        if (empty($sortfield)) {
5078
            $sortfield = 'code';
5079
        }
5080
        if (empty($sortorder)) {
5081
            $sortorder = 'ASC';
5082
        }
5083
5084
        $error = 0;
5085
5086
        $search_country_id = GETPOSTINT('search_country_id');
5087
5088
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
5089
        $hookmanager->initHooks(['admin']);
5090
5091
// This page is a generic page to edit dictionaries
5092
// Put here declaration of dictionaries properties
5093
5094
// Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this.
5095
        $taborder = [35];
5096
5097
// Name of SQL tables of dictionaries
5098
        $tabname = [];
5099
        $tabname[35] = MAIN_DB_PREFIX . "accounting_journal";
5100
5101
// Dictionary labels
5102
        $tablib = [];
5103
        $tablib[35] = "DictionaryAccountancyJournal";
5104
5105
// Requests to extract data
5106
        $tabsql = [];
5107
        $tabsql[35] = "SELECT a.rowid as rowid, a.code as code, a.label, a.nature, a.active FROM " . MAIN_DB_PREFIX . "accounting_journal as a";
5108
5109
// Criteria to sort dictionaries
5110
        $tabsqlsort = [];
5111
        $tabsqlsort[35] = "code ASC";
5112
5113
// Nom des champs en resultat de select pour affichage du dictionnaire
5114
        $tabfield = [];
5115
        $tabfield[35] = "code,label,nature";
5116
5117
// Nom des champs d'edition pour modification d'un enregistrement
5118
        $tabfieldvalue = [];
5119
        $tabfieldvalue[35] = "code,label,nature";
5120
5121
// Nom des champs dans la table pour insertion d'un enregistrement
5122
        $tabfieldinsert = [];
5123
        $tabfieldinsert[35] = "code,label,nature";
5124
5125
// Nom du rowid si le champ n'est pas de type autoincrement
5126
// Example: "" if id field is "rowid" and has autoincrement on
5127
//          "nameoffield" if id field is not "rowid" or has not autoincrement on
5128
        $tabrowid = [];
5129
        $tabrowid[35] = "";
5130
5131
// Condition to show dictionary in setup page
5132
        $tabcond = [];
5133
        $tabcond[35] = isModEnabled('accounting');
5134
5135
// List of help for fields
5136
        $tabhelp = [];
5137
        $tabhelp[35] = ['code' => $langs->trans("EnterAnyCode")];
5138
5139
// List of check for fields (NOT USED YET)
5140
        $tabfieldcheck = [];
5141
        $tabfieldcheck[35] = [];
5142
5143
// Complete all arrays with entries found into modules
5144
        complete_dictionary_with_modules($taborder, $tabname, $tablib, $tabsql, $tabsqlsort, $tabfield, $tabfieldvalue, $tabfieldinsert, $tabrowid, $tabcond, $tabhelp, $tabfieldcheck);
5145
5146
5147
// Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact")
5148
        $elementList = [];
5149
// Must match ids defined into eldy.lib.php
5150
        $sourceList = [
5151
            '1' => $langs->trans('AccountingJournalType1'),
5152
            '2' => $langs->trans('AccountingJournalType2'),
5153
            '3' => $langs->trans('AccountingJournalType3'),
5154
            '4' => $langs->trans('AccountingJournalType4'),
5155
            '5' => $langs->trans('AccountingJournalType5'),
5156
            '8' => $langs->trans('AccountingJournalType8'),
5157
            '9' => $langs->trans('AccountingJournalType9'),
5158
        ];
5159
5160
        /*
5161
         * Actions
5162
         */
5163
5164
        if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) {
5165
            $search_country_id = '';
5166
        }
5167
5168
// Actions add or modify an entry into a dictionary
5169
        if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
5170
            $listfield = explode(',', str_replace(' ', '', $tabfield[$id]));
5171
            $listfieldinsert = explode(',', $tabfieldinsert[$id]);
5172
            $listfieldmodify = explode(',', $tabfieldinsert[$id]);
5173
            $listfieldvalue = explode(',', $tabfieldvalue[$id]);
5174
5175
            // Check that all fields are filled
5176
            $ok = 1;
5177
5178
            // Other checks
5179
            if (GETPOSTISSET("code")) {
5180
                if (GETPOST("code") == '0') {
5181
                    $ok = 0;
5182
                    setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
5183
                }
5184
            }
5185
            if (!GETPOST('label', 'alpha')) {
5186
                setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
5187
                $ok = 0;
5188
            }
5189
5190
            // Si verif ok et action add, on ajoute la ligne
5191
            if ($ok && GETPOST('actionadd', 'alpha')) {
5192
                if ($tabrowid[$id]) {
5193
                    // Get free id for insert
5194
                    $newid = 0;
5195
                    $sql = "SELECT MAX(" . $db->sanitize($tabrowid[$id]) . ") newid FROM " . $db->sanitize($tabname[$id]);
5196
                    $result = $db->query($sql);
5197
                    if ($result) {
5198
                        $obj = $db->fetch_object($result);
5199
                        $newid = ($obj->newid + 1);
5200
                    } else {
5201
                        dol_print_error($db);
5202
                    }
5203
                }
5204
5205
                // Add new entry
5206
                $sql = "INSERT INTO " . $db->sanitize($tabname[$id]) . " (";
5207
                // List of fields
5208
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
5209
                    $sql .= $tabrowid[$id] . ",";
5210
                }
5211
                $sql .= $db->sanitize($tabfieldinsert[$id]);
5212
                $sql .= ",active,entity)";
5213
                $sql .= " VALUES(";
5214
5215
                // List of values
5216
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
5217
                    $sql .= $newid . ",";
5218
                }
5219
                $i = 0;
5220
                foreach ($listfieldinsert as $f => $value) {
5221
                    if ($i) {
5222
                        $sql .= ",";
5223
                    }
5224
                    if (GETPOST($listfieldvalue[$i]) == '') {
5225
                        $sql .= "null"; // For vat, we want/accept code = ''
5226
                    } else {
5227
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
5228
                    }
5229
                    $i++;
5230
                }
5231
                $sql .= ",1," . $conf->entity . ")";
5232
5233
                dol_syslog("actionadd", LOG_DEBUG);
5234
                $result = $db->query($sql);
5235
                if ($result) {  // Add is ok
5236
                    setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
5237
                    $_POST = ['id' => $id]; // Clean $_POST array, we keep only id
5238
                } else {
5239
                    if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
5240
                        setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
5241
                    } else {
5242
                        dol_print_error($db);
5243
                    }
5244
                }
5245
            }
5246
5247
            // Si verif ok et action modify, on modifie la ligne
5248
            if ($ok && GETPOST('actionmodify', 'alpha')) {
5249
                if ($tabrowid[$id]) {
5250
                    $rowidcol = $tabrowid[$id];
5251
                } else {
5252
                    $rowidcol = "rowid";
5253
                }
5254
5255
                // Modify entry
5256
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET ";
5257
                // Modifie valeur des champs
5258
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) {
5259
                    $sql .= $db->sanitize($tabrowid[$id]) . " = ";
5260
                    $sql .= "'" . $db->escape($rowid) . "', ";
5261
                }
5262
                $i = 0;
5263
                foreach ($listfieldmodify as $field) {
5264
                    if ($i) {
5265
                        $sql .= ",";
5266
                    }
5267
                    $sql .= $field . " = ";
5268
                    $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
5269
                    $i++;
5270
                }
5271
                $sql .= " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
5272
                $sql .= " AND entity = " . ((int) $conf->entity);
5273
5274
                dol_syslog("actionmodify", LOG_DEBUG);
5275
                //print $sql;
5276
                $resql = $db->query($sql);
5277
                if (!$resql) {
5278
                    setEventMessages($db->error(), null, 'errors');
5279
                }
5280
            }
5281
            //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
5282
        }
5283
5284
//if (GETPOST('actioncancel', 'alpha'))
5285
//{
5286
//  $_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
5287
//}
5288
5289
        if ($action == 'confirm_delete' && $confirm == 'yes') {       // delete
5290
            if ($tabrowid[$id]) {
5291
                $rowidcol = $tabrowid[$id];
5292
            } else {
5293
                $rowidcol = "rowid";
5294
            }
5295
5296
            $sql = "DELETE from " . $db->sanitize($tabname[$id]) . " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
5297
            $sql .= " AND entity = " . ((int) $conf->entity);
5298
5299
            dol_syslog("delete", LOG_DEBUG);
5300
            $result = $db->query($sql);
5301
            if (!$result) {
5302
                if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') {
5303
                    setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors');
5304
                } else {
5305
                    dol_print_error($db);
5306
                }
5307
            }
5308
        }
5309
5310
// activate
5311
        if ($action == $acts[0]) {
5312
            if ($tabrowid[$id]) {
5313
                $rowidcol = $tabrowid[$id];
5314
            } else {
5315
                $rowidcol = "rowid";
5316
            }
5317
5318
            if ($rowid) {
5319
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
5320
            } elseif ($code) {
5321
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE code = '" . $db->escape($code) . "'";
5322
            }
5323
            $sql .= " AND entity = " . $conf->entity;
5324
5325
            $result = $db->query($sql);
5326
            if (!$result) {
5327
                dol_print_error($db);
5328
            }
5329
        }
5330
5331
// disable
5332
        if ($action == $acts[1]) {
5333
            if ($tabrowid[$id]) {
5334
                $rowidcol = $tabrowid[$id];
5335
            } else {
5336
                $rowidcol = "rowid";
5337
            }
5338
5339
            if ($rowid) {
5340
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
5341
            } elseif ($code) {
5342
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE code='" . $db->escape($code) . "'";
5343
            }
5344
            $sql .= " AND entity = " . $conf->entity;
5345
5346
            $result = $db->query($sql);
5347
            if (!$result) {
5348
                dol_print_error($db);
5349
            }
5350
        }
5351
5352
5353
        /*
5354
         * View
5355
         */
5356
5357
        $form = new Form($db);
5358
        $formadmin = new FormAdmin($db);
5359
5360
        $title = $langs->trans('AccountingJournals');
5361
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
5362
        llxHeader('', $title, $help_url);
5363
5364
        $titre = $langs->trans("DictionarySetup");
5365
        $linkback = '';
5366
        if ($id) {
5367
            $titre .= ' - ' . $langs->trans($tablib[$id]);
5368
            $titlepicto = 'title_accountancy';
5369
        }
5370
5371
        print load_fiche_titre($titre, $linkback, $titlepicto);
5372
5373
5374
// Confirmation de la suppression de la ligne
5375
        if ($action == 'delete') {
5376
            print $form->formconfirm($_SERVER['PHP_SELF'] . '?' . ($page ? 'page=' . $page . '&' : '') . 'sortfield=' . $sortfield . '&sortorder=' . $sortorder . '&rowid=' . $rowid . '&code=' . $code . '&id=' . $id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1);
5377
        }
5378
5379
        /*
5380
         * Show a dictionary
5381
         */
5382
        if ($id) {
5383
            // Complete requete recherche valeurs avec critere de tri
5384
            $sql = $tabsql[$id];
5385
            $sql .= " WHERE a.entity = " . ((int) $conf->entity);
5386
5387
            // If sort order is "country", we use country_code instead
5388
            if ($sortfield == 'country') {
5389
                $sortfield = 'country_code';
5390
            }
5391
            $sql .= $db->order($sortfield, $sortorder);
5392
            $sql .= $db->plimit($listlimit + 1, $offset);
5393
5394
            $fieldlist = explode(',', $tabfield[$id]);
5395
5396
            print '<form action="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '" method="POST">';
5397
            print '<input type="hidden" name="token" value="' . newToken() . '">';
5398
            print '<input type="hidden" name="from" value="' . dol_escape_htmltag(GETPOST('from', 'alpha')) . '">';
5399
5400
            print '<div class="div-table-responsive">';
5401
            print '<table class="noborder centpercent">';
5402
5403
            // Form to add a new line
5404
            if ($tabname[$id]) {
5405
                $fieldlist = explode(',', $tabfield[$id]);
5406
5407
                // Line for title
5408
                print '<tr class="liste_titre">';
5409
                foreach ($fieldlist as $field => $value) {
5410
                    // Determine le nom du champ par rapport aux noms possibles
5411
                    // dans les dictionnaires de donnees
5412
                    $valuetoshow = ucfirst($fieldlist[$field]); // By default
5413
                    $valuetoshow = $langs->trans($valuetoshow); // try to translate
5414
                    $class = "left";
5415
                    if ($fieldlist[$field] == 'code') {
5416
                        $valuetoshow = $langs->trans("Code");
5417
                    }
5418
                    if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') {
5419
                        $valuetoshow = $langs->trans("Label");
5420
                    }
5421
                    if ($fieldlist[$field] == 'nature') {
5422
                        $valuetoshow = $langs->trans("NatureOfJournal");
5423
                    }
5424
5425
                    if ($valuetoshow != '') {
5426
                        print '<td class="' . $class . '">';
5427
                        if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) {
5428
                            print '<a href="' . $tabhelp[$id][$value] . '">' . $valuetoshow . ' ' . img_help(1, $valuetoshow) . '</a>';
5429
                        } elseif (!empty($tabhelp[$id][$value])) {
5430
                            print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]);
5431
                        } else {
5432
                            print $valuetoshow;
5433
                        }
5434
                        print '</td>';
5435
                    }
5436
                }
5437
5438
                print '<td>';
5439
                print '<input type="hidden" name="id" value="' . $id . '">';
5440
                print '</td>';
5441
                print '<td></td>';
5442
                print '<td></td>';
5443
                print '<td></td>';
5444
                print '</tr>';
5445
5446
                // Line to enter new values
5447
                print '<tr class="oddeven nodrag nodrap nohover">';
5448
5449
                $obj = new stdClass();
5450
                // If data was already input, we define them in obj to populate input fields.
5451
                if (GETPOST('actionadd', 'alpha')) {
5452
                    foreach ($fieldlist as $key => $val) {
5453
                        if (GETPOST($val) != '') {
5454
                            $obj->$val = GETPOST($val);
5455
                        }
5456
                    }
5457
                }
5458
5459
                $tmpaction = 'create';
5460
                $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
5461
                $reshook = $hookmanager->executeHooks('createDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
5462
                $error = $hookmanager->error;
5463
                $errors = $hookmanager->errors;
5464
5465
                if (empty($reshook)) {
5466
                    $this->fieldListJournal($fieldlist, $obj, $tabname[$id], 'add');
5467
                }
5468
5469
                print '<td colspan="4" class="right">';
5470
                print '<input type="submit" class="button button-add" name="actionadd" value="' . $langs->trans("Add") . '">';
5471
                print '</td>';
5472
                print "</tr>";
5473
5474
                print '<tr><td colspan="7">&nbsp;</td></tr>'; // Keep &nbsp; to have a line with enough height
5475
            }
5476
5477
5478
            // List of available record in database
5479
            dol_syslog("htdocs/admin/dict", LOG_DEBUG);
5480
            $resql = $db->query($sql);
5481
            if ($resql) {
5482
                $num = $db->num_rows($resql);
5483
                $i = 0;
5484
5485
                $param = '&id=' . ((int) $id);
5486
                if ($search_country_id > 0) {
5487
                    $param .= '&search_country_id=' . urlencode((string) ($search_country_id));
5488
                }
5489
                $paramwithsearch = $param;
5490
                if ($sortorder) {
5491
                    $paramwithsearch .= '&sortorder=' . $sortorder;
5492
                }
5493
                if ($sortfield) {
5494
                    $paramwithsearch .= '&sortfield=' . $sortfield;
5495
                }
5496
                if (GETPOST('from', 'alpha')) {
5497
                    $paramwithsearch .= '&from=' . GETPOST('from', 'alpha');
5498
                }
5499
5500
                // There is several pages
5501
                if ($num > $listlimit) {
5502
                    print '<tr class="none"><td class="right" colspan="' . (3 + count($fieldlist)) . '">';
5503
                    print_fleche_navigation($page, $_SERVER['PHP_SELF'], $paramwithsearch, ($num > $listlimit), '<li class="pagination"><span>' . $langs->trans("Page") . ' ' . ($page + 1) . '</span></li>');
5504
                    print '</td></tr>';
5505
                }
5506
5507
                // Title line with search boxes
5508
                /*print '<tr class="liste_titre_filter liste_titre_add">';
5509
                print '<td class="liste_titre"></td>';
5510
                print '<td class="liste_titre"></td>';
5511
                print '<td class="liste_titre"></td>';
5512
                print '<td class="liste_titre"></td>';
5513
                print '<td class="liste_titre"></td>';
5514
                print '<td class="liste_titre"></td>';
5515
                print '<td class="liste_titre center">';
5516
                $searchpicto=$form->showFilterButtons();
5517
                print $searchpicto;
5518
                print '</td>';
5519
                print '</tr>';
5520
                */
5521
5522
                // Title of lines
5523
                print '<tr class="liste_titre liste_titre_add">';
5524
                foreach ($fieldlist as $field => $value) {
5525
                    // Determine le nom du champ par rapport aux noms possibles
5526
                    // dans les dictionnaires de donnees
5527
                    $showfield = 1; // By default
5528
                    $class = "left";
5529
                    $sortable = 1;
5530
                    $valuetoshow = '';
5531
                    /*
5532
                    $tmparray=getLabelOfField($fieldlist[$field]);
5533
                    $showfield=$tmp['showfield'];
5534
                    $valuetoshow=$tmp['valuetoshow'];
5535
                    $align=$tmp['align'];
5536
                    $sortable=$tmp['sortable'];
5537
                    */
5538
                    $valuetoshow = ucfirst($fieldlist[$field]); // By default
5539
                    $valuetoshow = $langs->trans($valuetoshow); // try to translate
5540
                    if ($fieldlist[$field] == 'code') {
5541
                        $valuetoshow = $langs->trans("Code");
5542
                    }
5543
                    if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') {
5544
                        $valuetoshow = $langs->trans("Label");
5545
                    }
5546
                    if ($fieldlist[$field] == 'nature') {
5547
                        $valuetoshow = $langs->trans("NatureOfJournal");
5548
                    }
5549
5550
                    // Affiche nom du champ
5551
                    if ($showfield) {
5552
                        print getTitleFieldOfList($valuetoshow, 0, $_SERVER['PHP_SELF'], ($sortable ? $fieldlist[$field] : ''), ($page ? 'page=' . $page . '&' : ''), $param, "", $sortfield, $sortorder, $class . ' ');
5553
                    }
5554
                }
5555
                print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER['PHP_SELF'], "active", ($page ? 'page=' . $page . '&' : ''), $param, '', $sortfield, $sortorder, 'center ');
5556
                print getTitleFieldOfList('');
5557
                print getTitleFieldOfList('');
5558
                print getTitleFieldOfList('');
5559
                print '</tr>';
5560
5561
                if ($num) {
5562
                    // Lines with values
5563
                    while ($i < $num) {
5564
                        $obj = $db->fetch_object($resql);
5565
                        //print_r($obj);
5566
                        print '<tr class="oddeven" id="rowid-' . $obj->rowid . '">';
5567
                        if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) {
5568
                            $tmpaction = 'edit';
5569
                            $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
5570
                            $reshook = $hookmanager->executeHooks('editDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
5571
                            $error = $hookmanager->error;
5572
                            $errors = $hookmanager->errors;
5573
5574
                            // Show fields
5575
                            if (empty($reshook)) {
5576
                                $this->fieldListJournal($fieldlist, $obj, $tabname[$id], 'edit');
5577
                            }
5578
5579
                            print '<td class="center" colspan="4">';
5580
                            print '<input type="hidden" name="page" value="' . $page . '">';
5581
                            print '<input type="hidden" name="rowid" value="' . $rowid . '">';
5582
                            print '<input type="submit" class="button button-edit" name="actionmodify" value="' . $langs->trans("Modify") . '">';
5583
                            print '<input type="submit" class="button button-cancel" name="actioncancel" value="' . $langs->trans("Cancel") . '">';
5584
                            print '<div name="' . (!empty($obj->rowid) ? $obj->rowid : $obj->code) . '"></div>';
5585
                            print '</td>';
5586
                        } else {
5587
                            $tmpaction = 'view';
5588
                            $parameters = ['fieldlist' => $fieldlist, 'tabname' => $tabname[$id]];
5589
                            $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
5590
5591
                            $error = $hookmanager->error;
5592
                            $errors = $hookmanager->errors;
5593
5594
                            if (empty($reshook)) {
5595
                                $langs->load("accountancy");
5596
                                foreach ($fieldlist as $field => $value) {
5597
                                    $showfield = 1;
5598
                                    $class = "left";
5599
                                    $tmpvar = $fieldlist[$field];
5600
                                    $valuetoshow = $obj->$tmpvar;
5601
                                    if ($valuetoshow == 'all') {
5602
                                        $valuetoshow = $langs->trans('All');
5603
                                    } elseif ($fieldlist[$field] == 'nature' && $tabname[$id] == MAIN_DB_PREFIX . 'accounting_journal') {
5604
                                        $key = $langs->trans("AccountingJournalType" . strtoupper($obj->nature));
5605
                                        $valuetoshow = ($obj->nature && $key != "AccountingJournalType" . strtoupper($langs->trans($obj->nature)) ? $key : $obj->{$fieldlist[$field]});
5606
                                    } elseif ($fieldlist[$field] == 'label' && $tabname[$id] == MAIN_DB_PREFIX . 'accounting_journal') {
5607
                                        $valuetoshow = $langs->trans($obj->label);
5608
                                    }
5609
5610
                                    $class = 'tddict';
5611
                                    // Show value for field
5612
                                    if ($showfield) {
5613
                                        print '<!-- ' . $fieldlist[$field] . ' --><td class="' . $class . '">' . dol_escape_htmltag($valuetoshow) . '</td>';
5614
                                    }
5615
                                }
5616
                            }
5617
5618
                            // Can an entry be erased or disabled ?
5619
                            $iserasable = 1;
5620
                            $canbedisabled = 1;
5621
                            $canbemodified = 1; // true by default
5622
                            if (isset($obj->code) && $id != 10) {
5623
                                if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i', $obj->code))) {
5624
                                    $iserasable = 0;
5625
                                    $canbedisabled = 0;
5626
                                }
5627
                            }
5628
5629
                            $canbemodified = $iserasable;
5630
5631
                            $url = $_SERVER['PHP_SELF'] . '?' . ($page ? 'page=' . $page . '&' : '') . 'sortfield=' . $sortfield . '&sortorder=' . $sortorder . '&rowid=' . (!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')) . '&code=' . (!empty($obj->code) ? urlencode($obj->code) : '');
5632
                            if ($param) {
5633
                                $url .= '&' . $param;
5634
                            }
5635
                            $url .= '&';
5636
5637
                            // Active
5638
                            print '<td class="nowrap center">';
5639
                            if ($canbedisabled) {
5640
                                print '<a href="' . $url . 'action=' . $acts[$obj->active] . '&token=' . newToken() . '">' . $actl[$obj->active] . '</a>';
5641
                            } else {
5642
                                print $langs->trans("AlwaysActive");
5643
                            }
5644
                            print "</td>";
5645
5646
                            // Modify link
5647
                            if ($canbemodified) {
5648
                                print '<td class="center"><a class="reposition editfielda" href="' . $url . 'action=edit&token=' . newToken() . '">' . img_edit() . '</a></td>';
5649
                            } else {
5650
                                print '<td>&nbsp;</td>';
5651
                            }
5652
5653
                            // Delete link
5654
                            if ($iserasable) {
5655
                                print '<td class="center">';
5656
                                if ($user->admin) {
5657
                                    print '<a href="' . $url . 'action=delete&token=' . newToken() . '">' . img_delete() . '</a>';
5658
                                }
5659
                                //else print '<a href="#">'.img_delete().'</a>';    // Some dictionary can be edited by other profile than admin
5660
                                print '</td>';
5661
                            } else {
5662
                                print '<td>&nbsp;</td>';
5663
                            }
5664
5665
                            print '<td></td>';
5666
5667
                            print '</td>';
5668
                        }
5669
5670
                        print "</tr>\n";
5671
                        $i++;
5672
                    }
5673
                }
5674
            } else {
5675
                dol_print_error($db);
5676
            }
5677
5678
            print '</table>';
5679
            print '</div>';
5680
5681
            print '</form>';
5682
        }
5683
5684
        print '<br>';
5685
5686
// End of page
5687
        llxFooter();
5688
        $db->close();
5689
    }
5690
5691
    /**
5692
     * \file        htdocs/accountancy/admin/productaccount.php
5693
     * \ingroup     Accountancy (Double entries)
5694
     * \brief       To define accounting account on product / service
5695
     */
5696
    public function productaccount()
5697
    {
5698
        global $conf;
5699
        global $db;
5700
        global $user;
5701
        global $hookmanager;
5702
        global $user;
5703
        global $menumanager;
5704
        global $langs;
5705
        global $mysoc;
5706
5707
// Load translation files required by the page
5708
        $langs->loadLangs(["companies", "compta", "accountancy", "products"]);
5709
5710
// Security check
5711
        if (!isModEnabled('accounting')) {
5712
            accessforbidden();
5713
        }
5714
        if (!$user->hasRight('accounting', 'bind', 'write')) {
5715
            accessforbidden();
5716
        }
5717
5718
// search & action GETPOST
5719
        $action = GETPOST('action', 'aZ09');
5720
        $massaction = GETPOST('massaction', 'alpha');
5721
        $confirm = GETPOST('confirm', 'alpha');
5722
        $optioncss = GETPOST('optioncss', 'alpha');
5723
5724
        $codeventil_buy = GETPOST('codeventil_buy', 'array');
5725
        $codeventil_sell = GETPOST('codeventil_sell', 'array');
5726
        $chk_prod = GETPOST('chk_prod', 'array');
5727
        $default_account = GETPOSTINT('default_account');
5728
        $account_number_buy = GETPOST('account_number_buy');
5729
        $account_number_sell = GETPOST('account_number_sell');
5730
        $changeaccount = GETPOST('changeaccount', 'array');
5731
        $changeaccount_buy = GETPOST('changeaccount_buy', 'array');
5732
        $changeaccount_sell = GETPOST('changeaccount_sell', 'array');
5733
        $searchCategoryProductOperator = (GETPOSTINT('search_category_product_operator') ? GETPOSTINT('search_category_product_operator') : 0);
5734
        $searchCategoryProductList = GETPOST('search_category_product_list', 'array');
5735
        $search_ref = GETPOST('search_ref', 'alpha');
5736
        $search_label = GETPOST('search_label', 'alpha');
5737
        $search_desc = GETPOST('search_desc', 'alpha');
5738
        $search_vat = GETPOST('search_vat', 'alpha');
5739
        $search_current_account = GETPOST('search_current_account', 'alpha');
5740
        $search_current_account_valid = GETPOST('search_current_account_valid', 'alpha');
5741
        if ($search_current_account_valid == '') {
5742
            $search_current_account_valid = 'withoutvalidaccount';
5743
        }
5744
        $search_onsell = GETPOST('search_onsell', 'alpha');
5745
        $search_onpurchase = GETPOST('search_onpurchase', 'alpha');
5746
5747
        $accounting_product_mode = GETPOST('accounting_product_mode', 'alpha');
5748
        $btn_changetype = GETPOST('changetype', 'alpha');
5749
5750
        if (empty($accounting_product_mode)) {
5751
            $accounting_product_mode = 'ACCOUNTANCY_SELL';
5752
        }
5753
5754
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : getDolGlobalInt('ACCOUNTING_LIMIT_LIST_VENTILATION', $conf->liste_limit);
5755
        $sortfield = GETPOST('sortfield', 'aZ09comma');
5756
        $sortorder = GETPOST('sortorder', 'aZ09comma');
5757
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
5758
        if (empty($page) || $page == -1) {
5759
            $page = 0;
5760
        }     // If $page is not defined, or '' or -1
5761
        $offset = $limit * $page;
5762
        $pageprev = $page - 1;
5763
        $pagenext = $page + 1;
5764
        if (!$sortfield) {
5765
            $sortfield = "p.ref";
5766
        }
5767
        if (!$sortorder) {
5768
            $sortorder = "ASC";
5769
        }
5770
5771
        if (empty($action)) {
5772
            $action = 'list';
5773
        }
5774
5775
        $arrayfields = [];
5776
5777
        $accounting_product_modes = [
5778
            'ACCOUNTANCY_SELL',
5779
            'ACCOUNTANCY_SELL_INTRA',
5780
            'ACCOUNTANCY_SELL_EXPORT',
5781
            'ACCOUNTANCY_BUY',
5782
            'ACCOUNTANCY_BUY_INTRA',
5783
            'ACCOUNTANCY_BUY_EXPORT',
5784
        ];
5785
5786
        if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
5787
            $accountancy_field_name = "accountancy_code_buy";
5788
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') {
5789
            $accountancy_field_name = "accountancy_code_buy_intra";
5790
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') {
5791
            $accountancy_field_name = "accountancy_code_buy_export";
5792
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
5793
            $accountancy_field_name = "accountancy_code_sell";
5794
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
5795
            $accountancy_field_name = "accountancy_code_sell_intra";
5796
        } else { // $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT'
5797
            $accountancy_field_name = "accountancy_code_sell_export";
5798
        }
5799
5800
        /*
5801
         * Actions
5802
         */
5803
5804
        if (GETPOST('cancel', 'alpha')) {
5805
            $action = 'list';
5806
            $massaction = '';
5807
        }
5808
        if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
5809
            $massaction = '';
5810
        }
5811
5812
        $parameters = [];
5813
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $object seems to be never defined.
Loading history...
5814
        if ($reshook < 0) {
5815
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
5816
        }
5817
5818
// Purge search criteria
5819
        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
5820
            $searchCategoryProductOperator = 0;
5821
            $searchCategoryProductList = [];
5822
            $search_ref = '';
5823
            $search_label = '';
5824
            $search_desc = '';
5825
            $search_vat = '';
5826
            $search_onsell = '';
5827
            $search_onpurchase = '';
5828
            $search_current_account = '';
5829
            $search_current_account_valid = '-1';
5830
        }
5831
5832
// Sales or Purchase mode ?
5833
        if ($action == 'update') {
5834
            if (!empty($btn_changetype)) {
5835
                $error = 0;
5836
5837
                if (in_array($accounting_product_mode, $accounting_product_modes)) {
5838
                    if (!dolibarr_set_const($db, 'ACCOUNTING_PRODUCT_MODE', $accounting_product_mode, 'chaine', 0, '', $conf->entity)) {
5839
                        $error++;
5840
                    }
5841
                } else {
5842
                    $error++;
5843
                }
5844
            }
5845
5846
            if (!empty($chk_prod) && $massaction === 'changeaccount') {
5847
                //$msg = '<div><span class="accountingprocessing">' . $langs->trans("Processing") . '...</span></div>';
5848
                if (!empty($chk_prod) && in_array($accounting_product_mode, $accounting_product_modes)) {
5849
                    $accounting = new AccountingAccount($db);
5850
5851
                    //$msg .= '<div><span class="accountingprocessing">' . count($chk_prod) . ' ' . $langs->trans("SelectedLines") . '</span></div>';
5852
                    $arrayofdifferentselectedvalues = [];
5853
5854
                    $cpt = 0;
5855
                    $ok = 0;
5856
                    $ko = 0;
5857
                    foreach ($chk_prod as $productid) {
5858
                        $accounting_account_id = GETPOST('codeventil_' . $productid);
5859
5860
                        $result = 0;
5861
                        if ($accounting_account_id > 0) {
5862
                            $arrayofdifferentselectedvalues[$accounting_account_id] = $accounting_account_id;
5863
                            $result = $accounting->fetch($accounting_account_id, null, 1);
5864
                        }
5865
                        if ($result <= 0) {
5866
                            // setEventMessages(null, $accounting->errors, 'errors');
5867
                            $msg .= '<div><span class="error">' . $langs->trans("ErrorDB") . ' : ' . $langs->trans("Product") . ' ' . $productid . ' ' . $langs->trans("NotVentilatedinAccount") . ' : id=' . $accounting_account_id . '<br> <pre>' . $sql . '</pre></span></div>';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $msg seems to be never defined.
Loading history...
5868
                            $ko++;
5869
                        } else {
5870
                            $sql = '';
5871
                            if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
5872
                                $sql_exists = "SELECT rowid FROM " . MAIN_DB_PREFIX . "product_perentity";
5873
                                $sql_exists .= " WHERE fk_product = " . ((int) $productid) . " AND entity = " . ((int) $conf->entity);
5874
                                $resql_exists = $db->query($sql_exists);
5875
                                if (!$resql_exists) {
5876
                                    $msg .= '<div><span class="error">' . $langs->trans("ErrorDB") . ' : ' . $langs->trans("Product") . ' ' . $productid . ' ' . $langs->trans("NotVentilatedinAccount") . ' : id=' . $accounting_account_id . '<br> <pre>' . json_encode($resql_exists) . '</pre></span></div>';
5877
                                    $ko++;
5878
                                } else {
5879
                                    $nb_exists = $db->num_rows($resql_exists);
5880
                                    if ($nb_exists <= 0) {
5881
                                        // insert
5882
                                        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_perentity (fk_product, entity, " . $db->sanitize($accountancy_field_name) . ")";
5883
                                        $sql .= " VALUES (" . ((int) $productid) . ", " . ((int) $conf->entity) . ", '" . $db->escape($accounting->account_number) . "')";
5884
                                    } else {
5885
                                        $obj_exists = $db->fetch_object($resql_exists);
5886
                                        // update
5887
                                        $sql = "UPDATE " . MAIN_DB_PREFIX . "product_perentity";
5888
                                        $sql .= " SET " . $db->sanitize($accountancy_field_name) . " = '" . $db->escape($accounting->account_number) . "'";
5889
                                        $sql .= " WHERE rowid = " . ((int) $obj_exists->rowid);
5890
                                    }
5891
                                }
5892
                            } else {
5893
                                $sql = " UPDATE " . MAIN_DB_PREFIX . "product";
5894
                                $sql .= " SET " . $db->sanitize($accountancy_field_name) . " = '" . $db->escape($accounting->account_number) . "'";
5895
                                $sql .= " WHERE rowid = " . ((int) $productid);
5896
                            }
5897
5898
                            dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG);
5899
5900
                            $db->begin();
5901
5902
                            if ($db->query($sql)) {
5903
                                $ok++;
5904
                                $db->commit();
5905
                            } else {
5906
                                $ko++;
5907
                                $db->rollback();
5908
                            }
5909
                        }
5910
5911
                        $cpt++;
5912
                    }
5913
                }
5914
5915
                if ($ko) {
5916
                    setEventMessages($langs->trans("XLineFailedToBeBinded", $ko), null, 'errors');
5917
                }
5918
                if ($ok) {
5919
                    setEventMessages($langs->trans("XLineSuccessfullyBinded", $ok), null, 'mesgs');
5920
                }
5921
            }
5922
        }
5923
5924
5925
        /*
5926
         * View
5927
         */
5928
5929
        $form = new FormAccounting($db);
5930
5931
// Default AccountingAccount RowId Product / Service
5932
// at this time ACCOUNTING_SERVICE_SOLD_ACCOUNT & ACCOUNTING_PRODUCT_SOLD_ACCOUNT are account number not accountingacount rowid
5933
// so we need to get those the rowid of those default value first
5934
        $accounting = new AccountingAccount($db);
5935
// TODO: we should need to check if result is already exists accountaccount rowid.....
5936
        $aarowid_servbuy = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT'), 1);
5937
        $aarowid_servbuy_intra = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT'), 1);
5938
        $aarowid_servbuy_export = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT'), 1);
5939
        $aarowid_prodbuy = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT'), 1);
5940
        $aarowid_prodbuy_intra = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT'), 1);
5941
        $aarowid_prodbuy_export = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT'), 1);
5942
        $aarowid_servsell = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT'), 1);
5943
        $aarowid_servsell_intra = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT'), 1);
5944
        $aarowid_servsell_export = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT'), 1);
5945
        $aarowid_prodsell = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT'), 1);
5946
        $aarowid_prodsell_intra = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT'), 1);
5947
        $aarowid_prodsell_export = $accounting->fetch(0, getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT'), 1);
5948
5949
        $aacompta_servbuy = getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
5950
        $aacompta_servbuy_intra = getDolGlobalString('ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
5951
        $aacompta_servbuy_export = getDolGlobalString('ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
5952
        $aacompta_prodbuy = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
5953
        $aacompta_prodbuy_intra = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
5954
        $aacompta_prodbuy_export = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
5955
        $aacompta_servsell = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
5956
        $aacompta_servsell_intra = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
5957
        $aacompta_servsell_export = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
5958
        $aacompta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
5959
        $aacompta_prodsell_intra = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
5960
        $aacompta_prodsell_export = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
5961
5962
5963
        $title = $langs->trans("ProductsBinding");
5964
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
5965
5966
        $paramsCat = '';
5967
        foreach ($searchCategoryProductList as $searchCategoryProduct) {
5968
            $paramsCat .= "&search_category_product_list[]=" . urlencode($searchCategoryProduct);
5969
        }
5970
5971
        llxHeader('', $title, $help_url, '', 0, 0, [], [], $paramsCat, '');
5972
5973
        $pcgverid = getDolGlobalString('CHARTOFACCOUNTS');
5974
        $pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version');
5975
        if (empty($pcgvercode)) {
5976
            $pcgvercode = $pcgverid;
5977
        }
5978
5979
        $sql = "SELECT p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.tva_tx,";
5980
        if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
5981
            $sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export,";
5982
            $sql .= " ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export,";
5983
        } else {
5984
            $sql .= " p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export,";
5985
            $sql .= " p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export,";
5986
        }
5987
        $sql .= " p.tms, p.fk_product_type as product_type,";
5988
        $sql .= " aa.rowid as aaid";
5989
        $sql .= " FROM " . MAIN_DB_PREFIX . "product as p";
5990
        if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
5991
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
5992
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.account_number = ppe." . $db->sanitize($accountancy_field_name) . " AND aa.fk_pcg_version = '" . $db->escape($pcgvercode) . "'";
5993
        } else {
5994
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.account_number = p." . $db->sanitize($accountancy_field_name) . " AND aa.fk_pcg_version = '" . $db->escape($pcgvercode) . "'";
5995
        }
5996
        if (!empty($searchCategoryProductList)) {
5997
            $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . "categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ
5998
        }
5999
        $sql .= ' WHERE p.entity IN (' . getEntity('product') . ')';
6000
        if (strlen(trim($search_current_account))) {
6001
            $sql .= natural_search((!getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED') ? "p." : "ppe.") . $db->sanitize($accountancy_field_name), $search_current_account);
6002
        }
6003
        if ($search_current_account_valid == 'withoutvalidaccount') {
6004
            $sql .= " AND aa.account_number IS NULL";
6005
        }
6006
        if ($search_current_account_valid == 'withvalidaccount') {
6007
            $sql .= " AND aa.account_number IS NOT NULL";
6008
        }
6009
        $searchCategoryProductSqlList = [];
6010
        if ($searchCategoryProductOperator == 1) {
6011
            foreach ($searchCategoryProductList as $searchCategoryProduct) {
6012
                if (intval($searchCategoryProduct) == -2) {
6013
                    $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL";
6014
                } elseif (intval($searchCategoryProduct) > 0) {
6015
                    $searchCategoryProductSqlList[] = "cp.fk_categorie = " . ((int) $searchCategoryProduct);
6016
                }
6017
            }
6018
            if (!empty($searchCategoryProductSqlList)) {
6019
                $sql .= " AND (" . implode(' OR ', $searchCategoryProductSqlList) . ")";
6020
            }
6021
        } else {
6022
            foreach ($searchCategoryProductList as $searchCategoryProduct) {
6023
                if (intval($searchCategoryProduct) == -2) {
6024
                    $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL";
6025
                } elseif (intval($searchCategoryProduct) > 0) {
6026
                    $searchCategoryProductSqlList[] = "p.rowid IN (SELECT fk_product FROM " . MAIN_DB_PREFIX . "categorie_product WHERE fk_categorie = " . ((int) $searchCategoryProduct) . ")";
6027
                }
6028
            }
6029
            if (!empty($searchCategoryProductSqlList)) {
6030
                $sql .= " AND (" . implode(' AND ', $searchCategoryProductSqlList) . ")";
6031
            }
6032
        }
6033
// Add search filter like
6034
        if (strlen(trim($search_ref))) {
6035
            $sql .= natural_search("p.ref", $search_ref);
6036
        }
6037
        if (strlen(trim($search_label))) {
6038
            $sql .= natural_search("p.label", $search_label);
6039
        }
6040
        if (strlen(trim($search_desc))) {
6041
            $sql .= natural_search("p.description", $search_desc);
6042
        }
6043
        if (strlen(trim($search_vat))) {
6044
            $sql .= natural_search("p.tva_tx", price2num($search_vat), 1);
6045
        }
6046
        if ($search_onsell != '' && $search_onsell != '-1') {
6047
            $sql .= natural_search('p.tosell', $search_onsell, 1);
6048
        }
6049
        if ($search_onpurchase != '' && $search_onpurchase != '-1') {
6050
            $sql .= natural_search('p.tobuy', $search_onpurchase, 1);
6051
        }
6052
6053
        $sql .= " GROUP BY p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.tva_tx,";
6054
        $sql .= " p.fk_product_type,";
6055
        $sql .= ' p.tms,';
6056
        $sql .= ' aa.rowid,';
6057
        if (!getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
6058
            $sql .= " p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export";
6059
        } else {
6060
            $sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export, ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export";
6061
        }
6062
6063
        $sql .= $db->order($sortfield, $sortorder);
6064
6065
        $nbtotalofrecords = '';
6066
        if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
6067
            $resql = $db->query($sql);
6068
            $nbtotalofrecords = $db->num_rows($resql);
6069
            if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
6070
                $page = 0;
6071
                $offset = 0;
6072
            }
6073
        }
6074
6075
        $sql .= $db->plimit($limit + 1, $offset);
6076
6077
        dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG);
6078
        $resql = $db->query($sql);
6079
        if ($resql) {
6080
            $num = $db->num_rows($resql);
6081
            $i = 0;
6082
6083
            $param = '';
6084
            if (!empty($contextpage) && $contextpage != $_SERVER['PHP_SELF']) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $contextpage seems to never exist and therefore empty should always be true.
Loading history...
6085
                $param .= '&contextpage=' . urlencode($contextpage);
6086
            }
6087
            if ($limit > 0 && $limit != $conf->liste_limit) {
6088
                $param .= '&limit=' . ((int) $limit);
6089
            }
6090
            if ($searchCategoryProductOperator == 1) {
6091
                $param .= "&search_category_product_operator=" . urlencode((string) ($searchCategoryProductOperator));
6092
            }
6093
            foreach ($searchCategoryProductList as $searchCategoryProduct) {
6094
                $param .= "&search_category_product_list[]=" . urlencode($searchCategoryProduct);
6095
            }
6096
            if ($search_ref > 0) {
6097
                $param .= "&search_ref=" . urlencode($search_ref);
6098
            }
6099
            if ($search_label > 0) {
6100
                $param .= "&search_label=" . urlencode($search_label);
6101
            }
6102
            if ($search_desc > 0) {
6103
                $param .= "&search_desc=" . urlencode($search_desc);
6104
            }
6105
            if ($search_vat > 0) {
6106
                $param .= '&search_vat=' . urlencode($search_vat);
6107
            }
6108
            if ($search_current_account > 0) {
6109
                $param .= "&search_current_account=" . urlencode($search_current_account);
6110
            }
6111
            if ($search_current_account_valid && $search_current_account_valid != '-1') {
6112
                $param .= "&search_current_account_valid=" . urlencode($search_current_account_valid);
6113
            }
6114
            if ($accounting_product_mode) {
6115
                $param .= '&accounting_product_mode=' . urlencode($accounting_product_mode);
6116
            }
6117
6118
            print '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">';
6119
            if ($optioncss != '') {
6120
                print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
6121
            }
6122
            print '<input type="hidden" name="token" value="' . newToken() . '">';
6123
            print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
6124
            print '<input type="hidden" name="action" value="update">';
6125
            print '<input type="hidden" name="sortfield" value="' . $sortfield . '">';
6126
            print '<input type="hidden" name="sortorder" value="' . $sortorder . '">';
6127
6128
            print load_fiche_titre($langs->trans("ProductsBinding"), '', 'title_accountancy');
6129
            print '<br>';
6130
6131
            print '<span class="opacitymedium">' . $langs->trans("InitAccountancyDesc") . '</span><br>';
6132
            print '<br>';
6133
6134
            // Select mode
6135
            print '<table class="noborder centpercent">';
6136
            print '<tr class="liste_titre">';
6137
            print '<td>' . $langs->trans('Options') . '</td><td>' . $langs->trans('Description') . '</td>';
6138
            print "</tr>\n";
6139
            print '<tr class="oddeven"><td><input type="radio" id="accounting_product_mode1" name="accounting_product_mode" value="ACCOUNTANCY_SELL"' . ($accounting_product_mode == 'ACCOUNTANCY_SELL' ? ' checked' : '') . '> <label for="accounting_product_mode1">' . $langs->trans('OptionModeProductSell') . '</label></td>';
6140
            print '<td>' . $langs->trans('OptionModeProductSellDesc');
6141
            print "</td></tr>\n";
6142
            if ($mysoc->isInEEC()) {
6143
                print '<tr class="oddeven"><td><input type="radio" id="accounting_product_mode2" name="accounting_product_mode" value="ACCOUNTANCY_SELL_INTRA"' . ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' ? ' checked' : '') . '> <label for="accounting_product_mode2">' . $langs->trans('OptionModeProductSellIntra') . '</label></td>';
6144
                print '<td>' . $langs->trans('OptionModeProductSellIntraDesc');
6145
                print "</td></tr>\n";
6146
            }
6147
            print '<tr class="oddeven"><td><input type="radio" id="accounting_product_mode3" name="accounting_product_mode" value="ACCOUNTANCY_SELL_EXPORT"' . ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT' ? ' checked' : '') . '> <label for="accounting_product_mode3">' . $langs->trans('OptionModeProductSellExport') . '</label></td>';
6148
            print '<td>' . $langs->trans('OptionModeProductSellExportDesc');
6149
            print "</td></tr>\n";
6150
            print '<tr class="oddeven"><td><input type="radio" id="accounting_product_mode4" name="accounting_product_mode" value="ACCOUNTANCY_BUY"' . ($accounting_product_mode == 'ACCOUNTANCY_BUY' ? ' checked' : '') . '> <label for="accounting_product_mode4">' . $langs->trans('OptionModeProductBuy') . '</label></td>';
6151
            print '<td>' . $langs->trans('OptionModeProductBuyDesc') . "</td></tr>\n";
6152
            if ($mysoc->isInEEC()) {
6153
                print '<tr class="oddeven"><td><input type="radio" id="accounting_product_mode5" name="accounting_product_mode" value="ACCOUNTANCY_BUY_INTRA"' . ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA' ? ' checked' : '') . '> <label for="accounting_product_mode5">' . $langs->trans('OptionModeProductBuyIntra') . '</label></td>';
6154
                print '<td>' . $langs->trans('OptionModeProductBuyDesc') . "</td></tr>\n";
6155
            }
6156
            print '<tr class="oddeven"><td><input type="radio" id="accounting_product_mode6" name="accounting_product_mode" value="ACCOUNTANCY_BUY_EXPORT"' . ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT' ? ' checked' : '') . '> <label for="accounting_product_mode6">' . $langs->trans('OptionModeProductBuyExport') . '</label></td>';
6157
            print '<td>' . $langs->trans('OptionModeProductBuyDesc') . "</td></tr>\n";
6158
            print "</table>\n";
6159
6160
            print '<div class="center"><input type="submit" class="button" value="' . $langs->trans('Refresh') . '" name="changetype"></div>';
6161
6162
            print "<br>\n";
6163
6164
6165
            // Filter on categories
6166
            $moreforfilter = '';
6167
            $varpage = empty($contextpage) ? $_SERVER['PHP_SELF'] : $contextpage;
6168
            $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
6169
6170
            if ($massaction !== 'set_default_account') {
6171
                $arrayofmassactions = [
6172
                    'changeaccount' => img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans("Save")
6173
                    , 'set_default_account' => img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans("ConfirmPreselectAccount"),
6174
                ];
6175
                $massactionbutton = $form->selectMassAction('', $arrayofmassactions, 1);
6176
            }
6177
6178
            $buttonsave = '<input type="submit" class="button button-save" id="changeaccount" name="changeaccount" value="' . $langs->trans("Save") . '">';
6179
            //print '<br><div class="center">'.$buttonsave.'</div>';
6180
6181
            $texte = $langs->trans("ListOfProductsServices");
6182
            print_barre_liste($texte, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, '', '', $limit, 0, 0, 1);
6183
6184
            if ($massaction == 'set_default_account') {
6185
                $formquestion = [];
6186
                $formquestion[] = [
6187
                    'type' => 'other',
6188
                    'name' => 'set_default_account',
6189
                    'label' => $langs->trans("AccountancyCode"),
6190
                    'value' => $form->select_account('', 'default_account', 1, [], 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'),
6191
                ];
6192
                print $form->formconfirm($_SERVER['PHP_SELF'], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($chk_prod)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1);
6193
            }
6194
6195
            // Filter on categories
6196
            $moreforfilter = '';
6197
            if (isModEnabled('category') && $user->hasRight('categorie', 'lire')) {
6198
                $formcategory = new FormCategory($db);
6199
                $moreforfilter .= $formcategory->getFilterBox(Categorie::TYPE_PRODUCT, $searchCategoryProductList, 'minwidth300', $searchCategoryProductList ? $searchCategoryProductList : 0);
6200
                /*
6201
                $moreforfilter .= '<div class="divsearchfield">';
6202
                $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"');
6203
                $categoriesProductArr = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', '', 64, 0, 1);
6204
                $categoriesProductArr[-2] = '- '.$langs->trans('NotCategorized').' -';
6205
                $moreforfilter .= Form::multiselectarray('search_category_product_list', $categoriesProductArr, $searchCategoryProductList, 0, 0, 'minwidth300');
6206
                $moreforfilter .= ' <input type="checkbox" class="valignmiddle" id="search_category_product_operator" name="search_category_product_operator" value="1"'.($searchCategoryProductOperator == 1 ? ' checked="checked"' : '').'/> <label for="search_category_product_operator"><span class="none">'.$langs->trans('UseOrOperatorForCategories').'</span></label>';
6207
                $moreforfilter .= '</div>';
6208
                */
6209
            }
6210
6211
            // Show/hide child products. Hidden by default
6212
            if (isModEnabled('variants') && getDolGlobalInt('PRODUIT_ATTRIBUTES_HIDECHILD')) {
6213
                $moreforfilter .= '<div class="divsearchfield">';
6214
                $moreforfilter .= '<input type="checkbox" id="search_show_childproducts" name="search_show_childproducts"' . ($show_childproducts ? 'checked="checked"' : '') . '>';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $show_childproducts seems to be never defined.
Loading history...
6215
                $moreforfilter .= ' <label for="search_show_childproducts">' . $langs->trans('ShowChildProducts') . '</label>';
6216
                $moreforfilter .= '</div>';
6217
            }
6218
6219
            $parameters = [];
6220
            $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
6221
            if (empty($reshook)) {
6222
                $moreforfilter .= $hookmanager->resPrint;
6223
            } else {
6224
                $moreforfilter = $hookmanager->resPrint;
6225
            }
6226
6227
            if ($moreforfilter) {
6228
                print '<div class="liste_titre liste_titre_bydiv centpercent">';
6229
                print $moreforfilter;
6230
                print '</div>';
6231
            }
6232
6233
            print '<div class="div-table-responsive">';
6234
            print '<table class="liste ' . ($moreforfilter ? "listwithfilterbefore" : "") . '">';
6235
6236
            print '<tr class="liste_titre_filter">';
6237
            // Action column
6238
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6239
                print '<td class="center liste_titre">';
6240
                $searchpicto = $form->showFilterButtons();
6241
                print $searchpicto;
6242
                print '</td>';
6243
            }
6244
            print '<td class="liste_titre"><input type="text" class="flat" size="8" name="search_ref" value="' . dol_escape_htmltag($search_ref) . '"></td>';
6245
            print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
6246
            print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_vat" placeholder="%" value="' . dol_escape_htmltag($search_vat) . '"></td>';
6247
6248
            if (getDolGlobalInt('ACCOUNTANCY_SHOW_PROD_DESC')) {
6249
                print '<td class="liste_titre"><input type="text" class="flat" size="20" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
6250
            }
6251
            // On sell
6252
            if ($accounting_product_mode == 'ACCOUNTANCY_SELL' || $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' || $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
6253
                print '<td class="liste_titre center">' . $form->selectyesno('search_onsell', $search_onsell, 1, false, 1) . '</td>';
6254
            } else {
6255
                // On buy
6256
                print '<td class="liste_titre center">' . $form->selectyesno('search_onpurchase', $search_onpurchase, 1, false, 1) . '</td>';
6257
            }
6258
            // Current account
6259
            print '<td class="liste_titre">';
6260
            print '<input type="text" class="flat" size="6" name="search_current_account" id="search_current_account" value="' . dol_escape_htmltag($search_current_account) . '">';
6261
            $listofvals = ['withoutvalidaccount' => $langs->trans("WithoutValidAccount"), 'withvalidaccount' => $langs->trans("WithValidAccount")];
6262
            print ' ' . $langs->trans("or") . ' ' . $form->selectarray('search_current_account_valid', $listofvals, $search_current_account_valid, 1);
6263
            print '</td>';
6264
            print '<td class="liste_titre">&nbsp;</td>';
6265
            // Action column
6266
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6267
                print '<td class="center liste_titre">';
6268
                $searchpicto = $form->showFilterButtons();
6269
                print $searchpicto;
6270
                print '</td>';
6271
            }
6272
            print '</tr>';
6273
6274
            print '<tr class="liste_titre">';
6275
            // Action column
6276
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6277
                $clickpitco = $form->showCheckAddButtons('checkforselect', 1);
6278
                print_liste_field_titre($clickpitco, '', '', '', '', '', '', '', 'center ');
6279
            }
6280
            print_liste_field_titre("Ref", $_SERVER['PHP_SELF'], "p.ref", "", $param, '', $sortfield, $sortorder);
6281
            print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "p.label", "", $param, '', $sortfield, $sortorder);
6282
            if (getDolGlobalInt('ACCOUNTANCY_SHOW_PROD_DESC')) {
6283
                print_liste_field_titre("Description", $_SERVER['PHP_SELF'], "p.description", "", $param, '', $sortfield, $sortorder);
6284
            }
6285
            print_liste_field_titre("VATRate", $_SERVER['PHP_SELF'], "p.tva_tx", "", $param, '', $sortfield, $sortorder, 'right ');
6286
            // On sell / On purchase
6287
            if ($accounting_product_mode == 'ACCOUNTANCY_SELL' || $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' || $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
6288
                print_liste_field_titre("OnSell", $_SERVER['PHP_SELF'], "p.tosell", "", $param, '', $sortfield, $sortorder, 'center ');
6289
            } else {
6290
                print_liste_field_titre("OnBuy", $_SERVER['PHP_SELF'], "p.tobuy", "", $param, '', $sortfield, $sortorder, 'center ');
6291
            }
6292
            print_liste_field_titre("CurrentDedicatedAccountingAccount", $_SERVER['PHP_SELF'], (!getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED') ? "p." : "ppe.") . $accountancy_field_name, "", $param, '', $sortfield, $sortorder);
6293
            print_liste_field_titre("AssignDedicatedAccountingAccount");
6294
            // Action column
6295
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6296
                $clickpitco = $form->showCheckAddButtons('checkforselect', 1);
6297
                print_liste_field_titre($clickpitco, '', '', '', '', '', '', '', 'center ');
6298
            }
6299
            print '</tr>';
6300
6301
            $product_static = new Product($db);
6302
6303
            $i = 0;
6304
            while ($i < min($num, $limit)) {
6305
                $obj = $db->fetch_object($resql);
6306
6307
                // Ref produit as link
6308
                $product_static->ref = $obj->ref;
6309
                $product_static->id = $obj->rowid;
6310
                $product_static->type = $obj->product_type;
6311
                $product_static->label = $obj->label;
6312
                $product_static->description = $obj->description;
6313
                $product_static->status = $obj->tosell;
6314
                $product_static->status_buy = $obj->tobuy;
6315
6316
                // Sales
6317
                if ($obj->product_type == 0) {
6318
                    if ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
6319
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
6320
                        $compta_prodsell_id = $aarowid_prodsell;
6321
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
6322
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
6323
                        $compta_prodsell_id = $aarowid_prodsell_intra;
6324
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
6325
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
6326
                        $compta_prodsell_id = $aarowid_prodsell_export;
6327
                    } else {
6328
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
6329
                        $compta_prodsell_id = $aarowid_prodsell;
6330
                    }
6331
                } else {
6332
                    if ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
6333
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
6334
                        $compta_prodsell_id = $aarowid_servsell;
6335
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
6336
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
6337
                        $compta_prodsell_id = $aarowid_servsell_intra;
6338
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
6339
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
6340
6341
                        $compta_prodsell_id = $aarowid_servsell_export;
6342
                    } else {
6343
                        $compta_prodsell = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
6344
                        $compta_prodsell_id = $aarowid_servsell;
6345
                    }
6346
                }
6347
6348
                // Purchases
6349
                if ($obj->product_type == 0) {
6350
                    if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
6351
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
6352
                        $compta_prodbuy_id = $aarowid_prodbuy;
6353
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') {
6354
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
6355
                        $compta_prodbuy_id = $aarowid_prodbuy_intra;
6356
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') {
6357
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
6358
                        $compta_prodbuy_id = $aarowid_prodbuy_export;
6359
                    } else {
6360
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
6361
                        $compta_prodbuy_id = $aarowid_prodbuy;
6362
                    }
6363
                } else {
6364
                    if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
6365
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
6366
                        $compta_prodbuy_id = $aarowid_servbuy;
6367
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') {
6368
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
6369
                        $compta_prodbuy_id = $aarowid_servbuy_intra;
6370
                    } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') {
6371
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
6372
                        $compta_prodbuy_id = $aarowid_servbuy_export;
6373
                    } else {
6374
                        $compta_prodbuy = getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
6375
                        $compta_prodbuy_id = $aarowid_servbuy;
6376
                    }
6377
                }
6378
6379
                $selected = 0;
6380
                if (!empty($chk_prod)) {
6381
                    if (in_array($product_static->id, $chk_prod)) {
6382
                        $selected = 1;
6383
                    }
6384
                }
6385
6386
                print '<tr class="oddeven">';
6387
6388
                // Action column
6389
                if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6390
                    print '<td class="center">';
6391
                    print '<input type="checkbox" class="checkforselect productforselectcodeventil_' . $product_static->id . '" name="chk_prod[]" ' . ($selected ? "checked" : "") . ' value="' . $obj->rowid . '"/>';
6392
                    print '</td>';
6393
                }
6394
6395
                print '<td>';
6396
                print $product_static->getNomUrl(1);
6397
                print '</td>';
6398
6399
                print '<td class="left">' . $obj->label . '</td>';
6400
6401
                if (getDolGlobalInt('ACCOUNTANCY_SHOW_PROD_DESC')) {
6402
                    // TODO ADJUST DESCRIPTION SIZE
6403
                    // print '<td class="left">' . $obj->description . '</td>';
6404
                    // TODO: we should set a user defined value to adjust user square / wide screen size
6405
                    $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION', 32);
6406
                    print '<td>' . nl2br(dol_trunc($obj->description, $trunclength)) . '</td>';
6407
                }
6408
6409
                // VAT
6410
                print '<td class="right">';
6411
                print vatrate($obj->tva_tx);
6412
                print '</td>';
6413
6414
                // On sell / On purchase
6415
                if ($accounting_product_mode == 'ACCOUNTANCY_SELL' || $accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA' || $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT') {
6416
                    print '<td class="center">' . $product_static->getLibStatut(3, 0) . '</td>';
6417
                } else {
6418
                    print '<td class="center">' . $product_static->getLibStatut(3, 1) . '</td>';
6419
                }
6420
6421
                // Current accounting account
6422
                print '<td class="left">';
6423
                if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
6424
                    print length_accountg($obj->accountancy_code_buy);
6425
                    if ($obj->accountancy_code_buy && empty($obj->aaid)) {
6426
                        print ' ' . img_warning($langs->trans("ValueNotIntoChartOfAccount"));
6427
                    }
6428
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') {
6429
                    print length_accountg($obj->accountancy_code_buy_intra);
6430
                    if ($obj->accountancy_code_buy_intra && empty($obj->aaid)) {
6431
                        print ' ' . img_warning($langs->trans("ValueNotIntoChartOfAccount"));
6432
                    }
6433
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') {
6434
                    print length_accountg($obj->accountancy_code_buy_export);
6435
                    if ($obj->accountancy_code_buy_export && empty($obj->aaid)) {
6436
                        print ' ' . img_warning($langs->trans("ValueNotIntoChartOfAccount"));
6437
                    }
6438
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
6439
                    print length_accountg($obj->accountancy_code_sell);
6440
                    if ($obj->accountancy_code_sell && empty($obj->aaid)) {
6441
                        print ' ' . img_warning($langs->trans("ValueNotIntoChartOfAccount"));
6442
                    }
6443
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
6444
                    print length_accountg($obj->accountancy_code_sell_intra);
6445
                    if ($obj->accountancy_code_sell_intra && empty($obj->aaid)) {
6446
                        print ' ' . img_warning($langs->trans("ValueNotIntoChartOfAccount"));
6447
                    }
6448
                } else {
6449
                    print length_accountg($obj->accountancy_code_sell_export);
6450
                    if ($obj->accountancy_code_sell_export && empty($obj->aaid)) {
6451
                        print ' ' . img_warning($langs->trans("ValueNotIntoChartOfAccount"));
6452
                    }
6453
                }
6454
                print '</td>';
6455
6456
                // New account to set
6457
                $defaultvalue = '';
6458
                if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
6459
                    // Accounting account buy
6460
                    print '<td class="left">';
6461
                    //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
6462
                    if (empty($defaultvalue)) {
6463
                        $defaultvalue = $compta_prodbuy;
6464
                    }
6465
                    $codesell = length_accountg($obj->accountancy_code_buy);
6466
                    if (!empty($obj->aaid)) {
6467
                        $defaultvalue = ''; // Do not suggest default new value is code is already valid
6468
                    }
6469
                    print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_' . $product_static->id, 1, [], 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
6470
                    print '</td>';
6471
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') {
6472
                    // Accounting account buy intra (In EEC)
6473
                    print '<td class="left">';
6474
                    //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
6475
                    if (empty($defaultvalue)) {
6476
                        $defaultvalue = $compta_prodbuy;
6477
                    }
6478
                    $codesell = length_accountg($obj->accountancy_code_buy_intra);
6479
                    //var_dump($defaultvalue.' - '.$codesell.' - '.$compta_prodsell);
6480
                    if (!empty($obj->aaid)) {
6481
                        $defaultvalue = ''; // Do not suggest default new value is code is already valid
6482
                    }
6483
                    print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_' . $product_static->id, 1, [], 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
6484
                    print '</td>';
6485
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') {
6486
                    // Accounting account buy export (Out of EEC)
6487
                    print '<td class="left">';
6488
                    //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
6489
                    if (empty($defaultvalue)) {
6490
                        $defaultvalue = $compta_prodbuy;
6491
                    }
6492
                    $codesell = length_accountg($obj->accountancy_code_buy_export);
6493
                    //var_dump($defaultvalue.' - '.$codesell.' - '.$compta_prodsell);
6494
                    if (!empty($obj->aaid)) {
6495
                        $defaultvalue = ''; // Do not suggest default new value is code is already valid
6496
                    }
6497
                    print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_' . $product_static->id, 1, [], 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
6498
                    print '</td>';
6499
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
6500
                    // Accounting account sell
6501
                    print '<td class="left">';
6502
                    //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
6503
                    if (empty($defaultvalue)) {
6504
                        $defaultvalue = $compta_prodsell;
6505
                    }
6506
                    $codesell = length_accountg($obj->accountancy_code_sell);
6507
                    //var_dump($defaultvalue.' - '.$codesell.' - '.$compta_prodsell);
6508
                    if (!empty($obj->aaid)) {
6509
                        $defaultvalue = ''; // Do not suggest default new value is code is already valid
6510
                    }
6511
                    print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_' . $product_static->id, 1, [], 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
6512
                    print '</td>';
6513
                } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
6514
                    // Accounting account sell intra (In EEC)
6515
                    print '<td class="left">';
6516
                    //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
6517
                    if (empty($defaultvalue)) {
6518
                        $defaultvalue = $compta_prodsell;
6519
                    }
6520
                    $codesell = length_accountg($obj->accountancy_code_sell_intra);
6521
                    //var_dump($defaultvalue.' - '.$codesell.' - '.$compta_prodsell);
6522
                    if (!empty($obj->aaid)) {
6523
                        $defaultvalue = ''; // Do not suggest default new value is code is already valid
6524
                    }
6525
                    print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_' . $product_static->id, 1, [], 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
6526
                    print '</td>';
6527
                } else {
6528
                    // Accounting account sell export (Out of EEC)
6529
                    print '<td class="left">';
6530
                    //$defaultvalue=GETPOST('codeventil_' . $product_static->id,'alpha');        This is id and we need a code
6531
                    if (empty($defaultvalue)) {
6532
                        $defaultvalue = $compta_prodsell;
6533
                    }
6534
                    $codesell = length_accountg($obj->accountancy_code_sell_export);
6535
                    if (!empty($obj->aaid)) {
6536
                        $defaultvalue = ''; // Do not suggest default new value is code is already valid
6537
                    }
6538
                    print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_' . $product_static->id, 1, [], 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
6539
                    print '</td>';
6540
                }
6541
6542
                // Action column
6543
                if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6544
                    print '<td class="center">';
6545
                    print '<input type="checkbox" class="checkforselect productforselectcodeventil_' . $product_static->id . '" name="chk_prod[]" ' . ($selected ? "checked" : "") . ' value="' . $obj->rowid . '"/>';
6546
                    print '</td>';
6547
                }
6548
6549
                print "</tr>";
6550
                $i++;
6551
            }
6552
            print '</table>';
6553
            print '</div>';
6554
6555
            print '<script type="text/javascript">
6556
        jQuery(document).ready(function() {
6557
        	function init_savebutton()
6558
        	{
6559
	            console.log("We check if at least one line is checked")
6560
6561
    			atleastoneselected=0;
6562
	    		jQuery(".checkforselect").each(function( index ) {
6563
	  				/* console.log( index + ": " + $( this ).text() ); */
6564
	  				if ($(this).is(\':checked\')) atleastoneselected++;
6565
	  			});
6566
6567
	            if (atleastoneselected) jQuery("#changeaccount").removeAttr(\'disabled\');
6568
	            else jQuery("#changeaccount").attr(\'disabled\',\'disabled\');
6569
	            if (atleastoneselected) jQuery("#changeaccount").attr(\'class\',\'button\');
6570
	            else jQuery("#changeaccount").attr(\'class\',\'button\');
6571
        	}
6572
6573
        	jQuery(".checkforselect").change(function() {
6574
        		init_savebutton();
6575
        	});
6576
        	jQuery(".productforselect").change(function() {
6577
				console.log($(this).attr("id")+" "+$(this).val());
6578
				if ($(this).val() && $(this).val() != -1) {
6579
					$(".productforselect"+$(this).attr("id")).prop(\'checked\', true);
6580
				} else {
6581
					$(".productforselect"+$(this).attr("id")).prop(\'checked\', false);
6582
				}
6583
        		init_savebutton();
6584
        	});
6585
6586
        	init_savebutton();
6587
6588
            jQuery("#search_current_account").keyup(function() {
6589
        		if (jQuery("#search_current_account").val() != \'\')
6590
                {
6591
                    console.log("We set a value of account to search "+jQuery("#search_current_account").val()+", so we disable the other search criteria on account");
6592
                    jQuery("#search_current_account_valid").val(-1);
6593
                }
6594
        	});
6595
        });
6596
        </script>';
6597
6598
            print '</form>';
6599
6600
            $db->free($resql);
6601
        } else {
6602
            dol_print_error($db);
6603
        }
6604
6605
// End of page
6606
        llxFooter();
6607
        $db->close();
6608
    }
6609
6610
    /**
6611
     * \file        htdocs/accountancy/admin/subaccount.php
6612
     * \ingroup     Accountancy (Double entries)
6613
     * \brief       List of accounting sub-account (auxiliary accounts)
6614
     */
6615
    public function subaccount()
6616
    {
6617
        global $conf;
6618
        global $db;
6619
        global $user;
6620
        global $hookmanager;
6621
        global $user;
6622
        global $menumanager;
6623
        global $langs;
6624
6625
// Load translation files required by the page
6626
        $langs->loadLangs(["accountancy", "admin", "bills", "compta", "errors", "hrm", "salaries"]);
6627
6628
        $mesg = '';
6629
        $action = GETPOST('action', 'aZ09');
6630
        $cancel = GETPOST('cancel', 'alpha');
6631
        $id = GETPOSTINT('id');
6632
        $rowid = GETPOSTINT('rowid');
6633
        $massaction = GETPOST('massaction', 'aZ09');
6634
        $optioncss = GETPOST('optioncss', 'alpha');
6635
        $mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
6636
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'accountingsubaccountlist'; // To manage different context of search
6637
6638
        $search_subaccount = GETPOST('search_subaccount', 'alpha');
6639
        $search_label = GETPOST('search_label', 'alpha');
6640
        $search_type = GETPOSTINT('search_type');
6641
6642
// Security check
6643
        if ($user->socid > 0) {
6644
            accessforbidden();
6645
        }
6646
        if (!$user->hasRight('accounting', 'chartofaccount')) {
6647
            accessforbidden();
6648
        }
6649
6650
// Load variable for pagination
6651
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
6652
        $sortfield = GETPOST('sortfield', 'aZ09comma');
6653
        $sortorder = GETPOST('sortorder', 'aZ09comma');
6654
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
6655
        if (empty($page) || $page == -1) {
6656
            $page = 0;
6657
        }     // If $page is not defined, or '' or -1
6658
        $offset = $limit * $page;
6659
        $pageprev = $page - 1;
6660
        $pagenext = $page + 1;
6661
        if (!$sortfield) {
6662
            $sortfield = "label";
6663
        }
6664
        if (!$sortorder) {
6665
            $sortorder = "ASC";
6666
        }
6667
6668
        $arrayfields = [
6669
            'subaccount' => ['label' => $langs->trans("AccountNumber"), 'checked' => 1],
6670
            'label' => ['label' => $langs->trans("Label"), 'checked' => 1],
6671
            'type' => ['label' => $langs->trans("Type"), 'checked' => 1],
6672
            'reconcilable' => ['label' => $langs->trans("Reconcilable"), 'checked' => 1],
6673
        ];
6674
6675
        if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
6676
            unset($arrayfields['reconcilable']);
6677
        }
6678
6679
6680
        /*
6681
         * Actions
6682
         */
6683
6684
        if (GETPOST('cancel', 'alpha')) {
6685
            $action = 'list';
6686
            $massaction = '';
6687
        }
6688
        if (!GETPOST('confirmmassaction', 'alpha')) {
6689
            $massaction = '';
6690
        }
6691
6692
        $parameters = [];
6693
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $object seems to be never defined.
Loading history...
6694
        if ($reshook < 0) {
6695
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
6696
        }
6697
6698
        if (empty($reshook)) {
6699
            if (!empty($cancel)) {
6700
                $action = '';
6701
            }
6702
6703
            include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php';
6704
6705
            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
6706
                $search_subaccount = "";
6707
                $search_label = "";
6708
                $search_type = "";
6709
                $search_array_options = [];
6710
            }
6711
        }
6712
6713
6714
        /*
6715
         * View
6716
         */
6717
6718
        $form = new Form($db);
6719
6720
6721
// Page Header
6722
        $help_url = 'EN:Module_Double_Entry_Accounting#Setup|FR:Module_Comptabilit&eacute;_en_Partie_Double#Configuration';
6723
        $title = $langs->trans('ChartOfIndividualAccountsOfSubsidiaryLedger');
6724
        llxHeader('', $title, $help_url);
6725
6726
6727
// Customer
6728
        $sql = "SELECT sa.rowid, sa.nom as label, sa.code_compta as subaccount, '1' as type, sa.entity, sa.client as nature";
6729
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe sa";
6730
        $sql .= " WHERE sa.entity IN (" . getEntity('societe') . ")";
6731
        $sql .= " AND sa.code_compta <> ''";
6732
//print $sql;
6733
        if (strlen(trim($search_subaccount))) {
6734
            $lengthpaddingaccount = 0;
6735
            if (getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT')) {
6736
                $lengthpaddingaccount = getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT');
6737
            }
6738
            $search_subaccount_tmp = $search_subaccount;
6739
            $weremovedsomezero = 0;
6740
            if (strlen($search_subaccount_tmp) <= $lengthpaddingaccount) {
6741
                for ($i = 0; $i < $lengthpaddingaccount; $i++) {
6742
                    if (preg_match('/0$/', $search_subaccount_tmp)) {
6743
                        $weremovedsomezero++;
6744
                        $search_subaccount_tmp = preg_replace('/0$/', '', $search_subaccount_tmp);
6745
                    }
6746
                }
6747
            }
6748
6749
            //var_dump($search_subaccount); exit;
6750
            if ($search_subaccount_tmp) {
6751
                if ($weremovedsomezero) {
6752
                    $search_subaccount_tmp_clean = $search_subaccount_tmp;
6753
                    $search_subaccount_clean = $search_subaccount;
6754
                    $startchar = '%';
6755
                    if (strpos($search_subaccount_tmp, '^') === 0) {
6756
                        $startchar = '';
6757
                        $search_subaccount_tmp_clean = preg_replace('/^\^/', '', $search_subaccount_tmp);
6758
                        $search_subaccount_clean = preg_replace('/^\^/', '', $search_subaccount);
6759
                    }
6760
                    $sql .= " AND (sa.code_compta LIKE '" . $db->escape($startchar . $search_subaccount_tmp_clean) . "'";
6761
                    $sql .= " OR sa.code_compta LIKE '" . $db->escape($startchar . $search_subaccount_clean) . "%')";
6762
                } else {
6763
                    $sql .= natural_search("sa.code_compta", $search_subaccount_tmp);
6764
                }
6765
            }
6766
        }
6767
        if (strlen(trim($search_label))) {
6768
            $sql .= natural_search("sa.nom", $search_label);
6769
        }
6770
        if (!empty($search_type) && $search_type >= 0) {
6771
            $sql .= " HAVING type LIKE '" . $db->escape($search_type) . "'";
6772
        }
6773
6774
// Supplier
6775
        $sql .= " UNION ";
6776
        $sql .= " SELECT sa.rowid, sa.nom as label, sa.code_compta_fournisseur as subaccount, '2' as type, sa.entity, '0' as nature FROM " . MAIN_DB_PREFIX . "societe sa";
6777
        $sql .= " WHERE sa.entity IN (" . getEntity('societe') . ")";
6778
        $sql .= " AND sa.code_compta_fournisseur <> ''";
6779
//print $sql;
6780
        if (strlen(trim($search_subaccount))) {
6781
            $lengthpaddingaccount = 0;
6782
            if (getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT')) {
6783
                $lengthpaddingaccount = getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT');
6784
            }
6785
            $search_subaccount_tmp = $search_subaccount;
6786
            $weremovedsomezero = 0;
6787
            if (strlen($search_subaccount_tmp) <= $lengthpaddingaccount) {
6788
                for ($i = 0; $i < $lengthpaddingaccount; $i++) {
6789
                    if (preg_match('/0$/', $search_subaccount_tmp)) {
6790
                        $weremovedsomezero++;
6791
                        $search_subaccount_tmp = preg_replace('/0$/', '', $search_subaccount_tmp);
6792
                    }
6793
                }
6794
            }
6795
6796
            //var_dump($search_subaccount); exit;
6797
            if ($search_subaccount_tmp) {
6798
                if ($weremovedsomezero) {
6799
                    $search_subaccount_tmp_clean = $search_subaccount_tmp;
6800
                    $search_subaccount_clean = $search_subaccount;
6801
                    $startchar = '%';
6802
                    if (strpos($search_subaccount_tmp, '^') === 0) {
6803
                        $startchar = '';
6804
                        $search_subaccount_tmp_clean = preg_replace('/^\^/', '', $search_subaccount_tmp);
6805
                        $search_subaccount_clean = preg_replace('/^\^/', '', $search_subaccount);
6806
                    }
6807
                    $sql .= " AND (sa.code_compta_fournisseur LIKE '" . $db->escape($startchar . $search_subaccount_tmp_clean) . "'";
6808
                    $sql .= " OR sa.code_compta_fournisseur LIKE '" . $db->escape($startchar . $search_subaccount_clean) . "%')";
6809
                } else {
6810
                    $sql .= natural_search("sa.code_compta_fournisseur", $search_subaccount_tmp);
6811
                }
6812
            }
6813
        }
6814
        if (strlen(trim($search_label))) {
6815
            $sql .= natural_search("sa.nom", $search_label);
6816
        }
6817
        if (!empty($search_type) && $search_type >= 0) {
6818
            $sql .= " HAVING type LIKE '" . $db->escape($search_type) . "'";
6819
        }
6820
6821
// User - Employee
6822
        $sql .= " UNION ";
6823
        $sql .= " SELECT u.rowid, u.lastname as label, u.accountancy_code as subaccount, '3' as type, u.entity, '0' as nature FROM " . MAIN_DB_PREFIX . "user u";
6824
        $sql .= " WHERE u.entity IN (" . getEntity('user') . ")";
6825
        $sql .= " AND u.accountancy_code <> ''";
6826
//print $sql;
6827
        if (strlen(trim($search_subaccount))) {
6828
            $lengthpaddingaccount = 0;
6829
            if (getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT')) {
6830
                $lengthpaddingaccount = getDolGlobalInt('ACCOUNTING_LENGTH_AACCOUNT');
6831
            }
6832
            $search_subaccount_tmp = $search_subaccount;
6833
            $weremovedsomezero = 0;
6834
            if (strlen($search_subaccount_tmp) <= $lengthpaddingaccount) {
6835
                for ($i = 0; $i < $lengthpaddingaccount; $i++) {
6836
                    if (preg_match('/0$/', $search_subaccount_tmp)) {
6837
                        $weremovedsomezero++;
6838
                        $search_subaccount_tmp = preg_replace('/0$/', '', $search_subaccount_tmp);
6839
                    }
6840
                }
6841
            }
6842
6843
            //var_dump($search_subaccount); exit;
6844
            if ($search_subaccount_tmp) {
6845
                if ($weremovedsomezero) {
6846
                    $search_subaccount_tmp_clean = $search_subaccount_tmp;
6847
                    $search_subaccount_clean = $search_subaccount;
6848
                    $startchar = '%';
6849
                    if (strpos($search_subaccount_tmp, '^') === 0) {
6850
                        $startchar = '';
6851
                        $search_subaccount_tmp_clean = preg_replace('/^\^/', '', $search_subaccount_tmp);
6852
                        $search_subaccount_clean = preg_replace('/^\^/', '', $search_subaccount);
6853
                    }
6854
                    $sql .= " AND (u.accountancy_code LIKE '" . $db->escape($startchar . $search_subaccount_tmp_clean) . "'";
6855
                    $sql .= " OR u.accountancy_code LIKE '" . $db->escape($startchar . $search_subaccount_clean) . "%')";
6856
                } else {
6857
                    $sql .= natural_search("u.accountancy_code", $search_subaccount_tmp);
6858
                }
6859
            }
6860
        }
6861
        if (strlen(trim($search_label))) {
6862
            $sql .= natural_search("u.lastname", $search_label);
6863
        }
6864
        if (!empty($search_type) && $search_type >= 0) {
6865
            $sql .= " HAVING type LIKE '" . $db->escape($search_type) . "'";
6866
        }
6867
6868
        $sql .= $db->order($sortfield, $sortorder);
6869
6870
// Count total nb of records
6871
        $nbtotalofrecords = '';
6872
        if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
6873
            $resql = $db->query($sql);
6874
            $nbtotalofrecords = $db->num_rows($resql);
6875
            if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
6876
                $page = 0;
6877
                $offset = 0;
6878
            }
6879
        }
6880
6881
        $sql .= $db->plimit($limit + 1, $offset);
6882
6883
        dol_syslog('accountancy/admin/subaccount.php:: $sql=' . $sql);
6884
        $resql = $db->query($sql);
6885
6886
        if ($resql) {
6887
            $num = $db->num_rows($resql);
6888
6889
            $param = '';
6890
            if (!empty($contextpage) && $contextpage != $_SERVER['PHP_SELF']) {
6891
                $param .= '&contextpage=' . urlencode($contextpage);
6892
            }
6893
            if ($limit > 0 && $limit != $conf->liste_limit) {
6894
                $param .= '&limit=' . ((int) $limit);
6895
            }
6896
            if ($search_subaccount) {
6897
                $param .= '&search_subaccount=' . urlencode($search_subaccount);
6898
            }
6899
            if ($search_label) {
6900
                $param .= '&search_label=' . urlencode($search_label);
6901
            }
6902
            if ($optioncss != '') {
6903
                $param .= '&optioncss=' . urlencode($optioncss);
6904
            }
6905
6906
            // List of mass actions available
6907
            $arrayofmassactions = [];
6908
6909
            print '<form method="POST" id="searchFormList" action="' . $_SERVER['PHP_SELF'] . '">';
6910
            if ($optioncss != '') {
6911
                print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
6912
            }
6913
            print '<input type="hidden" name="token" value="' . newToken() . '">';
6914
            print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
6915
            print '<input type="hidden" name="action" value="list">';
6916
            print '<input type="hidden" name="sortfield" value="' . $sortfield . '">';
6917
            print '<input type="hidden" name="sortorder" value="' . $sortorder . '">';
6918
            print '<input type="hidden" name="contextpage" value="' . $contextpage . '">';
6919
6920
            print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit, 0, 0, 1);
6921
6922
            print '<div class="info">' . $langs->trans("WarningCreateSubAccounts") . '</div>';
6923
6924
            $varpage = empty($contextpage) ? $_SERVER['PHP_SELF'] : $contextpage;
6925
            $selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) : ''); // This also change content of $arrayfields
6926
            $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
6927
6928
            $moreforfilter = '';
6929
            $massactionbutton = '';
6930
6931
            print '<div class="div-table-responsive">';
6932
            print '<table class="tagtable liste' . ($moreforfilter ? " listwithfilterbefore" : "") . '">' . "\n";
6933
6934
            // Line for search fields
6935
            print '<tr class="liste_titre_filter">';
6936
            // Action column
6937
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6938
                print '<td class="liste_titre center maxwidthsearch">';
6939
                $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
6940
                print $searchpicto;
6941
                print '</td>';
6942
            }
6943
            if (!empty($arrayfields['subaccount']['checked'])) {
6944
                print '<td class="liste_titre"><input type="text" class="flat" size="10" name="search_subaccount" value="' . $search_subaccount . '"></td>';
6945
            }
6946
            if (!empty($arrayfields['label']['checked'])) {
6947
                print '<td class="liste_titre"><input type="text" class="flat" size="20" name="search_label" value="' . $search_label . '"></td>';
6948
            }
6949
            if (!empty($arrayfields['type']['checked'])) {
6950
                print '<td class="liste_titre center">' . $form->selectarray('search_type', ['1' => $langs->trans('Customer'), '2' => $langs->trans('Supplier'), '3' => $langs->trans('Employee')], $search_type, 1) . '</td>';
6951
            }
6952
            if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
6953
                if (!empty($arrayfields['reconcilable']['checked'])) {
6954
                    print '<td class="liste_titre">&nbsp;</td>';
6955
                }
6956
            }
6957
            // Action column
6958
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6959
                print '<td class="liste_titre maxwidthsearch">';
6960
                $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
6961
                print $searchpicto;
6962
                print '</td>';
6963
            }
6964
            print '</tr>';
6965
6966
            print '<tr class="liste_titre">';
6967
            // Action column
6968
            if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6969
                print_liste_field_titre($selectedfields, $_SERVER['PHP_SELF'], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
6970
            }
6971
            if (!empty($arrayfields['subaccount']['checked'])) {
6972
                print_liste_field_titre($arrayfields['subaccount']['label'], $_SERVER['PHP_SELF'], "subaccount", "", $param, '', $sortfield, $sortorder);
6973
            }
6974
            if (!empty($arrayfields['label']['checked'])) {
6975
                print_liste_field_titre($arrayfields['label']['label'], $_SERVER['PHP_SELF'], "label", "", $param, '', $sortfield, $sortorder);
6976
            }
6977
            if (!empty($arrayfields['type']['checked'])) {
6978
                print_liste_field_titre($arrayfields['type']['label'], $_SERVER['PHP_SELF'], "type", "", $param, '', $sortfield, $sortorder, 'center ');
6979
            }
6980
            if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
6981
                if (!empty($arrayfields['reconcilable']['checked'])) {
6982
                    print_liste_field_titre($arrayfields['reconcilable']['label'], $_SERVER['PHP_SELF'], 'reconcilable', '', $param, '', $sortfield, $sortorder, 'center ');
6983
                }
6984
            }
6985
            // Action column
6986
            if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
6987
                print_liste_field_titre($selectedfields, $_SERVER['PHP_SELF'], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
6988
            }
6989
            print "</tr>\n";
6990
6991
            $totalarray = [];
6992
            $totalarray['nbfield'] = 0;
6993
            $i = 0;
6994
            while ($i < min($num, $limit)) {
6995
                $obj = $db->fetch_object($resql);
6996
6997
                print '<tr class="oddeven">';
6998
6999
                // Action column
7000
                if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
7001
                    print '<td class="center">';
7002
                    $e = '';
7003
7004
                    // Customer
7005
                    if ($obj->type == 1) {
7006
                        $e .= '<a class="editfielda" title="' . $langs->trans("Customer") . '" href="' . DOL_URL_ROOT . '/societe/card.php?action=edit&token=' . newToken() . '&socid=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF']) . '">' . img_edit() . '</a>';
7007
                    } elseif ($obj->type == 2) {
7008
                        // Supplier
7009
                        $e .= '<a class="editfielda" title="' . $langs->trans("Supplier") . '" href="' . DOL_URL_ROOT . '/societe/card.php?action=edit&token=' . newToken() . '&socid=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF']) . '">' . img_edit() . '</a>';
7010
                    } elseif ($obj->type == 3) {
7011
                        // User - Employee
7012
                        $e .= '<a class="editfielda" title="' . $langs->trans("Employee") . '" href="' . DOL_URL_ROOT . '/user/card.php?action=edit&token=' . newToken() . '&id=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF']) . '">' . img_edit() . '</a>';
7013
                    }
7014
                    print $e;
7015
                    print '</td>' . "\n";
7016
                    if (!$i) {
7017
                        $totalarray['nbfield']++;
7018
                    }
7019
                }
7020
7021
                // Account number
7022
                if (!empty($arrayfields['subaccount']['checked'])) {
7023
                    print "<td>";
7024
                    print length_accounta($obj->subaccount);
7025
                    print "</td>\n";
7026
                    if (!$i) {
7027
                        $totalarray['nbfield']++;
7028
                    }
7029
                }
7030
7031
                // Subaccount label
7032
                if (!empty($arrayfields['label']['checked'])) {
7033
                    print "<td>";
7034
                    print dol_escape_htmltag($obj->label);
7035
                    print "</td>\n";
7036
                    if (!$i) {
7037
                        $totalarray['nbfield']++;
7038
                    }
7039
                }
7040
7041
                // Type
7042
                if (!empty($arrayfields['type']['checked'])) {
7043
                    print '<td class="center">';
7044
                    $s = '';
7045
7046
                    // Customer
7047
                    if ($obj->type == 1) {
7048
                        $s .= '<a class="customer-back" style="padding-left: 6px; padding-right: 6px" title="' . $langs->trans("Customer") . '" href="' . DOL_URL_ROOT . '/comm/card.php?socid=' . $obj->rowid . '">' . $langs->trans("Customer") . '</a>';
7049
                    } elseif ($obj->type == 2) {
7050
                        // Supplier
7051
                        $s .= '<a class="vendor-back" style="padding-left: 6px; padding-right: 6px" title="' . $langs->trans("Supplier") . '" href="' . DOL_URL_ROOT . '/fourn/card.php?socid=' . $obj->rowid . '">' . $langs->trans("Supplier") . '</a>';
7052
                    } elseif ($obj->type == 3) {
7053
                        // User - Employee
7054
                        $s .= '<a class="user-back" style="padding-left: 6px; padding-right: 6px" title="' . $langs->trans("Employee") . '" href="' . DOL_URL_ROOT . '/user/card.php?id=' . $obj->rowid . '">' . $langs->trans("Employee") . '</a>';
7055
                    }
7056
                    print $s;
7057
                    if ($obj->nature == 2) {
7058
                        print ' <span class="warning bold">(' . $langs->trans("Prospect") . ')</span>';
7059
                    }
7060
                    print '</td>';
7061
                    if (!$i) {
7062
                        $totalarray['nbfield']++;
7063
                    }
7064
                }
7065
7066
                if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) {
7067
                    // Activated or not reconciliation on accounting account
7068
                    if (!empty($arrayfields['reconcilable']['checked'])) {
7069
                        print '<td class="center">';
7070
                        if (empty($obj->reconcilable)) {
7071
                            print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=enable&mode=1&token=' . newToken() . '">';
7072
                            print img_picto($langs->trans("Disabled"), 'switch_off');
7073
                            print '</a>';
7074
                        } else {
7075
                            print '<a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?id=' . $obj->rowid . '&action=disable&mode=1&token=' . newToken() . '">';
7076
                            print img_picto($langs->trans("Activated"), 'switch_on');
7077
                            print '</a>';
7078
                        }
7079
                        print '</td>';
7080
                        if (!$i) {
7081
                            $totalarray['nbfield']++;
7082
                        }
7083
                    }
7084
                }
7085
7086
                // Action column
7087
                if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
7088
                    print '<td class="center">';
7089
                    $e = '';
7090
7091
                    // Customer
7092
                    if ($obj->type == 1) {
7093
                        $e .= '<a class="editfielda" title="' . $langs->trans("Customer") . '" href="' . DOL_URL_ROOT . '/societe/card.php?action=edit&token=' . newToken() . '&socid=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF']) . '">' . img_edit() . '</a>';
7094
                    } elseif ($obj->type == 2) {
7095
                        // Supplier
7096
                        $e .= '<a class="editfielda" title="' . $langs->trans("Supplier") . '" href="' . DOL_URL_ROOT . '/societe/card.php?action=edit&token=' . newToken() . '&socid=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF']) . '">' . img_edit() . '</a>';
7097
                    } elseif ($obj->type == 3) {
7098
                        // User - Employee
7099
                        $e .= '<a class="editfielda" title="' . $langs->trans("Employee") . '" href="' . DOL_URL_ROOT . '/user/card.php?action=edit&token=' . newToken() . '&id=' . $obj->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF']) . '">' . img_edit() . '</a>';
7100
                    }
7101
                    print $e;
7102
                    print '</td>' . "\n";
7103
                    if (!$i) {
7104
                        $totalarray['nbfield']++;
7105
                    }
7106
                }
7107
7108
                print '</tr>' . "\n";
7109
                $i++;
7110
            }
7111
7112
            // If no record found
7113
            if ($num == 0) {
7114
                $colspan = 1;
7115
                foreach ($arrayfields as $key => $val) {
7116
                    if (!empty($val['checked'])) {
7117
                        $colspan++;
7118
                    }
7119
                }
7120
                print '<tr><td colspan="' . $colspan . '"><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
7121
            }
7122
7123
            $db->free($resql);
7124
7125
            $parameters = ['arrayfields' => $arrayfields, 'sql' => $sql];
7126
            $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook
7127
            print $hookmanager->resPrint;
7128
7129
            print "</table>";
7130
            print "</div>";
7131
7132
            print '</form>';
7133
        } else {
7134
            dol_print_error($db);
7135
        }
7136
7137
// End of page
7138
        llxFooter();
7139
        $db->close();
7140
    }
7141
7142
    /**
7143
     *  Show fields in insert/edit mode
7144
     *
7145
     * @param array  $fieldlist Array of fields
7146
     * @param Object $obj       If we show a particular record, obj is filled with record fields
7147
     * @param string $tabname   Name of SQL table
7148
     * @param string $context   'add'=Output field for the "add form", 'edit'=Output field for the "edit form",
7149
     *                          'hide'=Output field for the "add form" but we don't want it to be rendered
7150
     *
7151
     * @return     void
7152
     */
7153
    private function fieldListAccountModel($fieldlist, $obj = null, $tabname = '', $context = '')
7154
    {
7155
        global $langs, $db;
7156
        global $form;
7157
        global $elementList, $sourceList;
7158
7159
        $formadmin = new FormAdmin($db);
7160
        $formcompany = new FormCompany($db);
7161
        $formaccounting = new FormAccounting($db);
7162
7163
        foreach ($fieldlist as $field => $value) {
7164
            if ($fieldlist[$field] == 'country') {
7165
                if (in_array('region_id', $fieldlist)) {
7166
                    print '<td>';
7167
                    //print join(',',$fieldlist);
7168
                    print '</td>';
7169
                    continue;
7170
                }   // For state page, we do not show the country input (we link to region, not country)
7171
                print '<td>';
7172
                $fieldname = 'country';
7173
                print $form->select_country((!empty($obj->country_code) ? $obj->country_code : (!empty($obj->country) ? $obj->country : '')), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone');
7174
                print '</td>';
7175
            } elseif ($fieldlist[$field] == 'country_id') {
7176
                if (!in_array('country', $fieldlist)) { // If there is already a field country, we don't show country_id (avoid duplicate)
7177
                    $country_id = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0);
7178
                    print '<td>';
7179
                    print '<input type="hidden" name="' . $fieldlist[$field] . '" value="' . $country_id . '">';
7180
                    print '</td>';
7181
                }
7182
            } elseif ($fieldlist[$field] == 'type_cdr') {
7183
                if ($fieldlist[$field] == 'type_cdr') {
7184
                    print '<td class="center">';
7185
                } else {
7186
                    print '<td>';
7187
                }
7188
                if ($fieldlist[$field] == 'type_cdr') {
7189
                    print $form->selectarray($fieldlist[$field], [0 => $langs->trans('None'), 1 => $langs->trans('AtEndOfMonth'), 2 => $langs->trans('CurrentNext')], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''));
7190
                } else {
7191
                    print $form->selectyesno($fieldlist[$field], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''), 1);
7192
                }
7193
                print '</td>';
7194
            } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
7195
                print '<td><input type="text" class="flat" value="' . (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" size="10" name="' . $fieldlist[$field] . '"></td>';
7196
            } else {
7197
                print '<td>';
7198
                $class = '';
7199
                if ($fieldlist[$field] == 'pcg_version') {
7200
                    $class = 'width150';
7201
                }
7202
                if ($fieldlist[$field] == 'label') {
7203
                    $class = 'width300';
7204
                }
7205
                print '<input type="text" class="flat' . ($class ? ' ' . $class : '') . '" value="' . (isset($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '">';
7206
                print '</td>';
7207
            }
7208
        }
7209
    }
7210
7211
    /**
7212
     *  Show fields in insert/edit mode
7213
     *
7214
     * @param array  $fieldlist Array of fields
7215
     * @param Object $obj       If we show a particular record, obj is filled with record fields
7216
     * @param string $tabname   Name of SQL table
7217
     * @param string $context   'add'=Output field for the "add form", 'edit'=Output field for the "edit form",
7218
     *                          'hide'=Output field for the "add form" but we don't want it to be rendered
7219
     *
7220
     * @return     void
7221
     */
7222
    private function fieldListJournal($fieldlist, $obj = null, $tabname = '', $context = '')
7223
    {
7224
        global $db, $form, $sourceList;
7225
7226
        $formadmin = new FormAdmin($db);
7227
        $formcompany = new FormCompany($db);
7228
7229
        foreach ($fieldlist as $field => $value) {
7230
            if ($fieldlist[$field] == 'nature') {
7231
                print '<td>';
7232
                print $form->selectarray('nature', $sourceList, (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''));
7233
                print '</td>';
7234
            } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
7235
                print '<td><input type="text" class="flat minwidth100" value="' . (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '"></td>';
7236
            } else {
7237
                print '<td>';
7238
                $size = '';
7239
                $class = '';
7240
                if ($fieldlist[$field] == 'code') {
7241
                    $class = 'maxwidth100';
7242
                }
7243
                if ($fieldlist[$field] == 'label') {
7244
                    $class = 'quatrevingtpercent';
7245
                }
7246
                if ($fieldlist[$field] == 'sortorder' || $fieldlist[$field] == 'sens' || $fieldlist[$field] == 'category_type') {
7247
                    $size = 'size="2" ';
7248
                }
7249
                print '<input type="text" ' . $size . 'class="flat' . ($class ? ' ' . $class : '') . '" value="' . (isset($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '">';
7250
                print '</td>';
7251
            }
7252
        }
7253
    }
7254
}
7255