Passed
Push — main ( f1540e...02d90d )
by Rafael
45:15
created

AccountingAdminController::account()   F

Complexity

Conditions 41
Paths > 20000

Size

Total Lines 211
Code Lines 135

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 41
eloc 135
nc 14688256
nop 0
dl 0
loc 211
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 . '/core/class/doleditor.class.php';
55
require_once DOL_DOCUMENT_ROOT . '/core/class/fiscalyear.class.php';
56
require_once BASE_PATH . '/../Dolibarr/Lib/Accounting.php';
57
require_once BASE_PATH . '/../Dolibarr/Lib/Admin.php';
58
require_once BASE_PATH . '/../Dolibarr/Lib/Date.php';
59
require_once BASE_PATH . '/../Dolibarr/Lib/FiscalYear.php';
60
require_once BASE_PATH . '/../Dolibarr/Lib/Functions2.php';
61
require_once BASE_PATH . '/../Dolibarr/Lib/Report.php';
62
63
use DoliCore\Base\DolibarrController;
64
use DoliCore\Form\FormAccounting;
65
use DoliCore\Form\FormAdmin;
66
use DoliCore\Form\FormCompany;
67
use DoliModules\Accounting\Model\AccountancyCategory;
68
use DoliModules\Accounting\Model\AccountancyExport;
69
use DoliModules\Accounting\Model\AccountingAccount;
70
use Fiscalyear;
71
72
class AccountingAdminController extends DolibarrController
73
{
74
    /**
75
     * \file        htdocs/accountancy/admin/account.php
76
     * \ingroup     Accountancy (Double entries)
77
     * \brief       List accounting account
78
     */
79
    public function account()
80
    {
81
        global $conf;
82
        global $db;
83
        global $user;
84
        global $hookmanager;
85
        global $user;
86
        global $menumanager;
87
        global $langs;
88
89
// Load translation files required by the page
90
        $langs->loadLangs(['accountancy', 'admin', 'bills', 'compta', 'salaries']);
91
92
        $action = GETPOST('action', 'aZ09');
93
        $cancel = GETPOST('cancel', 'alpha');
94
        $id = GETPOSTINT('id');
95
        $rowid = GETPOSTINT('rowid');
96
        $massaction = GETPOST('massaction', 'aZ09');
97
        $optioncss = GETPOST('optioncss', 'alpha');
98
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'accountingaccountlist'; // To manage different context of search
99
        $mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
100
101
        $search_account = GETPOST('search_account', 'alpha');
102
        $search_label = GETPOST('search_label', 'alpha');
103
        $search_labelshort = GETPOST('search_labelshort', 'alpha');
104
        $search_accountparent = GETPOST('search_accountparent', 'alpha');
105
        $search_pcgtype = GETPOST('search_pcgtype', 'alpha');
106
        $search_import_key = GETPOST('search_import_key', 'alpha');
107
        $toselect = GETPOST('toselect', 'array');
108
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
109
        $confirm = GETPOST('confirm', 'alpha');
110
111
        $chartofaccounts = GETPOSTINT('chartofaccounts');
112
113
        $permissiontoadd = $user->hasRight('accounting', 'chartofaccount');
114
        $permissiontodelete = $user->hasRight('accounting', 'chartofaccount');
115
116
// Security check
117
        if ($user->socid > 0) {
118
            accessforbidden();
119
        }
120
        if (!$user->hasRight('accounting', 'chartofaccount')) {
121
            accessforbidden();
122
        }
123
124
// Load variable for pagination
125
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
126
        $sortfield = GETPOST('sortfield', 'aZ09comma');
127
        $sortorder = GETPOST('sortorder', 'aZ09comma');
128
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
129
        if (empty($page) || $page == -1) {
130
            $page = 0;
131
        }     // If $page is not defined, or '' or -1
132
        $offset = $limit * $page;
133
        $pageprev = $page - 1;
134
        $pagenext = $page + 1;
135
        if (!$sortfield) {
136
            $sortfield = "aa.account_number";
137
        }
138
        if (!$sortorder) {
139
            $sortorder = "ASC";
140
        }
141
142
        $arrayfields = [
143
            'aa.account_number' => ['label' => "AccountNumber", 'checked' => 1],
144
            'aa.label' => ['label' => "Label", 'checked' => 1],
145
            'aa.labelshort' => ['label' => "LabelToShow", 'checked' => 1],
146
            'aa.account_parent' => ['label' => "Accountparent", 'checked' => 1],
147
            'aa.pcg_type' => ['label' => "Pcgtype", 'checked' => 1, 'help' => 'PcgtypeDesc'],
148
            'categories' => ['label' => "AccountingCategories", 'checked' => -1, 'help' => 'AccountingCategoriesDesc'],
149
            'aa.reconcilable' => ['label' => "Reconcilable", 'checked' => 1],
150
            'aa.import_key' => ['label' => "ImportId", 'checked' => -1, 'help' => ''],
151
            'aa.active' => ['label' => "Activated", 'checked' => 1],
152
        ];
153
154
        if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
155
            unset($arrayfields['categories']);
156
            unset($arrayfields['aa.reconcilable']);
157
        }
158
159
        $accounting = new AccountingAccount($db);
160
161
// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
162
        $hookmanager->initHooks(['accountancyadminaccount']);
163
164
165
        /*
166
         * Actions
167
         */
168
169
        if (GETPOST('cancel', 'alpha')) {
170
            $action = 'list';
171
            $massaction = '';
172
        }
173
        if (!GETPOST('confirmmassaction', 'alpha')) {
174
            $massaction = '';
175
        }
176
177
        $parameters = ['chartofaccounts' => $chartofaccounts, 'permissiontoadd' => $permissiontoadd, 'permissiontodelete' => $permissiontodelete];
178
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $accounting, $action); // Note that $action and $object may have been monowraponalldified by some hooks
179
        if ($reshook < 0) {
180
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
181
        }
182
183
        if (empty($reshook)) {
184
            if (!empty($cancel)) {
185
                $action = '';
186
            }
187
188
            $objectclass = 'AccountingAccount';
189
            $uploaddir = $conf->accounting->multidir_output[$conf->entity];
190
            include DOL_DOCUMENT_ROOT . '/core/actions_massactions.inc.php';
191
192
            if ($action == "delete") {
193
                $action = "";
194
            }
195
            include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php';
196
197
            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
198
                $search_account = "";
199
                $search_label = "";
200
                $search_labelshort = "";
201
                $search_accountparent = "";
202
                $search_pcgtype = "";
203
                $search_import_key = "";
204
                $search_array_options = [];
205
            }
206
            if (
207
                (GETPOSTINT('valid_change_chart') && GETPOSTINT('chartofaccounts') > 0) // explicit click on button 'Change and load' with js on
208
                || (GETPOSTINT('chartofaccounts') > 0 && GETPOSTINT('chartofaccounts') != getDolGlobalInt('CHARTOFACCOUNTS'))
209
            ) {    // a submit of form is done and chartofaccounts combo has been modified
210
                $error = 0;
211
212
                if ($chartofaccounts > 0 && $permissiontoadd) {
213
                    $country_code = '';
214
                    // Get language code for this $chartofaccounts
215
                    $sql = 'SELECT code FROM ' . MAIN_DB_PREFIX . 'c_country as c, ' . MAIN_DB_PREFIX . 'accounting_system as a';
216
                    $sql .= ' WHERE c.rowid = a.fk_country AND a.rowid = ' . (int) $chartofaccounts;
217
                    $resql = $db->query($sql);
218
                    if ($resql) {
219
                        $obj = $db->fetch_object($resql);
220
                        if ($obj) {
221
                            $country_code = $obj->code;
222
                        }
223
                    } else {
224
                        dol_print_error($db);
225
                    }
226
227
                    // Try to load sql file
228
                    if ($country_code) {
229
                        $sqlfile = DOL_DOCUMENT_ROOT . '/install/mysql/data/llx_accounting_account_' . strtolower($country_code) . '.sql';
230
231
                        $offsetforchartofaccount = 0;
232
                        // Get the comment line '-- ADD CCCNNNNN to rowid...' to find CCCNNNNN (CCC is country num, NNNNN is id of accounting account)
233
                        // 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.
234
                        // This is to be sure there is no conflict for each chart of account, whatever is country, whatever is company when multicompany is used.
235
                        $tmp = file_get_contents($sqlfile);
236
                        $reg = [];
237
                        if (preg_match('/-- ADD (\d+) to rowid/ims', $tmp, $reg)) {
238
                            $offsetforchartofaccount += $reg[1];
239
                        }
240
                        $offsetforchartofaccount += ($conf->entity * 100000000);
241
242
                        $result = run_sql($sqlfile, 1, $conf->entity, 1, '', 'default', 32768, 0, $offsetforchartofaccount);
243
244
                        if ($result > 0) {
245
                            setEventMessages($langs->trans("ChartLoaded"), null, 'mesgs');
246
                        } else {
247
                            setEventMessages($langs->trans("ErrorDuringChartLoad"), null, 'warnings');
248
                        }
249
                    }
250
251
                    if (!dolibarr_set_const($db, 'CHARTOFACCOUNTS', $chartofaccounts, 'chaine', 0, '', $conf->entity)) {
252
                        $error++;
253
                    }
254
                } else {
255
                    $error++;
256
                }
257
            }
258
259
            if ($action == 'disable' && $permissiontoadd) {
260
                if ($accounting->fetch($id)) {
261
                    $mode = GETPOSTINT('mode');
262
                    $result = $accounting->accountDeactivate($id, $mode);
263
                    if ($result < 0) {
264
                        setEventMessages($accounting->error, $accounting->errors, 'errors');
265
                    }
266
                }
267
268
                $action = 'update';
269
            } elseif ($action == 'enable' && $permissiontoadd) {
270
                if ($accounting->fetch($id)) {
271
                    $mode = GETPOSTINT('mode');
272
                    $result = $accounting->accountActivate($id, $mode);
273
                    if ($result < 0) {
274
                        setEventMessages($accounting->error, $accounting->errors, 'errors');
275
                    }
276
                }
277
                $action = 'update';
278
            }
279
        }
280
281
282
        /*
283
         * View
284
         */
285
286
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_account.php');
287
288
        $db->close();
289
        return true;
290
    }
291
292
    /**
293
     *      \file       htdocs/accountancy/admin/accountmodel.php
294
     *      \ingroup    Accountancy (Double entries)
295
     *      \brief      Page to administer model of chart of accounts
296
     */
297
    public function accountmodel()
298
    {
299
        global $conf;
300
        global $db;
301
        global $user;
302
        global $hookmanager;
303
        global $user;
304
        global $menumanager;
305
        global $langs;
306
307
        if (isModEnabled('accounting')) {
308
        }
309
310
// Load translation files required by the page
311
        $langs->loadLangs(['accountancy', 'admin', 'companies', 'compta', 'errors', 'holiday', 'hrm', 'resource']);
312
313
        $action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view';
314
        $confirm = GETPOST('confirm', 'alpha');
315
        $id = 31;
316
        $rowid = GETPOST('rowid', 'alpha');
317
        $code = GETPOST('code', 'alpha');
318
319
        $acts = [];
320
        $actl = [];
321
        $acts[0] = "activate";
322
        $acts[1] = "disable";
323
        $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
324
        $actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"');
325
326
        $listoffset = GETPOST('listoffset', 'alpha');
327
        $listlimit = GETPOSTINT('listlimit') > 0 ? GETPOSTINT('listlimit') : 1000;
328
        $active = 1;
329
330
        $sortfield = GETPOST("sortfield", 'aZ09comma');
331
        $sortorder = GETPOST("sortorder", 'aZ09comma');
332
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
333
        if (empty($page) || $page == -1) {
334
            $page = 0;
335
        }     // If $page is not defined, or '' or -1
336
        $offset = $listlimit * $page;
337
        $pageprev = $page - 1;
338
        $pagenext = $page + 1;
339
340
        $search_country_id = GETPOSTINT('search_country_id');
341
342
343
// Security check
344
        if ($user->socid > 0) {
345
            accessforbidden();
346
        }
347
        if (!$user->hasRight('accounting', 'chartofaccount')) {
348
            accessforbidden();
349
        }
350
351
352
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
353
        $hookmanager->initHooks(['admin']);
354
355
// This page is a generic page to edit dictionaries
356
// Put here declaration of dictionaries properties
357
358
// Name of SQL tables of dictionaries
359
        $tabname = [];
360
361
        $tabname[31] = MAIN_DB_PREFIX . "accounting_system";
362
363
// Dictionary labels
364
        $tablib = [];
365
        $tablib[31] = "Pcg_version";
366
367
// Requests to extract data
368
        $tabsql = [];
369
        $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";
370
371
// Criteria to sort dictionaries
372
        $tabsqlsort = [];
373
        $tabsqlsort[31] = "pcg_version ASC";
374
375
// Nom des champs en resultat de select pour affichage du dictionnaire
376
        $tabfield = [];
377
        $tabfield[31] = "pcg_version,label,country_id,country";
378
379
// Nom des champs d'edition pour modification d'un enregistrement
380
        $tabfieldvalue = [];
381
        $tabfieldvalue[31] = "pcg_version,label,country";
382
383
// Nom des champs dans la table pour insertion d'un enregistrement
384
        $tabfieldinsert = [];
385
        $tabfieldinsert[31] = "pcg_version,label,fk_country";
386
387
// Nom du rowid si le champ n'est pas de type autoincrement
388
// Example: "" if id field is "rowid" and has autoincrement on
389
//          "nameoffield" if id field is not "rowid" or has not autoincrement on
390
        $tabrowid = [];
391
        $tabrowid[31] = "";
392
393
// List of help for fields
394
        $tabhelp = [];
395
        $tabhelp[31] = ['pcg_version' => $langs->trans("EnterAnyCode")];
396
397
398
// Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact")
399
        $elementList = [];
400
        $sourceList = [];
401
402
403
        /*
404
         * Actions
405
         */
406
407
        if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) {
408
            $search_country_id = '';
409
        }
410
411
// Actions add or modify an entry into a dictionary
412
        if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
413
            $listfield = explode(',', str_replace(' ', '', $tabfield[$id]));
414
            $listfieldinsert = explode(',', $tabfieldinsert[$id]);
415
            $listfieldmodify = explode(',', $tabfieldinsert[$id]);
416
            $listfieldvalue = explode(',', $tabfieldvalue[$id]);
417
418
            // Check that all fields are filled
419
            $ok = 1;
420
            foreach ($listfield as $f => $value) {
421
                if ($value == 'country_id' && in_array($tablib[$id], ['Pcg_version'])) {
422
                    continue; // For some pages, country is not mandatory
423
                }
424
                if ((!GETPOSTISSET($value)) || GETPOST($value) == '') {
425
                    $ok = 0;
426
                    $fieldnamekey = $listfield[$f];
427
                    // We take translate key of field
428
429
                    if ($fieldnamekey == 'pcg_version') {
430
                        $fieldnamekey = 'Pcg_version';
431
                    }
432
                    if ($fieldnamekey == 'label') {
433
                        $fieldnamekey = 'Label';
434
                    }
435
                    if ($fieldnamekey == 'country') {
436
                        $fieldnamekey = "Country";
437
                    }
438
439
                    setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors');
440
                }
441
            }
442
            // Other checks
443
            if (GETPOSTISSET("pcg_version")) {
444
                if (GETPOST("pcg_version") == '0') {
445
                    $ok = 0;
446
                    setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
447
                }
448
            }
449
            if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) {
450
                $ok = 0;
451
                setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Country")), null, 'errors');
452
            }
453
454
            // Si verif ok et action add, on ajoute la ligne
455
            if ($ok && GETPOST('actionadd', 'alpha')) {
456
                $newid = 0;
457
                if ($tabrowid[$id]) {
458
                    // Get free id for insert
459
                    $sql = "SELECT MAX(" . $db->sanitize($tabrowid[$id]) . ") as newid FROM " . $db->sanitize($tabname[$id]);
460
                    $result = $db->query($sql);
461
                    if ($result) {
462
                        $obj = $db->fetch_object($result);
463
                        $newid = ($obj->newid + 1);
464
                    } else {
465
                        dol_print_error($db);
466
                    }
467
                }
468
469
                // Add new entry
470
                $sql = "INSERT INTO " . $db->sanitize($tabname[$id]) . " (";
471
                // List of fields
472
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
473
                    $sql .= $db->sanitize($tabrowid[$id]) . ",";
474
                }
475
                $sql .= $db->sanitize($tabfieldinsert[$id]);
476
                $sql .= ",active)";
477
                $sql .= " VALUES(";
478
479
                // List of values
480
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
481
                    $sql .= $newid . ",";
482
                }
483
                $i = 0;
484
                foreach ($listfieldinsert as $f => $value) {
485
                    if ($value == 'price' || preg_match('/^amount/i', $value) || $value == 'taux') {
486
                        $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU');
487
                    } elseif ($value == 'entity') {
488
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
489
                    }
490
                    if ($i) {
491
                        $sql .= ",";
492
                    }
493
                    if (GETPOST($listfieldvalue[$i]) == '') {
494
                        $sql .= "null";
495
                    } else {
496
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
497
                    }
498
                    $i++;
499
                }
500
                $sql .= ",1)";
501
502
                dol_syslog("actionadd", LOG_DEBUG);
503
                $result = $db->query($sql);
504
                if ($result) {  // Add is ok
505
                    setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
506
                    $_POST = ['id' => $id]; // Clean $_POST array, we keep only
507
                } else {
508
                    if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
509
                        setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
510
                    } else {
511
                        dol_print_error($db);
512
                    }
513
                }
514
            }
515
516
            // Si verif ok et action modify, on modifie la ligne
517
            if ($ok && GETPOST('actionmodify', 'alpha')) {
518
                if ($tabrowid[$id]) {
519
                    $rowidcol = $tabrowid[$id];
520
                } else {
521
                    $rowidcol = "rowid";
522
                }
523
524
                // Modify entry
525
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET ";
526
                // Modifie valeur des champs
527
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) {
528
                    $sql .= $db->sanitize($tabrowid[$id]) . " = ";
529
                    $sql .= "'" . $db->escape($rowid) . "', ";
530
                }
531
                $i = 0;
532
                foreach ($listfieldmodify as $field) {
533
                    if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') {
534
                        $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU');
535
                    } elseif ($field == 'entity') {
536
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
537
                    }
538
                    if ($i) {
539
                        $sql .= ",";
540
                    }
541
                    $sql .= $field . "=";
542
                    if (GETPOST($listfieldvalue[$i]) == '') {
543
                        $sql .= "null";
544
                    } else {
545
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
546
                    }
547
                    $i++;
548
                }
549
                $sql .= " WHERE " . $rowidcol . " = " . ((int) $rowid);
550
551
                dol_syslog("actionmodify", LOG_DEBUG);
552
                //print $sql;
553
                $resql = $db->query($sql);
554
                if (!$resql) {
555
                    setEventMessages($db->error(), null, 'errors');
556
                }
557
            }
558
        }
559
560
        if ($action == 'confirm_delete' && $confirm == 'yes') {       // delete
561
            if ($tabrowid[$id]) {
562
                $rowidcol = $tabrowid[$id];
563
            } else {
564
                $rowidcol = "rowid";
565
            }
566
567
            $sql = "DELETE from " . $db->sanitize($tabname[$id]) . " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
568
569
            dol_syslog("delete", LOG_DEBUG);
570
            $result = $db->query($sql);
571
            if (!$result) {
572
                if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') {
573
                    setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors');
574
                } else {
575
                    dol_print_error($db);
576
                }
577
            }
578
        }
579
580
// activate
581
        if ($action == 'activate') {
582
            $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE rowid = " . ((int) $rowid);
583
            $result = $db->query($sql);
584
            if (!$result) {
585
                dol_print_error($db);
586
            }
587
        }
588
589
// disable
590
        if ($action == $acts[1]) {
591
            $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE rowid = " . ((int) $rowid);
592
            $result = $db->query($sql);
593
            if (!$result) {
594
                dol_print_error($db);
595
            }
596
        }
597
598
599
        /*
600
         * View
601
         */
602
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_accountmodel.php');
603
604
        $db->close();
605
        return true;
606
    }
607
608
    /**
609
     *  \file       htdocs/accountancy/admin/card.php
610
     *  \ingroup    Accountancy (Double entries)
611
     *  \brief      Card of accounting account
612
     */
613
    public function card()
614
    {
615
        global $conf;
616
        global $db;
617
        global $user;
618
        global $hookmanager;
619
        global $user;
620
        global $menumanager;
621
        global $langs;
622
623
        $error = 0;
624
625
// Load translation files required by the page
626
        $langs->loadLangs(['accountancy', 'bills', 'compta']);
627
628
        $action = GETPOST('action', 'aZ09');
629
        $backtopage = GETPOST('backtopage', 'alpha');
630
        $id = GETPOSTINT('id');
631
        $ref = GETPOST('ref', 'alpha');
632
        $rowid = GETPOSTINT('rowid');
633
        $cancel = GETPOST('cancel', 'alpha');
634
635
        $account_number = GETPOST('account_number', 'alphanohtml');
636
        $label = GETPOST('label', 'alpha');
637
638
// Security check
639
        if ($user->socid > 0) {
640
            accessforbidden();
641
        }
642
        if (!$user->hasRight('accounting', 'chartofaccount')) {
643
            accessforbidden();
644
        }
645
646
647
        $object = new AccountingAccount($db);
648
649
650
        /*
651
         * Action
652
         */
653
654
        if (GETPOST('cancel', 'alpha')) {
655
            $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT . '/accountancy/admin/account.php';
656
            header("Location: " . $urltogo);
657
            exit;
658
        }
659
660
        if ($action == 'add' && $user->hasRight('accounting', 'chartofaccount')) {
661
            if (!$cancel) {
662
                if (!$account_number) {
663
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
664
                    $action = 'create';
665
                } elseif (!$label) {
666
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
667
                    $action = 'create';
668
                } else {
669
                    $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid = " . ((int) getDolGlobalInt('CHARTOFACCOUNTS'));
670
671
                    dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
672
                    $result = $db->query($sql);
673
                    $obj = $db->fetch_object($result);
674
675
                    // Clean code
676
677
                    // To manage zero or not at the end of the accounting account
678
                    if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
679
                        $account_number = clean_account($account_number);
680
                    }
681
682
                    $account_parent = (GETPOSTINT('account_parent') > 0) ? GETPOSTINT('account_parent') : 0;
683
684
                    $object->fk_pcg_version = $obj->pcg_version;
685
                    $object->pcg_type = GETPOST('pcg_type', 'alpha');
0 ignored issues
show
Documentation Bug introduced by
It seems like GETPOST('pcg_type', 'alpha') can also be of type array or array or array. However, the property $pcg_type 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...
686
                    $object->account_number = $account_number;
0 ignored issues
show
Documentation Bug introduced by
It seems like $account_number can also be of type array or array or array. However, the property $account_number 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...
687
                    $object->account_parent = $account_parent;
688
                    $object->account_category = GETPOSTINT('account_category');
689
                    $object->label = $label;
0 ignored issues
show
Documentation Bug introduced by
It seems like $label can also be of type 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...
690
                    $object->labelshort = GETPOST('labelshort', 'alpha');
0 ignored issues
show
Documentation Bug introduced by
It seems like GETPOST('labelshort', 'alpha') can also be of type array or array or array. However, the property $labelshort 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...
691
                    $object->active = 1;
692
693
                    $res = $object->create($user);
694
                    if ($res == -3) {
695
                        $error = 1;
696
                        $action = "create";
697
                        setEventMessages($object->error, $object->errors, 'errors');
698
                    } elseif ($res == -4) {
699
                        $error = 2;
700
                        $action = "create";
701
                        setEventMessages($object->error, $object->errors, 'errors');
702
                    } elseif ($res < 0) {
703
                        $error++;
704
                        setEventMessages($object->error, $object->errors, 'errors');
705
                        $action = "create";
706
                    }
707
                    if (!$error) {
708
                        setEventMessages("RecordCreatedSuccessfully", null, 'mesgs');
709
                        $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT . '/accountancy/admin/account.php';
710
                        header("Location: " . $urltogo);
711
                        exit;
712
                    }
713
                }
714
            }
715
        } elseif ($action == 'edit' && $user->hasRight('accounting', 'chartofaccount')) {
716
            if (!$cancel) {
717
                if (!$account_number) {
718
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
719
                    $action = 'update';
720
                } elseif (!$label) {
721
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
722
                    $action = 'update';
723
                } else {
724
                    $result = $object->fetch($id);
725
726
                    $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid=" . ((int) getDolGlobalInt('CHARTOFACCOUNTS'));
727
728
                    dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
729
                    $result2 = $db->query($sql);
730
                    $obj = $db->fetch_object($result2);
731
732
                    // Clean code
733
734
                    // To manage zero or not at the end of the accounting account
735
                    if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
736
                        $account_number = clean_account($account_number);
737
                    }
738
739
                    $account_parent = (GETPOSTINT('account_parent') > 0) ? GETPOSTINT('account_parent') : 0;
740
741
                    $object->fk_pcg_version = $obj->pcg_version;
742
                    $object->pcg_type = GETPOST('pcg_type', 'alpha');
743
                    $object->account_number = $account_number;
744
                    $object->account_parent = $account_parent;
745
                    $object->account_category = GETPOSTINT('account_category');
746
                    $object->label = $label;
747
                    $object->labelshort = GETPOST('labelshort', 'alpha');
748
749
                    $result = $object->update($user);
750
751
                    if ($result > 0) {
752
                        $urltogo = $backtopage ? $backtopage : ($_SERVER['PHP_SELF'] . "?id=" . $id);
753
                        header("Location: " . $urltogo);
754
                        exit();
755
                    } elseif ($result == -2) {
756
                        setEventMessages($langs->trans("ErrorAccountNumberAlreadyExists", $object->account_number), null, 'errors');
757
                    } else {
758
                        setEventMessages($object->error, null, 'errors');
759
                    }
760
                }
761
            } else {
762
                $urltogo = $backtopage ? $backtopage : ($_SERVER['PHP_SELF'] . "?id=" . $id);
763
                header("Location: " . $urltogo);
764
                exit();
765
            }
766
        } elseif ($action == 'delete' && $user->hasRight('accounting', 'chartofaccount')) {
767
            $result = $object->fetch($id);
768
769
            if (!empty($object->id)) {
770
                $result = $object->delete($user);
771
772
                if ($result > 0) {
773
                    header("Location: account.php");
774
                    exit;
775
                }
776
            }
777
778
            if ($result < 0) {
779
                setEventMessages($object->error, $object->errors, 'errors');
780
            }
781
        }
782
783
784
        /*
785
         * View
786
         */
787
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_card.php');
788
789
        $db->close();
790
        return true;
791
    }
792
793
    /**
794
     * \file    htdocs/accountancy/admin/categories.php
795
     * \ingroup Accountancy (Double entries)
796
     * \brief   Page to assign mass categories to accounts
797
     */
798
    public function categories()
799
    {
800
        global $conf;
801
        global $db;
802
        global $user;
803
        global $hookmanager;
804
        global $user;
805
        global $menumanager;
806
        global $langs;
807
808
        $error = 0;
809
810
// Load translation files required by the page
811
        $langs->loadLangs(["bills", "accountancy", "compta"]);
812
813
        $id = GETPOSTINT('id');
814
        $cancel = GETPOST('cancel', 'alpha');
815
        $action = GETPOST('action', 'aZ09');
816
        $cat_id = GETPOSTINT('account_category');
817
        $selectcpt = GETPOST('cpt_bk', 'array');
818
        $cpt_id = GETPOSTINT('cptid');
819
820
        if ($cat_id == 0) {
821
            $cat_id = null;
822
        }
823
824
// Load variable for pagination
825
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
826
        $sortfield = GETPOST('sortfield', 'aZ09comma');
827
        $sortorder = GETPOST('sortorder', 'aZ09comma');
828
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
829
        if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
830
            // If $page is not defined, or '' or -1 or if we click on clear filters
831
            $page = 0;
832
        }
833
        $offset = $limit * $page;
834
        $pageprev = $page - 1;
835
        $pagenext = $page + 1;
836
837
        if (empty($sortfield)) {
838
            $sortfield = 'account_number';
839
        }
840
        if (empty($sortorder)) {
841
            $sortorder = 'ASC';
842
        }
843
844
// Security check
845
        if (!$user->hasRight('accounting', 'chartofaccount')) {
846
            accessforbidden();
847
        }
848
849
        $accountingcategory = new AccountancyCategory($db);
850
851
852
        /*
853
         * Actions
854
         */
855
856
// If we add account
857
        if (!empty($selectcpt)) {
858
            $cpts = [];
859
            foreach ($selectcpt as $selectedoption) {
860
                if (!array_key_exists($selectedoption, $cpts)) {
861
                    $cpts[$selectedoption] = "'" . $selectedoption . "'";
862
                }
863
            }
864
865
            $return = $accountingcategory->updateAccAcc($cat_id, $cpts);
866
867
            if ($return < 0) {
868
                setEventMessages($langs->trans('errors'), $accountingcategory->errors, 'errors');
869
            } else {
870
                setEventMessages($langs->trans('RecordModifiedSuccessfully'), null, 'mesgs');
871
            }
872
        }
873
874
        if ($action == 'delete') {
875
            if ($cpt_id) {
876
                if ($accountingcategory->deleteCptCat($cpt_id)) {
877
                    setEventMessages($langs->trans('AccountRemovedFromGroup'), null, 'mesgs');
878
                } else {
879
                    setEventMessages($langs->trans('errors'), null, 'errors');
880
                }
881
            }
882
        }
883
884
885
        /*
886
         * View
887
         */
888
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_categories.php');
889
890
        $db->close();
891
        return true;
892
    }
893
894
    /**
895
     *      \file       htdocs/accountancy/admin/categories_list.php
896
     *      \ingroup    setup
897
     *      \brief      Page to administer data tables
898
     */
899
    public function categories_list()
900
    {
901
        global $conf;
902
        global $db;
903
        global $user;
904
        global $hookmanager;
905
        global $user;
906
        global $menumanager;
907
        global $langs;
908
909
// Load translation files required by the page
910
        $langs->loadLangs(["errors", "admin", "companies", "resource", "holiday", "accountancy", "hrm"]);
911
912
        $action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view';
913
        $confirm = GETPOST('confirm', 'alpha');
914
        $id = 32;
915
        $rowid = GETPOST('rowid', 'alpha');
916
        $code = GETPOST('code', 'alpha');
917
918
// Security access
919
        if (!$user->hasRight('accounting', 'chartofaccount')) {
920
            accessforbidden();
921
        }
922
923
        $acts = [];
924
        $acts[0] = "activate";
925
        $acts[1] = "disable";
926
        $actl = [];
927
        $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
928
        $actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"');
929
930
        $listoffset = GETPOST('listoffset', 'alpha');
931
        $listlimit = GETPOSTINT('listlimit') > 0 ? GETPOSTINT('listlimit') : 1000;
932
933
        $sortfield = GETPOST("sortfield", 'aZ09comma');
934
        $sortorder = GETPOST("sortorder", 'aZ09comma');
935
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
936
        if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
937
            // If $page is not defined, or '' or -1 or if we click on clear filters
938
            $page = 0;
939
        }
940
        $offset = $listlimit * $page;
941
        $pageprev = $page - 1;
942
        $pagenext = $page + 1;
943
944
        $search_country_id = GETPOSTINT('search_country_id');
945
946
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
947
        $hookmanager->initHooks(['admin']);
948
949
// This page is a generic page to edit dictionaries
950
// Put here declaration of dictionaries properties
951
952
// Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this.
953
        $taborder = [32];
954
955
// Name of SQL tables of dictionaries
956
        $tabname = [];
957
        $tabname[32] = MAIN_DB_PREFIX . "c_accounting_category";
958
959
// Dictionary labels
960
        $tablib = [];
961
        $tablib[32] = "DictionaryAccountancyCategory";
962
963
// Requests to extract data
964
        $tabsql = [];
965
        $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";
966
967
// Criteria to sort dictionaries
968
        $tabsqlsort = [];
969
        $tabsqlsort[32] = "position ASC";
970
971
// Name of the fields in the result of select to display the dictionary
972
        $tabfield = [];
973
        $tabfield[32] = "code,label,range_account,category_type,formula,position,country";
974
975
// Name of editing fields for record modification
976
        $tabfieldvalue = [];
977
        $tabfieldvalue[32] = "code,label,range_account,category_type,formula,position,country_id";
978
979
// Name of the fields in the table for inserting a record
980
        $tabfieldinsert = [];
981
        $tabfieldinsert[32] = "code,label,range_account,category_type,formula,position,fk_country";
982
983
// Name of the rowid if the field is not of type autoincrement
984
// Example: "" if id field is "rowid" and has autoincrement on
985
//          "nameoffield" if id field is not "rowid" or has not autoincrement on
986
        $tabrowid = [];
987
        $tabrowid[32] = "";
988
989
// Condition to show dictionary in setup page
990
        $tabcond = [];
991
        $tabcond[32] = isModEnabled('accounting');
992
993
// List of help for fields
994
        $tabhelp = [];
995
        $tabhelp[32] = ['code' => $langs->trans("EnterAnyCode"), 'category_type' => $langs->trans("SetToYesIfGroupIsComputationOfOtherGroups"), 'formula' => $langs->trans("EnterCalculationRuleIfPreviousFieldIsYes")];
996
997
// List of check for fields (NOT USED YET)
998
        $tabfieldcheck = [];
999
        $tabfieldcheck[32] = [];
1000
1001
// Complete all arrays with entries found into modules
1002
        complete_dictionary_with_modules($taborder, $tabname, $tablib, $tabsql, $tabsqlsort, $tabfield, $tabfieldvalue, $tabfieldinsert, $tabrowid, $tabcond, $tabhelp, $tabfieldcheck);
1003
1004
        $accountingcategory = new AccountancyCategory($db);
1005
1006
1007
        /*
1008
         * Actions
1009
         */
1010
1011
        if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) {
1012
            $search_country_id = '';
1013
        }
1014
1015
// Actions add or modify an entry into a dictionary
1016
        if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
1017
            $listfield = explode(',', str_replace(' ', '', $tabfield[$id]));
1018
            $listfieldinsert = explode(',', $tabfieldinsert[$id]);
1019
            $listfieldmodify = explode(',', $tabfieldinsert[$id]);
1020
            $listfieldvalue = explode(',', $tabfieldvalue[$id]);
1021
1022
            // Check that all fields are filled
1023
            $ok = 1;
1024
            foreach ($listfield as $f => $value) {
1025
                if ($value == 'formula' && !GETPOST('formula')) {
1026
                    continue;
1027
                }
1028
                if ($value == 'range_account' && !GETPOST('range_account')) {
1029
                    continue;
1030
                }
1031
                if (($value == 'country' || $value == 'country_id') && GETPOST('country_id')) {
1032
                    continue;
1033
                }
1034
                if (!GETPOSTISSET($value) || GETPOST($value) == '') {
1035
                    $ok = 0;
1036
                    $fieldnamekey = $listfield[$f];
1037
                    // We take translate key of field
1038
                    if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) {
1039
                        $fieldnamekey = 'Label';
1040
                    }
1041
                    if ($fieldnamekey == 'code') {
1042
                        $fieldnamekey = 'Code';
1043
                    }
1044
                    if ($fieldnamekey == 'note') {
1045
                        $fieldnamekey = 'Note';
1046
                    }
1047
                    if ($fieldnamekey == 'type') {
1048
                        $fieldnamekey = 'Type';
1049
                    }
1050
                    if ($fieldnamekey == 'position') {
1051
                        $fieldnamekey = 'Position';
1052
                    }
1053
                    if ($fieldnamekey == 'category_type') {
1054
                        $fieldnamekey = 'Calculated';
1055
                    }
1056
                    if ($fieldnamekey == 'country') {
1057
                        $fieldnamekey = 'Country';
1058
                    }
1059
1060
                    setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors');
1061
                }
1062
            }
1063
            if (GETPOSTISSET("code")) {
1064
                if (GETPOST("code") == '0') {
1065
                    $ok = 0;
1066
                    setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
1067
                }
1068
            }
1069
            if (GETPOST('position') && !is_numeric(GETPOST('position', 'alpha'))) {
1070
                $langs->loadLangs(["errors"]);
1071
                $ok = 0;
1072
                setEventMessages($langs->transnoentities('ErrorFieldMustBeANumeric', $langs->transnoentities("Position")), null, 'errors');
1073
            }
1074
1075
            // Si verif ok et action add, on ajoute la ligne
1076
            if ($ok && GETPOST('actionadd', 'alpha')) {
1077
                $newid = 0;
1078
1079
                if ($tabrowid[$id]) {
1080
                    // Get free id for insert
1081
                    $sql = "SELECT MAX(" . $db->sanitize($tabrowid[$id]) . ") newid FROM " . $db->sanitize($tabname[$id]);
1082
                    $result = $db->query($sql);
1083
                    if ($result) {
1084
                        $obj = $db->fetch_object($result);
1085
                        $newid = ($obj->newid + 1);
1086
                    } else {
1087
                        dol_print_error($db);
1088
                    }
1089
                }
1090
1091
                // Add new entry
1092
                $sql = "INSERT INTO " . $db->sanitize($tabname[$id]) . " (";
1093
                // List of fields
1094
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
1095
                    $sql .= $db->sanitize($tabrowid[$id]) . ",";
1096
                }
1097
                $sql .= $db->sanitize($tabfieldinsert[$id]);
1098
                $sql .= ",active)";
1099
                $sql .= " VALUES(";
1100
1101
                // List of values
1102
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
1103
                    $sql .= $newid . ",";
1104
                }
1105
                $i = 0;
1106
                foreach ($listfieldinsert as $f => $value) {
1107
                    if ($value == 'entity') {
1108
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
1109
                    }
1110
                    if ($i) {
1111
                        $sql .= ",";
1112
                    }
1113
                    if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'formula') {
1114
                        $sql .= "null"; // For vat, we want/accept code = ''
1115
                    } else {
1116
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
1117
                    }
1118
                    $i++;
1119
                }
1120
                $sql .= ",1)";
1121
1122
                dol_syslog("actionadd", LOG_DEBUG);
1123
                $result = $db->query($sql);
1124
                if ($result) {  // Add is ok
1125
                    setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
1126
                    $_POST = ['id' => $id]; // Clean $_POST array, we keep only
1127
                } else {
1128
                    if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1129
                        setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
1130
                    } else {
1131
                        dol_print_error($db);
1132
                    }
1133
                }
1134
            }
1135
1136
            // If check ok and action modify, we modify the line
1137
            if ($ok && GETPOST('actionmodify', 'alpha')) {
1138
                if ($tabrowid[$id]) {
1139
                    $rowidcol = $tabrowid[$id];
1140
                } else {
1141
                    $rowidcol = "rowid";
1142
                }
1143
1144
                // Modify entry
1145
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET ";
1146
                // Modifie valeur des champs
1147
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) {
1148
                    $sql .= $db->sanitize($tabrowid[$id]) . " = ";
1149
                    $sql .= "'" . $db->escape($rowid) . "', ";
1150
                }
1151
                $i = 0;
1152
                foreach ($listfieldmodify as $field) {
1153
                    if ($field == 'fk_country' && GETPOST('country') > 0) {
1154
                        $_POST[$listfieldvalue[$i]] = GETPOST('country');
1155
                    } elseif ($field == 'entity') {
1156
                        $_POST[$listfieldvalue[$i]] = $conf->entity;
1157
                    }
1158
                    if ($i) {
1159
                        $sql .= ",";
1160
                    }
1161
                    $sql .= $field . "=";
1162
                    if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'range_account') {
1163
                        $sql .= "null"; // For range_account, we want/accept code = ''
1164
                    } else {
1165
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
1166
                    }
1167
                    $i++;
1168
                }
1169
                $sql .= " WHERE " . $rowidcol . " = " . ((int) $rowid);
1170
1171
                dol_syslog("actionmodify", LOG_DEBUG);
1172
                //print $sql;
1173
                $resql = $db->query($sql);
1174
                if (!$resql) {
1175
                    setEventMessages($db->error(), null, 'errors');
1176
                }
1177
            }
1178
            //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
1179
        }
1180
1181
// if (GETPOST('actioncancel', 'alpha')) {
1182
//  $_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
1183
// }
1184
1185
        if ($action == 'confirm_delete' && $confirm == 'yes') {       // delete
1186
            $rowidcol = "rowid";
1187
1188
            $sql = "DELETE from " . $db->sanitize($tabname[$id]) . " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
1189
1190
            dol_syslog("delete", LOG_DEBUG);
1191
            $result = $db->query($sql);
1192
            if (!$result) {
1193
                if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') {
1194
                    setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors');
1195
                } else {
1196
                    dol_print_error($db);
1197
                }
1198
            }
1199
        }
1200
1201
// activate
1202
        if ($action == $acts[0]) {
1203
            $rowidcol = "rowid";
1204
1205
            if ($rowid) {
1206
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
1207
            } elseif ($code) {
1208
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE code = '" . $db->escape($code) . "'";
1209
            }
1210
1211
            if ($sql) {
1212
                $result = $db->query($sql);
1213
                if (!$result) {
1214
                    dol_print_error($db);
1215
                }
1216
            }
1217
        }
1218
1219
// disable
1220
        if ($action == $acts[1]) {
1221
            $rowidcol = "rowid";
1222
1223
            if ($rowid) {
1224
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
1225
            } elseif ($code) {
1226
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE code = '" . $db->escape($code) . "'";
1227
            }
1228
1229
            if ($sql) {
1230
                $result = $db->query($sql);
1231
                if (!$result) {
1232
                    dol_print_error($db);
1233
                }
1234
            }
1235
        }
1236
1237
// favorite
1238
        if ($action == 'activate_favorite') {
1239
            $rowidcol = "rowid";
1240
1241
            if ($rowid) {
1242
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 1 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
1243
            } elseif ($code) {
1244
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 1 WHERE code = '" . $db->escape($code) . "'";
1245
            }
1246
1247
            if ($sql) {
1248
                $result = $db->query($sql);
1249
                if (!$result) {
1250
                    dol_print_error($db);
1251
                }
1252
            }
1253
        }
1254
1255
// disable favorite
1256
        if ($action == 'disable_favorite') {
1257
            $rowidcol = "rowid";
1258
1259
            if ($rowid) {
1260
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 0 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
1261
            } elseif ($code) {
1262
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET favorite = 0 WHERE code = '" . $db->escape($code) . "'";
1263
            }
1264
1265
            if ($sql) {
1266
                $result = $db->query($sql);
1267
                if (!$result) {
1268
                    dol_print_error($db);
1269
                }
1270
            }
1271
        }
1272
1273
1274
        /*
1275
         * View
1276
         */
1277
1278
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_categories_list.php');
1279
1280
        $db->close();
1281
        return true;
1282
    }
1283
1284
1285
    /**
1286
     *  Show fields in insert/edit mode
1287
     *
1288
     * @param array  $fieldlist Array of fields
1289
     * @param Object $obj       If we show a particular record, obj is filled with record fields
1290
     * @param string $tabname   Name of SQL table
1291
     * @param string $context   'add'=Output field for the "add form", 'edit'=Output field for the "edit form",
1292
     *                          'hide'=Output field for the "add form" but we don't want it to be rendered
1293
     *
1294
     * @return     void
1295
     */
1296
    public function fieldListAccountingCategories($fieldlist, $obj = null, $tabname = '', $context = '')
1297
    {
1298
        global $conf, $langs, $db;
1299
        global $form, $mysoc;
1300
1301
        $formadmin = new FormAdmin($db);
1302
        $formcompany = new FormCompany($db);
1303
        if (isModEnabled('accounting')) {
1304
            $formaccounting = new FormAccounting($db);
1305
        }
1306
1307
        foreach ($fieldlist as $field => $value) {
1308
            if ($fieldlist[$field] == 'country') {
1309
                print '<td>';
1310
                $fieldname = 'country';
1311
                if ($context == 'add') {
1312
                    $fieldname = 'country_id';
1313
                    $preselectcountrycode = GETPOSTISSET('country_id') ? GETPOSTINT('country_id') : $mysoc->country_code;
1314
                    print $form->select_country($preselectcountrycode, $fieldname, '', 28, 'maxwidth150 maxwidthonsmartphone');
1315
                } else {
1316
                    $preselectcountrycode = (empty($obj->country_code) ? (empty($obj->country) ? $mysoc->country_code : $obj->country) : $obj->country_code);
1317
                    print $form->select_country($preselectcountrycode, $fieldname, '', 28, 'maxwidth150 maxwidthonsmartphone');
1318
                }
1319
                print '</td>';
1320
            } elseif ($fieldlist[$field] == 'country_id') {
1321
                if (!in_array('country', $fieldlist)) { // If there is already a field country, we don't show country_id (avoid duplicate)
1322
                    $country_id = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0);
1323
                    print '<td>';
1324
                    print '<input type="hidden" name="' . $fieldlist[$field] . '" value="' . $country_id . '">';
1325
                    print '</td>';
1326
                }
1327
            } elseif ($fieldlist[$field] == 'category_type') {
1328
                print '<td>';
1329
                print $form->selectyesno($fieldlist[$field], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''), 1);
1330
                print '</td>';
1331
            } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
1332
                print '<td><input type="text" class="flat minwidth100" value="' . (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '"></td>';
1333
            } else {
1334
                print '<td>';
1335
                $class = '';
1336
                if (in_array($fieldlist[$field], ['code', 'formula'])) {
1337
                    $class = 'maxwidth75';
1338
                }
1339
                if (in_array($fieldlist[$field], ['label', 'range_account'])) {
1340
                    $class = 'maxwidth150';
1341
                }
1342
                if ($fieldlist[$field] == 'position') {
1343
                    $class = 'maxwidth50';
1344
                }
1345
                print '<input type="text" class="flat' . ($class ? ' ' . $class : '') . '" value="' . (isset($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '">';
1346
                print '</td>';
1347
            }
1348
        }
1349
    }
1350
1351
    /**
1352
     * \file        htdocs/accountancy/admin/closure.php
1353
     * \ingroup     Accountancy (Double entries)
1354
     * \brief       Setup page to configure accounting expert module
1355
     */
1356
    public function closure()
1357
    {
1358
        global $conf;
1359
        global $db;
1360
        global $user;
1361
        global $hookmanager;
1362
        global $user;
1363
        global $menumanager;
1364
        global $langs;
1365
1366
// Load translation files required by the page
1367
        $langs->loadLangs(["compta", "admin", "accountancy"]);
1368
1369
// Security check
1370
        if (!$user->hasRight('accounting', 'chartofaccount')) {
1371
            accessforbidden();
1372
        }
1373
1374
        $action = GETPOST('action', 'aZ09');
1375
1376
1377
        $list_account_main = [
1378
            'ACCOUNTING_RESULT_PROFIT',
1379
            'ACCOUNTING_RESULT_LOSS',
1380
        ];
1381
1382
        /*
1383
         * Actions
1384
         */
1385
1386
        if ($action == 'update') {
1387
            $error = 0;
1388
1389
            $defaultjournal = GETPOST('ACCOUNTING_CLOSURE_DEFAULT_JOURNAL', 'alpha');
1390
1391
            if (!empty($defaultjournal)) {
1392
                if (!dolibarr_set_const($db, 'ACCOUNTING_CLOSURE_DEFAULT_JOURNAL', $defaultjournal, 'chaine', 0, '', $conf->entity)) {
1393
                    $error++;
1394
                }
1395
            } else {
1396
                $error++;
1397
            }
1398
1399
            $accountinggroupsusedforbalancesheetaccount = GETPOST('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT', 'alphanohtml');
1400
            if (!empty($accountinggroupsusedforbalancesheetaccount)) {
1401
                if (!dolibarr_set_const($db, 'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_BALANCE_SHEET_ACCOUNT', $accountinggroupsusedforbalancesheetaccount, 'chaine', 0, '', $conf->entity)) {
1402
                    $error++;
1403
                }
1404
            } else {
1405
                $error++;
1406
            }
1407
1408
            $accountinggroupsusedforincomestatement = GETPOST('ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT', 'alpha');
1409
            if (!empty($accountinggroupsusedforincomestatement)) {
1410
                if (!dolibarr_set_const($db, 'ACCOUNTING_CLOSURE_ACCOUNTING_GROUPS_USED_FOR_INCOME_STATEMENT', $accountinggroupsusedforincomestatement, 'chaine', 0, '', $conf->entity)) {
1411
                    $error++;
1412
                }
1413
            } else {
1414
                $error++;
1415
            }
1416
1417
            foreach ($list_account_main as $constname) {
1418
                $constvalue = GETPOST($constname, 'alpha');
1419
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
1420
                    $error++;
1421
                }
1422
            }
1423
1424
            if (!$error) {
1425
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
1426
            } else {
1427
                setEventMessages($langs->trans("Error"), null, 'errors');
1428
            }
1429
        }
1430
1431
1432
        /*
1433
         * View
1434
         */
1435
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_closure.php');
1436
1437
        $db->close();
1438
        return true;
1439
    }
1440
1441
    /**
1442
     * \file        htdocs/accountancy/admin/defaultaccounts.php
1443
     * \ingroup     Accountancy (Double entries)
1444
     * \brief       Setup page to configure accounting expert module
1445
     */
1446
    public function defaultaccounts()
1447
    {
1448
        global $conf;
1449
        global $db;
1450
        global $user;
1451
        global $hookmanager;
1452
        global $user;
1453
        global $menumanager;
1454
        global $langs;
1455
        global $mysoc;
1456
1457
// Load translation files required by the page
1458
        $langs->loadLangs(["compta", "bills", "admin", "accountancy", "salaries", "loan"]);
1459
1460
// Security check
1461
        if (!$user->hasRight('accounting', 'chartofaccount')) {
1462
            accessforbidden();
1463
        }
1464
1465
        $action = GETPOST('action', 'aZ09');
1466
1467
1468
        $list_account_main = [
1469
            'ACCOUNTING_ACCOUNT_CUSTOMER',
1470
            'ACCOUNTING_ACCOUNT_SUPPLIER',
1471
            'SALARIES_ACCOUNTING_ACCOUNT_PAYMENT',
1472
        ];
1473
1474
        $list_account = [];
1475
1476
        $list_account[] = '---Product---';
1477
        $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_ACCOUNT';
1478
        if ($mysoc->isInEEC()) {
1479
            $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT';
1480
        }
1481
        $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT';
1482
        $list_account[] = 'ACCOUNTING_PRODUCT_BUY_ACCOUNT';
1483
        if ($mysoc->isInEEC()) {
1484
            $list_account[] = 'ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT';
1485
        }
1486
        $list_account[] = 'ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT';
1487
1488
        $list_account[] = '---Service---';
1489
        $list_account[] = 'ACCOUNTING_SERVICE_SOLD_ACCOUNT';
1490
        if ($mysoc->isInEEC()) {
1491
            $list_account[] = 'ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT';
1492
        }
1493
        $list_account[] = 'ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT';
1494
        $list_account[] = 'ACCOUNTING_SERVICE_BUY_ACCOUNT';
1495
        if ($mysoc->isInEEC()) {
1496
            $list_account[] = 'ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT';
1497
        }
1498
        $list_account[] = 'ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT';
1499
1500
        $list_account[] = '---Others---';
1501
        $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT';
1502
        $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT';
1503
1504
        /*if ($mysoc->useRevenueStamp()) {
1505
            $list_account[] = 'ACCOUNTING_REVENUESTAMP_SOLD_ACCOUNT';
1506
            $list_account[] = 'ACCOUNTING_REVENUESTAMP_BUY_ACCOUNT';
1507
        }*/
1508
1509
        $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT';
1510
1511
        if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
1512
            $list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT';
1513
            $list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT';
1514
        }
1515
        if (isModEnabled('bank')) {
1516
            $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH';
1517
        }
1518
        if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY')) {
1519
            $list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY';
1520
        }
1521
        if (isModEnabled('don')) {
1522
            $list_account[] = 'DONATION_ACCOUNTINGACCOUNT';
1523
        }
1524
        if (isModEnabled('member')) {
1525
            $list_account[] = 'ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT';
1526
        }
1527
        if (isModEnabled('loan')) {
1528
            $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL';
1529
            $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INTEREST';
1530
            $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE';
1531
        }
1532
        $list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE';
1533
        if (isModEnabled('societe')) {
1534
            $list_account[] = '---Deposits---';
1535
        }
1536
1537
        /*
1538
         * Actions
1539
         */
1540
1541
        if ($action == 'update') {
1542
            $error = 0;
1543
            // Process $list_account_main
1544
            foreach ($list_account_main as $constname) {
1545
                $constvalue = GETPOST($constname, 'alpha');
1546
1547
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
1548
                    $error++;
1549
                }
1550
            }
1551
            // Process $list_account
1552
            foreach ($list_account as $constname) {
1553
                $reg = [];
1554
                if (preg_match('/---(.*)---/', $constname, $reg)) { // This is a separator
1555
                    continue;
1556
                }
1557
1558
                $constvalue = GETPOST($constname, 'alpha');
1559
1560
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
1561
                    $error++;
1562
                }
1563
            }
1564
1565
            $constname = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT';
1566
            $constvalue = GETPOSTINT($constname);
1567
            if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
1568
                $error++;
1569
            }
1570
1571
            $constname = 'ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT';
1572
            $constvalue = GETPOSTINT($constname);
1573
            if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
1574
                $error++;
1575
            }
1576
1577
1578
            if (!$error) {
1579
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
1580
            } else {
1581
                setEventMessages($langs->trans("Error"), null, 'errors');
1582
            }
1583
        }
1584
1585
        if ($action == 'setACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT') {
1586
            $setDisableAuxiliaryAccountOnCustomerDeposit = GETPOSTINT('value');
1587
            $res = dolibarr_set_const($db, "ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT", $setDisableAuxiliaryAccountOnCustomerDeposit, 'yesno', 0, '', $conf->entity);
1588
            if (!($res > 0)) {
1589
                $error++;
1590
            }
1591
1592
            if (!$error) {
1593
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
1594
            } else {
1595
                setEventMessages($langs->trans("Error"), null, 'mesgs');
1596
            }
1597
        }
1598
1599
        if ($action == 'setACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT') {
1600
            $setDisableAuxiliaryAccountOnSupplierDeposit = GETPOSTINT('value');
1601
            $res = dolibarr_set_const($db, "ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT", $setDisableAuxiliaryAccountOnSupplierDeposit, 'yesno', 0, '', $conf->entity);
1602
            if (!($res > 0)) {
1603
                $error++;
1604
            }
1605
1606
            if (!$error) {
1607
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
1608
            } else {
1609
                setEventMessages($langs->trans("Error"), null, 'mesgs');
1610
            }
1611
        }
1612
1613
1614
        /*
1615
         * View
1616
         */
1617
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_defaultaccounts.php');
1618
1619
        $db->close();
1620
        return true;
1621
    }
1622
1623
    /**
1624
     * \file        htdocs/accountancy/admin/export.php
1625
     * \ingroup     Accountancy (Double entries)
1626
     * \brief       Setup page to configure accounting export module
1627
     */
1628
    public function export()
1629
    {
1630
        global $conf;
1631
        global $db;
1632
        global $user;
1633
        global $hookmanager;
1634
        global $user;
1635
        global $menumanager;
1636
        global $langs;
1637
1638
// Load translation files required by the page
1639
        $langs->loadLangs(["compta", "bills", "admin", "accountancy"]);
1640
1641
// Security access
1642
        if (!$user->hasRight('accounting', 'chartofaccount')) {
1643
            accessforbidden();
1644
        }
1645
1646
        $action = GETPOST('action', 'aZ09');
1647
1648
// Parameters ACCOUNTING_EXPORT_*
1649
        $main_option = [
1650
            'ACCOUNTING_EXPORT_PREFIX_SPEC',
1651
        ];
1652
1653
        $accountancyexport = new AccountancyExport($db);
1654
        $configuration = $accountancyexport->getTypeConfig();
1655
1656
        $listparam = $configuration['param'];
1657
1658
        $listformat = $configuration['format'];
1659
1660
        $listcr = $configuration['cr'];
1661
1662
1663
        $model_option = [
1664
            '1' => [
1665
                'label' => 'ACCOUNTING_EXPORT_FORMAT',
1666
                'param' => $listformat,
1667
            ],
1668
            '2' => [
1669
                'label' => 'ACCOUNTING_EXPORT_SEPARATORCSV',
1670
                'param' => '',
1671
            ],
1672
            '3' => [
1673
                'label' => 'ACCOUNTING_EXPORT_ENDLINE',
1674
                'param' => $listcr,
1675
            ],
1676
            '4' => [
1677
                'label' => 'ACCOUNTING_EXPORT_DATE',
1678
                'param' => '',
1679
            ],
1680
        ];
1681
1682
1683
        /*
1684
         * Actions
1685
         */
1686
1687
        if ($action == 'update') {
1688
            $error = 0;
1689
1690
            $modelcsv = GETPOSTINT('ACCOUNTING_EXPORT_MODELCSV');
1691
1692
            if (!empty($modelcsv)) {
1693
                if (!dolibarr_set_const($db, 'ACCOUNTING_EXPORT_MODELCSV', $modelcsv, 'chaine', 0, '', $conf->entity)) {
1694
                    $error++;
1695
                }
1696
                //if ($modelcsv==AccountancyExport::$EXPORT_TYPE_QUADRATUS || $modelcsv==AccountancyExport::$EXPORT_TYPE_CIEL) {
1697
                //  dolibarr_set_const($db, 'ACCOUNTING_EXPORT_FORMAT', 'txt', 'chaine', 0, '', $conf->entity);
1698
                //}
1699
            } else {
1700
                $error++;
1701
            }
1702
1703
            foreach ($main_option as $constname) {
1704
                $constvalue = GETPOST($constname, 'alpha');
1705
1706
                if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
1707
                    $error++;
1708
                }
1709
            }
1710
1711
            foreach ($listparam[$modelcsv] as $key => $value) {
1712
                $constante = $key;
1713
1714
                if (strpos($constante, 'ACCOUNTING') !== false) {
1715
                    $constvalue = GETPOST($key, 'alpha');
1716
                    if (!dolibarr_set_const($db, $constante, $constvalue, 'chaine', 0, '', $conf->entity)) {
1717
                        $error++;
1718
                    }
1719
                }
1720
            }
1721
1722
            if (!$error) {
1723
                // reload
1724
                $configuration = $accountancyexport->getTypeConfig();
1725
                $listparam = $configuration['param'];
1726
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
1727
            } else {
1728
                setEventMessages($langs->trans("Error"), null, 'errors');
1729
            }
1730
        }
1731
1732
1733
        /*
1734
         * View
1735
         */
1736
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_export.php');
1737
1738
        $db->close();
1739
        return true;
1740
    }
1741
1742
    /**
1743
     *  \file       htdocs/accountancy/admin/fiscalyear.php
1744
     *  \ingroup    Accountancy (Double entries)
1745
     *  \brief      Setup page to configure fiscal year
1746
     */
1747
    public function fiscalyear()
1748
    {
1749
        global $conf;
1750
        global $db;
1751
        global $user;
1752
        global $hookmanager;
1753
        global $user;
1754
        global $menumanager;
1755
        global $langs;
1756
1757
        $action = GETPOST('action', 'aZ09');
1758
1759
// Load variable for pagination
1760
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
1761
        $sortfield = GETPOST('sortfield', 'aZ09comma');
1762
        $sortorder = GETPOST('sortorder', 'aZ09comma');
1763
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
1764
        if (empty($page) || $page == -1) {
1765
            $page = 0;
1766
        }     // If $page is not defined, or '' or -1
1767
        $offset = $limit * $page;
1768
        $pageprev = $page - 1;
1769
        $pagenext = $page + 1;
1770
        if (!$sortfield) {
1771
            $sortfield = "f.rowid"; // Set here default search field
1772
        }
1773
        if (!$sortorder) {
1774
            $sortorder = "ASC";
1775
        }
1776
1777
// Load translation files required by the page
1778
        $langs->loadLangs(["admin", "compta"]);
1779
1780
        $error = 0;
1781
        $errors = [];
1782
1783
// List of status
1784
        static $tmpstatut2label = [
1785
            '0' => 'OpenFiscalYear',
1786
            '1' => 'CloseFiscalYear',
1787
        ];
1788
1789
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1790
        $object = new Fiscalyear($db);
1791
        $hookmanager->initHooks(['fiscalyearlist']);
1792
1793
// Security check
1794
        if ($user->socid > 0) {
1795
            accessforbidden();
1796
        }
1797
        if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {              // If we can read accounting records, we should be able to see fiscal year.
1798
            accessforbidden();
1799
        }
1800
1801
        /*
1802
         * Actions
1803
         */
1804
1805
1806
        /*
1807
         * View
1808
         */
1809
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_fiscalyear.php');
1810
1811
        $db->close();
1812
        return true;
1813
    }
1814
1815
    /**
1816
     * \file        htdocs/accountancy/admin/fiscalyear_card.php
1817
     * \ingroup     Accountancy (Double entries)
1818
     * \brief       Page to show a fiscal year
1819
     */
1820
    public function fiscalyear_card()
1821
    {
1822
        global $conf;
1823
        global $db;
1824
        global $user;
1825
        global $hookmanager;
1826
        global $user;
1827
        global $menumanager;
1828
        global $langs;
1829
1830
// Load translation files required by the page
1831
        $langs->loadLangs(["admin", "compta"]);
1832
1833
// Get parameters
1834
        $id = GETPOSTINT('id');
1835
        $ref = GETPOST('ref', 'alpha');
1836
1837
        $action = GETPOST('action', 'aZ09');
1838
        $confirm = GETPOST('confirm', 'alpha');
1839
        $cancel = GETPOST('cancel', 'aZ09');
1840
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)) . basename(__FILE__, '.php')); // To manage different context of search
1841
        $backtopage = GETPOST('backtopage', 'alpha');                   // if not set, a default page will be used
1842
        $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
1843
        $backtopagejsfields = GETPOST('backtopagejsfields', 'alpha');
1844
        $dol_openinpopup = GETPOST('dol_openinpopup', 'aZ09');
1845
1846
        if (!empty($backtopagejsfields)) {
1847
            $tmpbacktopagejsfields = explode(':', $backtopagejsfields);
1848
            $dol_openinpopup = $tmpbacktopagejsfields[0];
1849
        }
1850
1851
        $error = 0;
1852
1853
// Initialize technical objects
1854
        $object = new Fiscalyear($db);
1855
        $extrafields = new ExtraFields($db);
1856
1857
// Load object
1858
        include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
1859
1860
// List of status
1861
        static $tmpstatus2label = [
1862
            '0' => 'OpenFiscalYear',
1863
            '1' => 'CloseFiscalYear',
1864
        ];
1865
        $status2label = [
1866
            '',
1867
        ];
1868
        foreach ($tmpstatus2label as $key => $val) {
1869
            $status2label[$key] = $langs->trans($val);
1870
        }
1871
1872
        $date_start = dol_mktime(0, 0, 0, GETPOSTINT('fiscalyearmonth'), GETPOSTINT('fiscalyearday'), GETPOSTINT('fiscalyearyear'));
1873
        $date_end = dol_mktime(0, 0, 0, GETPOSTINT('fiscalyearendmonth'), GETPOSTINT('fiscalyearendday'), GETPOSTINT('fiscalyearendyear'));
1874
1875
        $permissiontoadd = $user->hasRight('accounting', 'fiscalyear', 'write');
1876
1877
// Security check
1878
        if ($user->socid > 0) {
1879
            accessforbidden();
1880
        }
1881
        if (!$permissiontoadd) {
1882
            accessforbidden();
1883
        }
1884
1885
1886
        /*
1887
         * Actions
1888
         */
1889
1890
        $parameters = [];
1891
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
1892
        if ($reshook < 0) {
1893
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1894
        }
1895
1896
        if ($action == 'confirm_delete' && $confirm == "yes") {
1897
            $result = $object->delete($user);
1898
            if ($result >= 0) {
1899
                header("Location: fiscalyear.php");
1900
                exit();
1901
            } else {
1902
                setEventMessages($object->error, $object->errors, 'errors');
1903
            }
1904
        } elseif ($action == 'add') {
1905
            if (!GETPOST('cancel', 'alpha')) {
1906
                $error = 0;
1907
1908
                $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...
1909
                $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...
1910
                $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...
1911
                $object->status = GETPOSTINT('status');
1912
                $object->datec = dol_now();
1913
1914
                if (empty($object->date_start) && empty($object->date_end)) {
1915
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
1916
                    $error++;
1917
                }
1918
                if (empty($object->label)) {
1919
                    setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
1920
                    $error++;
1921
                }
1922
1923
                if (!$error) {
1924
                    $db->begin();
1925
1926
                    $id = $object->create($user);
1927
1928
                    if ($id > 0) {
1929
                        $db->commit();
1930
1931
                        header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
1932
                        exit();
1933
                    } else {
1934
                        $db->rollback();
1935
1936
                        setEventMessages($object->error, $object->errors, 'errors');
1937
                        $action = 'create';
1938
                    }
1939
                } else {
1940
                    $action = 'create';
1941
                }
1942
            } else {
1943
                header("Location: ./fiscalyear.php");
1944
                exit();
1945
            }
1946
        } elseif ($action == 'update') {
1947
            // Update record
1948
            if (!GETPOST('cancel', 'alpha')) {
1949
                $result = $object->fetch($id);
1950
1951
                $object->date_start = GETPOST("fiscalyear") ? $date_start : '';
1952
                $object->date_end = GETPOST("fiscalyearend") ? $date_end : '';
1953
                $object->label = GETPOST('label', 'alpha');
1954
                $object->status = GETPOSTINT('status');
1955
1956
                $result = $object->update($user);
1957
1958
                if ($result > 0) {
1959
                    header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
1960
                    exit();
1961
                } else {
1962
                    setEventMessages($object->error, $object->errors, 'errors');
1963
                }
1964
            } else {
1965
                header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id);
1966
                exit();
1967
            }
1968
        }
1969
1970
1971
        /*
1972
         * View
1973
         */
1974
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_fiscalyear_card.php');
1975
1976
        $db->close();
1977
        return true;
1978
    }
1979
1980
    /**
1981
     * \file        htdocs/accountancy/admin/fiscalyear_info.php
1982
     * \ingroup     Accountancy (Double entries)
1983
     * \brief       Page to show info of a fiscal year
1984
     */
1985
    public function fiscalyear_info()
1986
    {
1987
        global $conf;
1988
        global $db;
1989
        global $user;
1990
        global $hookmanager;
1991
        global $user;
1992
        global $menumanager;
1993
        global $langs;
1994
1995
// Load translation files required by the page
1996
        $langs->loadLangs(["admin", "compta"]);
1997
1998
// Security check
1999
        if ($user->socid > 0) {
2000
            accessforbidden();
2001
        }
2002
        if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {
2003
            accessforbidden();
2004
        }
2005
2006
        $id = GETPOSTINT('id');
2007
2008
        /*
2009
         * View
2010
         */
2011
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_fiscalyear_info.php');
2012
2013
        $db->close();
2014
        return true;
2015
    }
2016
2017
    /**
2018
     * \file        htdocs/accountancy/admin/index.php
2019
     * \ingroup     Accountancy (Double entries)
2020
     * \brief       Setup page to configure accounting expert module
2021
     */
2022
    public function index(bool $executeActions = true): bool
2023
    {
2024
        global $conf;
2025
        global $db;
2026
        global $user;
2027
        global $hookmanager;
2028
        global $user;
2029
        global $menumanager;
2030
        global $langs;
2031
2032
// Load translation files required by the page
2033
        $langs->loadLangs(["compta", "bills", "admin", "accountancy", "other"]);
2034
2035
// Security access
2036
        if (!$user->hasRight('accounting', 'chartofaccount')) {
2037
            accessforbidden();
2038
        }
2039
2040
        $action = GETPOST('action', 'aZ09');
2041
2042
        $nbletter = GETPOSTINT('ACCOUNTING_LETTERING_NBLETTERS');
2043
2044
// Parameters ACCOUNTING_* and others
2045
        $list = [
2046
            'ACCOUNTING_LENGTH_GACCOUNT',
2047
            'ACCOUNTING_LENGTH_AACCOUNT',
2048
//  '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.
2049
//  'ACCOUNTING_LENGTH_DESCRIPTION',         // adjust size displayed for lines description for dol_trunc
2050
//  'ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT', // adjust size displayed for select account description for dol_trunc
2051
        ];
2052
2053
        $list_binding = [
2054
            'ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER',
2055
            'ACCOUNTING_DATE_START_BINDING',
2056
        ];
2057
2058
        $error = 0;
2059
2060
2061
        /*
2062
         * Actions
2063
         */
2064
2065
        if (in_array($action, ['setBANK_DISABLE_DIRECT_INPUT', 'setACCOUNTANCY_COMBO_FOR_AUX', 'setACCOUNTING_MANAGE_ZERO'])) {
2066
            $constname = preg_replace('/^set/', '', $action);
2067
            $constvalue = GETPOSTINT('value');
2068
            $res = dolibarr_set_const($db, $constname, $constvalue, 'yesno', 0, '', $conf->entity);
2069
            if (!($res > 0)) {
2070
                $error++;
2071
            }
2072
2073
            if (!$error) {
2074
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2075
            } else {
2076
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2077
            }
2078
        }
2079
2080
        if ($action == 'update') {
2081
            $error = 0;
2082
2083
            if (!$error) {
2084
                foreach ($list as $constname) {
2085
                    $constvalue = GETPOST($constname, 'alpha');
2086
                    if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
2087
                        $error++;
2088
                    }
2089
                }
2090
                if ($error) {
2091
                    setEventMessages($langs->trans("Error"), null, 'errors');
2092
                }
2093
2094
                // option in section binding
2095
                foreach ($list_binding as $constname) {
2096
                    $constvalue = GETPOST($constname, 'alpha');
2097
2098
                    if ($constname == 'ACCOUNTING_DATE_START_BINDING') {
2099
                        $constvalue = dol_mktime(0, 0, 0, GETPOSTINT($constname . 'month'), GETPOSTINT($constname . 'day'), GETPOSTINT($constname . 'year'));
2100
                    }
2101
2102
                    if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
2103
                        $error++;
2104
                    }
2105
                }
2106
2107
                // options in section other
2108
                if (GETPOSTISSET('ACCOUNTING_LETTERING_NBLETTERS')) {
2109
                    if (!dolibarr_set_const($db, 'ACCOUNTING_LETTERING_NBLETTERS', GETPOST('ACCOUNTING_LETTERING_NBLETTERS'), 'chaine', 0, '', $conf->entity)) {
2110
                        $error++;
2111
                    }
2112
                }
2113
2114
                if ($error) {
2115
                    setEventMessages($langs->trans("Error"), null, 'errors');
2116
                }
2117
            }
2118
2119
            if (!$error) {
2120
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2121
            }
2122
        }
2123
2124
        if ($action == 'setmanagezero') {
2125
            $setmanagezero = GETPOSTINT('value');
2126
            $res = dolibarr_set_const($db, "ACCOUNTING_MANAGE_ZERO", $setmanagezero, 'yesno', 0, '', $conf->entity);
2127
            if (!($res > 0)) {
2128
                $error++;
2129
            }
2130
2131
            if (!$error) {
2132
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2133
            } else {
2134
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2135
            }
2136
        }
2137
2138
        if ($action == 'setdisabledirectinput') {
2139
            $setdisabledirectinput = GETPOSTINT('value');
2140
            $res = dolibarr_set_const($db, "BANK_DISABLE_DIRECT_INPUT", $setdisabledirectinput, 'yesno', 0, '', $conf->entity);
2141
            if (!($res > 0)) {
2142
                $error++;
2143
            }
2144
2145
            if (!$error) {
2146
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2147
            } else {
2148
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2149
            }
2150
        }
2151
2152
        if ($action == 'setenabledraftexport') {
2153
            $setenabledraftexport = GETPOSTINT('value');
2154
            $res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL", $setenabledraftexport, 'yesno', 0, '', $conf->entity);
2155
            if (!($res > 0)) {
2156
                $error++;
2157
            }
2158
2159
            if (!$error) {
2160
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2161
            } else {
2162
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2163
            }
2164
        }
2165
2166
        if ($action == 'setenablesubsidiarylist') {
2167
            $setenablesubsidiarylist = GETPOSTINT('value');
2168
            $res = dolibarr_set_const($db, "ACCOUNTANCY_COMBO_FOR_AUX", $setenablesubsidiarylist, 'yesno', 0, '', $conf->entity);
2169
            if (!($res > 0)) {
2170
                $error++;
2171
            }
2172
2173
            if (!$error) {
2174
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2175
            } else {
2176
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2177
            }
2178
        }
2179
2180
        if ($action == 'setdisablebindingonsales') {
2181
            $setdisablebindingonsales = GETPOSTINT('value');
2182
            $res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_BINDING_ON_SALES", $setdisablebindingonsales, 'yesno', 0, '', $conf->entity);
2183
            if (!($res > 0)) {
2184
                $error++;
2185
            }
2186
2187
            if (!$error) {
2188
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2189
            } else {
2190
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2191
            }
2192
        }
2193
2194
        if ($action == 'setdisablebindingonpurchases') {
2195
            $setdisablebindingonpurchases = GETPOSTINT('value');
2196
            $res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_BINDING_ON_PURCHASES", $setdisablebindingonpurchases, 'yesno', 0, '', $conf->entity);
2197
            if (!($res > 0)) {
2198
                $error++;
2199
            }
2200
2201
            if (!$error) {
2202
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2203
            } else {
2204
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2205
            }
2206
        }
2207
2208
        if ($action == 'setdisablebindingonexpensereports') {
2209
            $setdisablebindingonexpensereports = GETPOSTINT('value');
2210
            $res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS", $setdisablebindingonexpensereports, 'yesno', 0, '', $conf->entity);
2211
            if (!($res > 0)) {
2212
                $error++;
2213
            }
2214
2215
            if (!$error) {
2216
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2217
            } else {
2218
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2219
            }
2220
        }
2221
2222
        if ($action == 'setenablelettering') {
2223
            $setenablelettering = GETPOSTINT('value');
2224
            $res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_LETTERING", $setenablelettering, 'yesno', 0, '', $conf->entity);
2225
            if (!($res > 0)) {
2226
                $error++;
2227
            }
2228
2229
            if (!$error) {
2230
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2231
            } else {
2232
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2233
            }
2234
        }
2235
2236
        if ($action == 'setenableautolettering') {
2237
            $setenableautolettering = GETPOSTINT('value');
2238
            $res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_AUTOLETTERING", $setenableautolettering, 'yesno', 0, '', $conf->entity);
2239
            if (!($res > 0)) {
2240
                $error++;
2241
            }
2242
2243
            if (!$error) {
2244
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2245
            } else {
2246
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2247
            }
2248
        }
2249
2250
        if ($action == 'setenablevatreversecharge') {
2251
            $setenablevatreversecharge = GETPOSTINT('value');
2252
            $res = dolibarr_set_const($db, "ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE", $setenablevatreversecharge, 'yesno', 0, '', $conf->entity);
2253
            if (!($res > 0)) {
2254
                $error++;
2255
            }
2256
2257
            if (!$error) {
2258
                setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
2259
            } else {
2260
                setEventMessages($langs->trans("Error"), null, 'mesgs');
2261
            }
2262
        }
2263
2264
2265
        /*
2266
         * View
2267
         */
2268
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_index.php');
2269
2270
        $db->close();
2271
2272
        return true;
2273
    }
2274
2275
    /**
2276
     * \file        htdocs/accountancy/admin/journals_list.php
2277
     * \ingroup     Accountancy (Double entries)
2278
     * \brief       Setup page to configure journals
2279
     */
2280
    public function journals_list()
2281
    {
2282
        global $conf;
2283
        global $db;
2284
        global $user;
2285
        global $hookmanager;
2286
        global $user;
2287
        global $menumanager;
2288
        global $langs;
2289
2290
        global $sourceList;
2291
2292
        defineIfNotDefined('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
2293
2294
// Load translation files required by the page
2295
        $langs->loadLangs(["admin", "compta", "accountancy"]);
2296
2297
        $action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view';
2298
        $confirm = GETPOST('confirm', 'alpha');
2299
        $id = 35;
2300
        $rowid = GETPOST('rowid', 'alpha');
2301
        $code = GETPOST('code', 'alpha');
2302
2303
// Security access
2304
        if (!$user->hasRight('accounting', 'chartofaccount')) {
2305
            accessforbidden();
2306
        }
2307
2308
        $acts = [];
2309
        $acts[0] = "activate";
2310
        $acts[1] = "disable";
2311
        $actl = [];
2312
        $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off', 'class="size15x"');
2313
        $actl[1] = img_picto($langs->trans("Activated"), 'switch_on', 'class="size15x"');
2314
2315
        $listoffset = GETPOST('listoffset', 'alpha');
2316
        $listlimit = GETPOSTINT('listlimit') > 0 ? GETPOSTINT('listlimit') : 1000;
2317
        $active = 1;
2318
2319
        $sortfield = GETPOST('sortfield', 'aZ09comma');
2320
        $sortorder = GETPOST('sortorder', 'aZ09comma');
2321
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
2322
        if (empty($page) || $page == -1) {
2323
            $page = 0;
2324
        }     // If $page is not defined, or '' or -1
2325
        $offset = $listlimit * $page;
2326
        $pageprev = $page - 1;
2327
        $pagenext = $page + 1;
2328
        if (empty($sortfield)) {
2329
            $sortfield = 'code';
2330
        }
2331
        if (empty($sortorder)) {
2332
            $sortorder = 'ASC';
2333
        }
2334
2335
        $error = 0;
2336
2337
        $search_country_id = GETPOSTINT('search_country_id');
2338
2339
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
2340
        $hookmanager->initHooks(['admin']);
2341
2342
// This page is a generic page to edit dictionaries
2343
// Put here declaration of dictionaries properties
2344
2345
// Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this.
2346
        $taborder = [35];
2347
2348
// Name of SQL tables of dictionaries
2349
        $tabname = [];
2350
        $tabname[35] = MAIN_DB_PREFIX . "accounting_journal";
2351
2352
// Dictionary labels
2353
        $tablib = [];
2354
        $tablib[35] = "DictionaryAccountancyJournal";
2355
2356
// Requests to extract data
2357
        $tabsql = [];
2358
        $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";
2359
2360
// Criteria to sort dictionaries
2361
        $tabsqlsort = [];
2362
        $tabsqlsort[35] = "code ASC";
2363
2364
// Nom des champs en resultat de select pour affichage du dictionnaire
2365
        $tabfield = [];
2366
        $tabfield[35] = "code,label,nature";
2367
2368
// Nom des champs d'edition pour modification d'un enregistrement
2369
        $tabfieldvalue = [];
2370
        $tabfieldvalue[35] = "code,label,nature";
2371
2372
// Nom des champs dans la table pour insertion d'un enregistrement
2373
        $tabfieldinsert = [];
2374
        $tabfieldinsert[35] = "code,label,nature";
2375
2376
// Nom du rowid si le champ n'est pas de type autoincrement
2377
// Example: "" if id field is "rowid" and has autoincrement on
2378
//          "nameoffield" if id field is not "rowid" or has not autoincrement on
2379
        $tabrowid = [];
2380
        $tabrowid[35] = "";
2381
2382
// Condition to show dictionary in setup page
2383
        $tabcond = [];
2384
        $tabcond[35] = isModEnabled('accounting');
2385
2386
// List of help for fields
2387
        $tabhelp = [];
2388
        $tabhelp[35] = ['code' => $langs->trans("EnterAnyCode")];
2389
2390
// List of check for fields (NOT USED YET)
2391
        $tabfieldcheck = [];
2392
        $tabfieldcheck[35] = [];
2393
2394
// Complete all arrays with entries found into modules
2395
        complete_dictionary_with_modules($taborder, $tabname, $tablib, $tabsql, $tabsqlsort, $tabfield, $tabfieldvalue, $tabfieldinsert, $tabrowid, $tabcond, $tabhelp, $tabfieldcheck);
2396
2397
2398
// Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact")
2399
        $elementList = [];
2400
// Must match ids defined into eldy.lib.php
2401
        $sourceList = [
2402
            '1' => $langs->trans('AccountingJournalType1'),
2403
            '2' => $langs->trans('AccountingJournalType2'),
2404
            '3' => $langs->trans('AccountingJournalType3'),
2405
            '4' => $langs->trans('AccountingJournalType4'),
2406
            '5' => $langs->trans('AccountingJournalType5'),
2407
            '8' => $langs->trans('AccountingJournalType8'),
2408
            '9' => $langs->trans('AccountingJournalType9'),
2409
        ];
2410
2411
        /*
2412
         * Actions
2413
         */
2414
2415
        if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) {
2416
            $search_country_id = '';
2417
        }
2418
2419
// Actions add or modify an entry into a dictionary
2420
        if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
2421
            $listfield = explode(',', str_replace(' ', '', $tabfield[$id]));
2422
            $listfieldinsert = explode(',', $tabfieldinsert[$id]);
2423
            $listfieldmodify = explode(',', $tabfieldinsert[$id]);
2424
            $listfieldvalue = explode(',', $tabfieldvalue[$id]);
2425
2426
            // Check that all fields are filled
2427
            $ok = 1;
2428
2429
            // Other checks
2430
            if (GETPOSTISSET("code")) {
2431
                if (GETPOST("code") == '0') {
2432
                    $ok = 0;
2433
                    setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
2434
                }
2435
            }
2436
            if (!GETPOST('label', 'alpha')) {
2437
                setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
2438
                $ok = 0;
2439
            }
2440
2441
            // Si verif ok et action add, on ajoute la ligne
2442
            if ($ok && GETPOST('actionadd', 'alpha')) {
2443
                if ($tabrowid[$id]) {
2444
                    // Get free id for insert
2445
                    $newid = 0;
2446
                    $sql = "SELECT MAX(" . $db->sanitize($tabrowid[$id]) . ") newid FROM " . $db->sanitize($tabname[$id]);
2447
                    $result = $db->query($sql);
2448
                    if ($result) {
2449
                        $obj = $db->fetch_object($result);
2450
                        $newid = ($obj->newid + 1);
2451
                    } else {
2452
                        dol_print_error($db);
2453
                    }
2454
                }
2455
2456
                // Add new entry
2457
                $sql = "INSERT INTO " . $db->sanitize($tabname[$id]) . " (";
2458
                // List of fields
2459
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
2460
                    $sql .= $tabrowid[$id] . ",";
2461
                }
2462
                $sql .= $db->sanitize($tabfieldinsert[$id]);
2463
                $sql .= ",active,entity)";
2464
                $sql .= " VALUES(";
2465
2466
                // List of values
2467
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) {
2468
                    $sql .= $newid . ",";
2469
                }
2470
                $i = 0;
2471
                foreach ($listfieldinsert as $f => $value) {
2472
                    if ($i) {
2473
                        $sql .= ",";
2474
                    }
2475
                    if (GETPOST($listfieldvalue[$i]) == '') {
2476
                        $sql .= "null"; // For vat, we want/accept code = ''
2477
                    } else {
2478
                        $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
2479
                    }
2480
                    $i++;
2481
                }
2482
                $sql .= ",1," . $conf->entity . ")";
2483
2484
                dol_syslog("actionadd", LOG_DEBUG);
2485
                $result = $db->query($sql);
2486
                if ($result) {  // Add is ok
2487
                    setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs');
2488
                    $_POST = ['id' => $id]; // Clean $_POST array, we keep only id
2489
                } else {
2490
                    if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2491
                        setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
2492
                    } else {
2493
                        dol_print_error($db);
2494
                    }
2495
                }
2496
            }
2497
2498
            // Si verif ok et action modify, on modifie la ligne
2499
            if ($ok && GETPOST('actionmodify', 'alpha')) {
2500
                if ($tabrowid[$id]) {
2501
                    $rowidcol = $tabrowid[$id];
2502
                } else {
2503
                    $rowidcol = "rowid";
2504
                }
2505
2506
                // Modify entry
2507
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET ";
2508
                // Modifie valeur des champs
2509
                if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) {
2510
                    $sql .= $db->sanitize($tabrowid[$id]) . " = ";
2511
                    $sql .= "'" . $db->escape($rowid) . "', ";
2512
                }
2513
                $i = 0;
2514
                foreach ($listfieldmodify as $field) {
2515
                    if ($i) {
2516
                        $sql .= ",";
2517
                    }
2518
                    $sql .= $field . " = ";
2519
                    $sql .= "'" . $db->escape(GETPOST($listfieldvalue[$i])) . "'";
2520
                    $i++;
2521
                }
2522
                $sql .= " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2523
                $sql .= " AND entity = " . ((int) $conf->entity);
2524
2525
                dol_syslog("actionmodify", LOG_DEBUG);
2526
                //print $sql;
2527
                $resql = $db->query($sql);
2528
                if (!$resql) {
2529
                    setEventMessages($db->error(), null, 'errors');
2530
                }
2531
            }
2532
            //$_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
2533
        }
2534
2535
//if (GETPOST('actioncancel', 'alpha'))
2536
//{
2537
//  $_GET["id"]=GETPOST('id', 'int');       // Force affichage dictionnaire en cours d'edition
2538
//}
2539
2540
        if ($action == 'confirm_delete' && $confirm == 'yes') {       // delete
2541
            if ($tabrowid[$id]) {
2542
                $rowidcol = $tabrowid[$id];
2543
            } else {
2544
                $rowidcol = "rowid";
2545
            }
2546
2547
            $sql = "DELETE from " . $db->sanitize($tabname[$id]) . " WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2548
            $sql .= " AND entity = " . ((int) $conf->entity);
2549
2550
            dol_syslog("delete", LOG_DEBUG);
2551
            $result = $db->query($sql);
2552
            if (!$result) {
2553
                if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') {
2554
                    setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors');
2555
                } else {
2556
                    dol_print_error($db);
2557
                }
2558
            }
2559
        }
2560
2561
// activate
2562
        if ($action == $acts[0]) {
2563
            if ($tabrowid[$id]) {
2564
                $rowidcol = $tabrowid[$id];
2565
            } else {
2566
                $rowidcol = "rowid";
2567
            }
2568
2569
            if ($rowid) {
2570
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2571
            } elseif ($code) {
2572
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 1 WHERE code = '" . $db->escape($code) . "'";
2573
            }
2574
            $sql .= " AND entity = " . $conf->entity;
2575
2576
            $result = $db->query($sql);
2577
            if (!$result) {
2578
                dol_print_error($db);
2579
            }
2580
        }
2581
2582
// disable
2583
        if ($action == $acts[1]) {
2584
            if ($tabrowid[$id]) {
2585
                $rowidcol = $tabrowid[$id];
2586
            } else {
2587
                $rowidcol = "rowid";
2588
            }
2589
2590
            if ($rowid) {
2591
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE " . $db->sanitize($rowidcol) . " = " . ((int) $rowid);
2592
            } elseif ($code) {
2593
                $sql = "UPDATE " . $db->sanitize($tabname[$id]) . " SET active = 0 WHERE code='" . $db->escape($code) . "'";
2594
            }
2595
            $sql .= " AND entity = " . $conf->entity;
2596
2597
            $result = $db->query($sql);
2598
            if (!$result) {
2599
                dol_print_error($db);
2600
            }
2601
        }
2602
2603
        /*
2604
         * View
2605
         */
2606
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_journals_list.php');
2607
2608
        $db->close();
2609
        return true;
2610
    }
2611
2612
    /**
2613
     * \file        htdocs/accountancy/admin/productaccount.php
2614
     * \ingroup     Accountancy (Double entries)
2615
     * \brief       To define accounting account on product / service
2616
     */
2617
    public function productaccount()
2618
    {
2619
        global $conf;
2620
        global $db;
2621
        global $user;
2622
        global $hookmanager;
2623
        global $user;
2624
        global $menumanager;
2625
        global $langs;
2626
        global $mysoc;
2627
2628
// Load translation files required by the page
2629
        $langs->loadLangs(["companies", "compta", "accountancy", "products"]);
2630
2631
// Security check
2632
        if (!isModEnabled('accounting')) {
2633
            accessforbidden();
2634
        }
2635
        if (!$user->hasRight('accounting', 'bind', 'write')) {
2636
            accessforbidden();
2637
        }
2638
2639
// search & action GETPOST
2640
        $action = GETPOST('action', 'aZ09');
2641
        $massaction = GETPOST('massaction', 'alpha');
2642
        $confirm = GETPOST('confirm', 'alpha');
2643
        $optioncss = GETPOST('optioncss', 'alpha');
2644
2645
        $codeventil_buy = GETPOST('codeventil_buy', 'array');
2646
        $codeventil_sell = GETPOST('codeventil_sell', 'array');
2647
        $chk_prod = GETPOST('chk_prod', 'array');
2648
        $default_account = GETPOSTINT('default_account');
2649
        $account_number_buy = GETPOST('account_number_buy');
2650
        $account_number_sell = GETPOST('account_number_sell');
2651
        $changeaccount = GETPOST('changeaccount', 'array');
2652
        $changeaccount_buy = GETPOST('changeaccount_buy', 'array');
2653
        $changeaccount_sell = GETPOST('changeaccount_sell', 'array');
2654
        $searchCategoryProductOperator = (GETPOSTINT('search_category_product_operator') ? GETPOSTINT('search_category_product_operator') : 0);
2655
        $searchCategoryProductList = GETPOST('search_category_product_list', 'array');
2656
        $search_ref = GETPOST('search_ref', 'alpha');
2657
        $search_label = GETPOST('search_label', 'alpha');
2658
        $search_desc = GETPOST('search_desc', 'alpha');
2659
        $search_vat = GETPOST('search_vat', 'alpha');
2660
        $search_current_account = GETPOST('search_current_account', 'alpha');
2661
        $search_current_account_valid = GETPOST('search_current_account_valid', 'alpha');
2662
        if ($search_current_account_valid == '') {
2663
            $search_current_account_valid = 'withoutvalidaccount';
2664
        }
2665
        $search_onsell = GETPOST('search_onsell', 'alpha');
2666
        $search_onpurchase = GETPOST('search_onpurchase', 'alpha');
2667
2668
        $accounting_product_mode = GETPOST('accounting_product_mode', 'alpha');
2669
        $btn_changetype = GETPOST('changetype', 'alpha');
2670
2671
        if (empty($accounting_product_mode)) {
2672
            $accounting_product_mode = 'ACCOUNTANCY_SELL';
2673
        }
2674
2675
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : getDolGlobalInt('ACCOUNTING_LIMIT_LIST_VENTILATION', $conf->liste_limit);
2676
        $sortfield = GETPOST('sortfield', 'aZ09comma');
2677
        $sortorder = GETPOST('sortorder', 'aZ09comma');
2678
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
2679
        if (empty($page) || $page == -1) {
2680
            $page = 0;
2681
        }     // If $page is not defined, or '' or -1
2682
        $offset = $limit * $page;
2683
        $pageprev = $page - 1;
2684
        $pagenext = $page + 1;
2685
        if (!$sortfield) {
2686
            $sortfield = "p.ref";
2687
        }
2688
        if (!$sortorder) {
2689
            $sortorder = "ASC";
2690
        }
2691
2692
        if (empty($action)) {
2693
            $action = 'list';
2694
        }
2695
2696
        $arrayfields = [];
2697
2698
        $accounting_product_modes = [
2699
            'ACCOUNTANCY_SELL',
2700
            'ACCOUNTANCY_SELL_INTRA',
2701
            'ACCOUNTANCY_SELL_EXPORT',
2702
            'ACCOUNTANCY_BUY',
2703
            'ACCOUNTANCY_BUY_INTRA',
2704
            'ACCOUNTANCY_BUY_EXPORT',
2705
        ];
2706
2707
        if ($accounting_product_mode == 'ACCOUNTANCY_BUY') {
2708
            $accountancy_field_name = "accountancy_code_buy";
2709
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') {
2710
            $accountancy_field_name = "accountancy_code_buy_intra";
2711
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') {
2712
            $accountancy_field_name = "accountancy_code_buy_export";
2713
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
2714
            $accountancy_field_name = "accountancy_code_sell";
2715
        } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
2716
            $accountancy_field_name = "accountancy_code_sell_intra";
2717
        } else { // $accounting_product_mode == 'ACCOUNTANCY_SELL_EXPORT'
2718
            $accountancy_field_name = "accountancy_code_sell_export";
2719
        }
2720
2721
        /*
2722
         * Actions
2723
         */
2724
2725
        if (GETPOST('cancel', 'alpha')) {
2726
            $action = 'list';
2727
            $massaction = '';
2728
        }
2729
        if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
2730
            $massaction = '';
2731
        }
2732
2733
        $parameters = [];
2734
        $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...
2735
        if ($reshook < 0) {
2736
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2737
        }
2738
2739
// Purge search criteria
2740
        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
2741
            $searchCategoryProductOperator = 0;
2742
            $searchCategoryProductList = [];
2743
            $search_ref = '';
2744
            $search_label = '';
2745
            $search_desc = '';
2746
            $search_vat = '';
2747
            $search_onsell = '';
2748
            $search_onpurchase = '';
2749
            $search_current_account = '';
2750
            $search_current_account_valid = '-1';
2751
        }
2752
2753
// Sales or Purchase mode ?
2754
        if ($action == 'update') {
2755
            if (!empty($btn_changetype)) {
2756
                $error = 0;
2757
2758
                if (in_array($accounting_product_mode, $accounting_product_modes)) {
2759
                    if (!dolibarr_set_const($db, 'ACCOUNTING_PRODUCT_MODE', $accounting_product_mode, 'chaine', 0, '', $conf->entity)) {
2760
                        $error++;
2761
                    }
2762
                } else {
2763
                    $error++;
2764
                }
2765
            }
2766
2767
            if (!empty($chk_prod) && $massaction === 'changeaccount') {
2768
                //$msg = '<div><span class="accountingprocessing">' . $langs->trans("Processing") . '...</span></div>';
2769
                if (!empty($chk_prod) && in_array($accounting_product_mode, $accounting_product_modes)) {
2770
                    $accounting = new AccountingAccount($db);
2771
2772
                    //$msg .= '<div><span class="accountingprocessing">' . count($chk_prod) . ' ' . $langs->trans("SelectedLines") . '</span></div>';
2773
                    $arrayofdifferentselectedvalues = [];
2774
2775
                    $cpt = 0;
2776
                    $ok = 0;
2777
                    $ko = 0;
2778
                    foreach ($chk_prod as $productid) {
2779
                        $accounting_account_id = GETPOST('codeventil_' . $productid);
2780
2781
                        $result = 0;
2782
                        if ($accounting_account_id > 0) {
2783
                            $arrayofdifferentselectedvalues[$accounting_account_id] = $accounting_account_id;
2784
                            $result = $accounting->fetch($accounting_account_id, null, 1);
2785
                        }
2786
                        if ($result <= 0) {
2787
                            // setEventMessages(null, $accounting->errors, 'errors');
2788
                            $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...
2789
                            $ko++;
2790
                        } else {
2791
                            $sql = '';
2792
                            if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
2793
                                $sql_exists = "SELECT rowid FROM " . MAIN_DB_PREFIX . "product_perentity";
2794
                                $sql_exists .= " WHERE fk_product = " . ((int) $productid) . " AND entity = " . ((int) $conf->entity);
2795
                                $resql_exists = $db->query($sql_exists);
2796
                                if (!$resql_exists) {
2797
                                    $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>';
2798
                                    $ko++;
2799
                                } else {
2800
                                    $nb_exists = $db->num_rows($resql_exists);
2801
                                    if ($nb_exists <= 0) {
2802
                                        // insert
2803
                                        $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_perentity (fk_product, entity, " . $db->sanitize($accountancy_field_name) . ")";
2804
                                        $sql .= " VALUES (" . ((int) $productid) . ", " . ((int) $conf->entity) . ", '" . $db->escape($accounting->account_number) . "')";
2805
                                    } else {
2806
                                        $obj_exists = $db->fetch_object($resql_exists);
2807
                                        // update
2808
                                        $sql = "UPDATE " . MAIN_DB_PREFIX . "product_perentity";
2809
                                        $sql .= " SET " . $db->sanitize($accountancy_field_name) . " = '" . $db->escape($accounting->account_number) . "'";
2810
                                        $sql .= " WHERE rowid = " . ((int) $obj_exists->rowid);
2811
                                    }
2812
                                }
2813
                            } else {
2814
                                $sql = " UPDATE " . MAIN_DB_PREFIX . "product";
2815
                                $sql .= " SET " . $db->sanitize($accountancy_field_name) . " = '" . $db->escape($accounting->account_number) . "'";
2816
                                $sql .= " WHERE rowid = " . ((int) $productid);
2817
                            }
2818
2819
                            dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG);
2820
2821
                            $db->begin();
2822
2823
                            if ($db->query($sql)) {
2824
                                $ok++;
2825
                                $db->commit();
2826
                            } else {
2827
                                $ko++;
2828
                                $db->rollback();
2829
                            }
2830
                        }
2831
2832
                        $cpt++;
2833
                    }
2834
                }
2835
2836
                if ($ko) {
2837
                    setEventMessages($langs->trans("XLineFailedToBeBinded", $ko), null, 'errors');
2838
                }
2839
                if ($ok) {
2840
                    setEventMessages($langs->trans("XLineSuccessfullyBinded", $ok), null, 'mesgs');
2841
                }
2842
            }
2843
        }
2844
2845
        /*
2846
         * View
2847
         */
2848
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_productaccount.php');
2849
2850
        $db->close();
2851
        return true;
2852
    }
2853
2854
    /**
2855
     * \file        htdocs/accountancy/admin/subaccount.php
2856
     * \ingroup     Accountancy (Double entries)
2857
     * \brief       List of accounting sub-account (auxiliary accounts)
2858
     */
2859
    public function subaccount()
2860
    {
2861
        global $conf;
2862
        global $db;
2863
        global $user;
2864
        global $hookmanager;
2865
        global $user;
2866
        global $menumanager;
2867
        global $langs;
2868
2869
// Load translation files required by the page
2870
        $langs->loadLangs(["accountancy", "admin", "bills", "compta", "errors", "hrm", "salaries"]);
2871
2872
        $mesg = '';
2873
        $action = GETPOST('action', 'aZ09');
2874
        $cancel = GETPOST('cancel', 'alpha');
2875
        $id = GETPOSTINT('id');
2876
        $rowid = GETPOSTINT('rowid');
2877
        $massaction = GETPOST('massaction', 'aZ09');
2878
        $optioncss = GETPOST('optioncss', 'alpha');
2879
        $mode = GETPOST('mode', 'aZ'); // The output mode ('list', 'kanban', 'hierarchy', 'calendar', ...)
2880
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'accountingsubaccountlist'; // To manage different context of search
2881
2882
        $search_subaccount = GETPOST('search_subaccount', 'alpha');
2883
        $search_label = GETPOST('search_label', 'alpha');
2884
        $search_type = GETPOSTINT('search_type');
2885
2886
// Security check
2887
        if ($user->socid > 0) {
2888
            accessforbidden();
2889
        }
2890
        if (!$user->hasRight('accounting', 'chartofaccount')) {
2891
            accessforbidden();
2892
        }
2893
2894
// Load variable for pagination
2895
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
2896
        $sortfield = GETPOST('sortfield', 'aZ09comma');
2897
        $sortorder = GETPOST('sortorder', 'aZ09comma');
2898
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
2899
        if (empty($page) || $page == -1) {
2900
            $page = 0;
2901
        }     // If $page is not defined, or '' or -1
2902
        $offset = $limit * $page;
2903
        $pageprev = $page - 1;
2904
        $pagenext = $page + 1;
2905
        if (!$sortfield) {
2906
            $sortfield = "label";
2907
        }
2908
        if (!$sortorder) {
2909
            $sortorder = "ASC";
2910
        }
2911
2912
        $arrayfields = [
2913
            'subaccount' => ['label' => $langs->trans("AccountNumber"), 'checked' => 1],
2914
            'label' => ['label' => $langs->trans("Label"), 'checked' => 1],
2915
            'type' => ['label' => $langs->trans("Type"), 'checked' => 1],
2916
            'reconcilable' => ['label' => $langs->trans("Reconcilable"), 'checked' => 1],
2917
        ];
2918
2919
        if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) {
2920
            unset($arrayfields['reconcilable']);
2921
        }
2922
2923
2924
        /*
2925
         * Actions
2926
         */
2927
2928
        if (GETPOST('cancel', 'alpha')) {
2929
            $action = 'list';
2930
            $massaction = '';
2931
        }
2932
        if (!GETPOST('confirmmassaction', 'alpha')) {
2933
            $massaction = '';
2934
        }
2935
2936
        $parameters = [];
2937
        $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...
2938
        if ($reshook < 0) {
2939
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2940
        }
2941
2942
        if (empty($reshook)) {
2943
            if (!empty($cancel)) {
2944
                $action = '';
2945
            }
2946
2947
            include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php';
2948
2949
            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
2950
                $search_subaccount = "";
2951
                $search_label = "";
2952
                $search_type = "";
2953
                $search_array_options = [];
2954
            }
2955
        }
2956
2957
2958
        /*
2959
         * View
2960
         */
2961
2962
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/admin_subaccount.php');
2963
2964
        $db->close();
2965
        return true;
2966
    }
2967
2968
    /**
2969
     *  Show fields in insert/edit mode
2970
     *
2971
     * @param array  $fieldlist Array of fields
2972
     * @param Object $obj       If we show a particular record, obj is filled with record fields
2973
     * @param string $tabname   Name of SQL table
2974
     * @param string $context   'add'=Output field for the "add form", 'edit'=Output field for the "edit form",
2975
     *                          'hide'=Output field for the "add form" but we don't want it to be rendered
2976
     *
2977
     * @return     void
2978
     */
2979
    private function fieldListAccountModel($fieldlist, $obj = null, $tabname = '', $context = '')
0 ignored issues
show
Unused Code introduced by
The method fieldListAccountModel() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
2980
    {
2981
        global $langs, $db;
2982
        global $form;
2983
        global $elementList, $sourceList;
2984
2985
        $formadmin = new FormAdmin($db);
2986
        $formcompany = new FormCompany($db);
2987
        $formaccounting = new FormAccounting($db);
2988
2989
        foreach ($fieldlist as $field => $value) {
2990
            if ($fieldlist[$field] == 'country') {
2991
                if (in_array('region_id', $fieldlist)) {
2992
                    print '<td>';
2993
                    //print join(',',$fieldlist);
2994
                    print '</td>';
2995
                    continue;
2996
                }   // For state page, we do not show the country input (we link to region, not country)
2997
                print '<td>';
2998
                $fieldname = 'country';
2999
                print $form->select_country((!empty($obj->country_code) ? $obj->country_code : (!empty($obj->country) ? $obj->country : '')), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone');
3000
                print '</td>';
3001
            } elseif ($fieldlist[$field] == 'country_id') {
3002
                if (!in_array('country', $fieldlist)) { // If there is already a field country, we don't show country_id (avoid duplicate)
3003
                    $country_id = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0);
3004
                    print '<td>';
3005
                    print '<input type="hidden" name="' . $fieldlist[$field] . '" value="' . $country_id . '">';
3006
                    print '</td>';
3007
                }
3008
            } elseif ($fieldlist[$field] == 'type_cdr') {
3009
                if ($fieldlist[$field] == 'type_cdr') {
3010
                    print '<td class="center">';
3011
                } else {
3012
                    print '<td>';
3013
                }
3014
                if ($fieldlist[$field] == 'type_cdr') {
3015
                    print $form->selectarray($fieldlist[$field], [0 => $langs->trans('None'), 1 => $langs->trans('AtEndOfMonth'), 2 => $langs->trans('CurrentNext')], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''));
3016
                } else {
3017
                    print $form->selectyesno($fieldlist[$field], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''), 1);
3018
                }
3019
                print '</td>';
3020
            } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
3021
                print '<td><input type="text" class="flat" value="' . (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" size="10" name="' . $fieldlist[$field] . '"></td>';
3022
            } else {
3023
                print '<td>';
3024
                $class = '';
3025
                if ($fieldlist[$field] == 'pcg_version') {
3026
                    $class = 'width150';
3027
                }
3028
                if ($fieldlist[$field] == 'label') {
3029
                    $class = 'width300';
3030
                }
3031
                print '<input type="text" class="flat' . ($class ? ' ' . $class : '') . '" value="' . (isset($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '">';
3032
                print '</td>';
3033
            }
3034
        }
3035
    }
3036
3037
    /**
3038
     *  Show fields in insert/edit mode
3039
     *
3040
     * @param array  $fieldlist Array of fields
3041
     * @param Object $obj       If we show a particular record, obj is filled with record fields
3042
     * @param string $tabname   Name of SQL table
3043
     * @param string $context   'add'=Output field for the "add form", 'edit'=Output field for the "edit form",
3044
     *                          'hide'=Output field for the "add form" but we don't want it to be rendered
3045
     *
3046
     * @return     void
3047
     */
3048
    private function fieldListJournal($fieldlist, $obj = null, $tabname = '', $context = '')
0 ignored issues
show
Unused Code introduced by
The method fieldListJournal() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
3049
    {
3050
        global $db, $form, $sourceList;
3051
3052
        $formadmin = new FormAdmin($db);
3053
        $formcompany = new FormCompany($db);
3054
3055
        foreach ($fieldlist as $field => $value) {
3056
            if ($fieldlist[$field] == 'nature') {
3057
                print '<td>';
3058
                print $form->selectarray('nature', $sourceList, (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : ''));
3059
                print '</td>';
3060
            } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) {
3061
                print '<td><input type="text" class="flat minwidth100" value="' . (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '"></td>';
3062
            } else {
3063
                print '<td>';
3064
                $size = '';
3065
                $class = '';
3066
                if ($fieldlist[$field] == 'code') {
3067
                    $class = 'maxwidth100';
3068
                }
3069
                if ($fieldlist[$field] == 'label') {
3070
                    $class = 'quatrevingtpercent';
3071
                }
3072
                if ($fieldlist[$field] == 'sortorder' || $fieldlist[$field] == 'sens' || $fieldlist[$field] == 'category_type') {
3073
                    $size = 'size="2" ';
3074
                }
3075
                print '<input type="text" ' . $size . 'class="flat' . ($class ? ' ' . $class : '') . '" value="' . (isset($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : '') . '" name="' . $fieldlist[$field] . '">';
3076
                print '</td>';
3077
            }
3078
        }
3079
    }
3080
}
3081