Test Failed
Branch main (fda838)
by Rafael
54:38 queued 11s
created

AccountingExpenseReportController::index()   F

Complexity

Conditions 64
Paths > 20000

Size

Total Lines 456
Code Lines 319

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 64
eloc 319
nc 715936320
nop 0
dl 0
loc 456
rs 0
c 1
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) 2005       Simon TOSSER            <[email protected]>
5
 * Copyright (C) 2013-2024  Alexandre Spangaro      <[email protected]>
6
 * Copyright (C) 2013-2016  Olivier Geffroy         <[email protected]>
7
 * Copyright (C) 2013-2014	Florian Henry		    <[email protected]>
8
 * Copyright (C) 2013-2024	Alexandre Spangaro	    <[email protected]>
9
 * Copyright (C) 2014-2015	Ari Elbaz (elarifr)	<[email protected]>
10
 * Copyright (C) 2014		Juanjo Menent		    <[email protected]>
11
 * Copyright (C) 2015       Jean-François Ferry     <[email protected]>
12
 * Copyright (C) 2024       Rafael San José         <[email protected]>
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 3 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26
 */
27
28
namespace DoliModules\Accounting\Controller;
29
30
global $conf;
31
global $db;
32
global $user;
33
global $hookmanager;
34
global $user;
35
global $menumanager;
36
global $langs;
37
global $mysoc;
38
39
// Load Dolibarr environment
40
require BASE_PATH . '/main.inc.php';
41
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php';
42
require_once DOL_DOCUMENT_ROOT . '/core/class/html.formother.class.php';
43
require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
44
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
45
require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport.class.php';
46
require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
47
48
use AccountingAccount;
49
use DoliCore\Base\DolibarrController;
50
use ExpenseReport;
51
use Form;
52
use FormAccounting;
53
use FormOther;
54
use User;
55
56
class AccountingExpenseReportController extends DolibarrController
0 ignored issues
show
Deprecated Code introduced by
The class DoliCore\Base\DolibarrController has been deprecated: This class is only needed for compatibility with Dolibarr. ( Ignorable by Annotation )

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

56
class AccountingExpenseReportController extends /** @scrutinizer ignore-deprecated */ DolibarrController
Loading history...
57
{
58
59
    /**
60
     * \file        htdocs/accountancy/supplier/card.php
61
     * \ingroup     Accountancy (Double entries)
62
     * \brief       Card expense report ventilation
63
     */
64
    public function card()
65
    {
66
        global $conf;
67
        global $db;
68
        global $user;
69
        global $hookmanager;
70
        global $user;
71
        global $menumanager;
72
        global $langs;
73
        global $mysoc;
74
75
// Load translation files required by the page
76
        $langs->loadLangs(array("bills", "accountancy", "trips"));
77
78
        $action = GETPOST('action', 'aZ09');
79
        $cancel = GETPOST('cancel', 'alpha');
80
        $backtopage = GETPOST('backtopage', 'alpha');
81
82
        $codeventil = GETPOSTINT('codeventil');
83
        $id = GETPOSTINT('id');
84
85
// Security check
86
        if (!isModEnabled('accounting')) {
87
            accessforbidden();
88
        }
89
        if ($user->socid > 0) {
90
            accessforbidden();
91
        }
92
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
93
            accessforbidden();
94
        }
95
96
97
        /*
98
         * Actions
99
         */
100
101
        if ($action == 'ventil' && $user->hasRight('accounting', 'bind', 'write')) {
102
            if (!$cancel) {
103
                if ($codeventil < 0) {
104
                    $codeventil = 0;
105
                }
106
107
                $sql = " UPDATE " . MAIN_DB_PREFIX . "expensereport_det";
108
                $sql .= " SET fk_code_ventilation = " . ((int) $codeventil);
109
                $sql .= " WHERE rowid = " . ((int) $id);
110
111
                $resql = $db->query($sql);
112
                if (!$resql) {
113
                    setEventMessages($db->lasterror(), null, 'errors');
114
                } else {
115
                    setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs');
116
                    if ($backtopage) {
117
                        header("Location: " . $backtopage);
118
                        exit();
119
                    }
120
                }
121
            } else {
122
                header("Location: ./lines.php");
123
                exit();
124
            }
125
        }
126
127
128
129
        /*
130
         * View
131
         */
132
        $help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#Liaisons_comptables';
133
134
        llxHeader("", $langs->trans('FicheVentilation'), $help_url);
135
136
        if ($cancel == $langs->trans("Cancel")) {
137
            $action = '';
138
        }
139
140
// Create
141
        $form = new Form($db);
142
        $expensereport_static = new ExpenseReport($db);
143
        $formaccounting = new FormAccounting($db);
144
145
        if (!empty($id)) {
146
            $sql = "SELECT er.ref, er.rowid as facid, erd.fk_c_type_fees, erd.comments, erd.rowid, erd.fk_code_ventilation,";
147
            $sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label,";
148
            $sql .= " aa.account_number, aa.label";
149
            $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
150
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees";
151
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON erd.fk_code_ventilation = aa.rowid";
152
            $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
153
            $sql .= " WHERE er.fk_statut > 0 AND erd.rowid = " . ((int) $id);
154
            $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
155
156
            dol_syslog("/accounting/expensereport/card.php", LOG_DEBUG);
157
            $result = $db->query($sql);
158
159
            if ($result) {
160
                $num_lines = $db->num_rows($result);
161
                $i = 0;
162
163
                if ($num_lines) {
164
                    $objp = $db->fetch_object($result);
165
166
                    print '<form action="' . $_SERVER['PHP_SELF'] . '?id=' . $id . '" method="post">' . "\n";
167
                    print '<input type="hidden" name="token" value="' . newToken() . '">';
168
                    print '<input type="hidden" name="action" value="ventil">';
169
                    print '<input type="hidden" name="backtopage" value="' . dol_escape_htmltag($backtopage) . '">';
170
171
                    print load_fiche_titre($langs->trans('ExpenseReportsVentilation'), '', 'title_accountancy');
172
173
                    print dol_get_fiche_head();
174
175
                    print '<table class="border centpercent">';
176
177
                    // Ref
178
                    print '<tr><td class="titlefield">' . $langs->trans("ExpenseReport") . '</td>';
179
                    $expensereport_static->ref = $objp->ref;
180
                    $expensereport_static->id = $objp->erid;
181
                    print '<td>' . $expensereport_static->getNomUrl(1) . '</td>';
182
                    print '</tr>';
183
184
                    print '<tr><td>' . $langs->trans("Line") . '</td>';
185
                    print '<td>' . stripslashes(nl2br($objp->rowid)) . '</td></tr>';
186
187
                    print '<tr><td>' . $langs->trans("Description") . '</td>';
188
                    print '<td>' . stripslashes(nl2br($objp->comments)) . '</td></tr>';
189
190
                    print '<tr><td>' . $langs->trans("TypeFees") . '</td>';
191
                    print '<td>' . ($langs->trans($objp->type_fees_code) == $objp->type_fees_code ? $objp->type_fees_label : $langs->trans(($objp->type_fees_code))) . '</td>';
192
193
                    print '<tr><td>' . $langs->trans("Account") . '</td><td>';
194
                    print $formaccounting->select_account($objp->fk_code_ventilation, 'codeventil', 1);
195
                    print '</td></tr>';
196
                    print '</table>';
197
198
                    print dol_get_fiche_end();
199
200
                    print '<div class="center">';
201
                    print '<input class="button button-save" type="submit" value="' . $langs->trans("Save") . '">';
202
                    print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
203
                    print '<input class="button button-cancel" type="submit" name="cancel" value="' . $langs->trans("Cancel") . '">';
204
                    print '</div>';
205
206
                    print '</form>';
207
                } else {
208
                    print "Error";
209
                }
210
            } else {
211
                print "Error";
212
            }
213
        } else {
214
            print "Error ID incorrect";
215
        }
216
217
// End of page
218
        llxFooter();
219
        $db->close();
220
    }
221
222
    /**
223
     * \file        htdocs/accountancy/expensereport/index.php
224
     * \ingroup     Accountancy (Double entries)
225
     * \brief       Home expense report ventilation
226
     */
227
    public function index()
228
    {
229
        global $conf;
230
        global $db;
231
        global $user;
232
        global $hookmanager;
233
        global $user;
234
        global $menumanager;
235
        global $langs;
236
        global $mysoc;
237
238
// Load translation files required by the page
239
        $langs->loadLangs(array("compta", "bills", "other", "accountancy"));
240
241
        $validatemonth = GETPOSTINT('validatemonth');
242
        $validateyear = GETPOSTINT('validateyear');
243
244
        $month_start = getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1);
245
        if (GETPOSTINT("year")) {
246
            $year_start = GETPOSTINT("year");
247
        } else {
248
            $year_start = dol_print_date(dol_now(), '%Y');
249
            if (dol_print_date(dol_now(), '%m') < $month_start) {
250
                $year_start--; // If current month is lower that starting fiscal month, we start last year
251
            }
252
        }
253
        $year_end = $year_start + 1;
254
        $month_end = $month_start - 1;
255
        if ($month_end < 1) {
256
            $month_end = 12;
257
            $year_end--;
258
        }
259
        $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start);
260
        $search_date_end = dol_get_last_day($year_end, $month_end);
261
        $year_current = $year_start;
262
263
// Validate History
264
        $action = GETPOST('action', 'aZ09');
265
266
        $chartaccountcode = dol_getIdFromCode($db, getDolGlobalInt('CHARTOFACCOUNTS'), 'accounting_system', 'rowid', 'pcg_version');
267
268
// Security check
269
        if (!isModEnabled('accounting')) {
270
            accessforbidden();
271
        }
272
        if ($user->socid > 0) {
273
            accessforbidden();
274
        }
275
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
276
            accessforbidden();
277
        }
278
279
280
        /*
281
         * Actions
282
         */
283
284
        if (($action == 'clean' || $action == 'validatehistory') && $user->hasRight('accounting', 'bind', 'write')) {
285
            // Clean database
286
            $db->begin();
287
            $sql1 = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det as erd";
288
            $sql1 .= " SET fk_code_ventilation = 0";
289
            $sql1 .= ' WHERE erd.fk_code_ventilation NOT IN';
290
            $sql1 .= '	(SELECT accnt.rowid ';
291
            $sql1 .= '	FROM ' . MAIN_DB_PREFIX . 'accounting_account as accnt';
292
            $sql1 .= '	INNER JOIN ' . MAIN_DB_PREFIX . 'accounting_system as syst';
293
            $sql1 .= '	ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=' . ((int) getDolGlobalInt('CHARTOFACCOUNTS')) . ' AND accnt.entity = ' . ((int) $conf->entity) . ')';
294
            $sql1 .= ' AND erd.fk_expensereport IN (SELECT rowid FROM ' . MAIN_DB_PREFIX . 'expensereport WHERE entity = ' . ((int) $conf->entity) . ')';
295
            $sql1 .= ' AND fk_code_ventilation <> 0';
296
            dol_syslog("htdocs/accountancy/customer/index.php fixaccountancycode", LOG_DEBUG);
297
            $resql1 = $db->query($sql1);
298
            if (!$resql1) {
299
                $error++;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $error seems to be never defined.
Loading history...
300
                $db->rollback();
301
                setEventMessages($db->lasterror(), null, 'errors');
302
            } else {
303
                $db->commit();
304
            }
305
            // End clean database
306
        }
307
308
        if ($action == 'validatehistory') {
309
            $error = 0;
310
            $nbbinddone = 0;
311
            $nbbindfailed = 0;
312
            $notpossible = 0;
313
314
            $db->begin();
315
316
            // Now make the binding
317
            $sql1 = "SELECT erd.rowid, accnt.rowid as suggestedid";
318
            $sql1 .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
319
            $sql1 .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as t ON erd.fk_c_type_fees = t.id";
320
            $sql1 .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as accnt ON t.accountancy_code = accnt.account_number AND accnt.active = 1 AND accnt.fk_pcg_version = '" . $db->escape($chartaccountcode) . "' AND accnt.entity =" . ((int) $conf->entity) . ",";
321
            $sql1 .= " " . MAIN_DB_PREFIX . "expensereport as er";
322
            $sql1 .= " WHERE erd.fk_expensereport = er.rowid AND er.entity = " . ((int) $conf->entity);
323
            $sql1 .= " AND er.fk_statut IN (" . ExpenseReport::STATUS_APPROVED . ", " . ExpenseReport::STATUS_CLOSED . ") AND erd.fk_code_ventilation <= 0";
324
            if ($validatemonth && $validateyear) {
325
                $sql1 .= dolSqlDateFilter('erd.date', 0, $validatemonth, $validateyear);
326
            }
327
328
            dol_syslog('htdocs/accountancy/expensereport/index.php');
329
330
            $result = $db->query($sql1);
331
            if (!$result) {
332
                $error++;
333
                setEventMessages($db->lasterror(), null, 'errors');
334
            } else {
335
                $num_lines = $db->num_rows($result);
336
337
                $i = 0;
338
                while ($i < min($num_lines, 10000)) {   // No more than 10000 at once
339
                    $objp = $db->fetch_object($result);
340
341
                    $lineid = $objp->rowid;
342
                    $suggestedid = $objp->suggestedid;
343
344
                    if ($suggestedid > 0) {
345
                        $sqlupdate = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det";
346
                        $sqlupdate .= " SET fk_code_ventilation = " . ((int) $suggestedid);
347
                        $sqlupdate .= " WHERE fk_code_ventilation <= 0 AND rowid = " . ((int) $lineid);
348
349
                        $resqlupdate = $db->query($sqlupdate);
350
                        if (!$resqlupdate) {
351
                            $error++;
352
                            setEventMessages($db->lasterror(), null, 'errors');
353
                            $nbbindfailed++;
354
                            break;
355
                        } else {
356
                            $nbbinddone++;
357
                        }
358
                    } else {
359
                        $notpossible++;
360
                        $nbbindfailed++;
361
                    }
362
363
                    $i++;
364
                }
365
                if ($num_lines > 10000) {
366
                    $notpossible += ($num_lines - 10000);
367
                }
368
            }
369
370
            if ($error) {
371
                $db->rollback();
372
            } else {
373
                $db->commit();
374
                setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone, $notpossible), null, ($notpossible ? 'warnings' : 'mesgs'));
375
                if ($nbbindfailed) {
376
                    setEventMessages($langs->trans('DoManualBindingForFailedRecord', $nbbindfailed), null, 'warnings');
377
                }
378
            }
379
        }
380
381
382
        /*
383
         * View
384
         */
385
        $help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#Liaisons_comptables';
386
387
        llxHeader('', $langs->trans("ExpenseReportsVentilation"), $help_url);
388
389
        $textprevyear = '<a href="' . $_SERVER['PHP_SELF'] . '?year=' . ($year_current - 1) . '">' . img_previous() . '</a>';
390
        $textnextyear = '&nbsp;<a href="' . $_SERVER['PHP_SELF'] . '?year=' . ($year_current + 1) . '">' . img_next() . '</a>';
391
392
393
        print load_fiche_titre($langs->trans("ExpenseReportsVentilation") . "&nbsp;" . $textprevyear . "&nbsp;" . $langs->trans("Year") . "&nbsp;" . $year_start . "&nbsp;" . $textnextyear, '', 'title_accountancy');
394
395
        print '<span class="opacitymedium">' . $langs->trans("DescVentilExpenseReport") . '</span><br>';
396
        print '<span class="opacitymedium hideonsmartphone">' . $langs->trans("DescVentilExpenseReportMore", $langs->transnoentitiesnoconv("ValidateHistory"), $langs->transnoentitiesnoconv("ToBind")) . '<br>';
397
        print '</span><br>';
398
399
400
        $y = $year_current;
401
402
        $buttonbind = '<a class="button small" href="' . $_SERVER['PHP_SELF'] . '?action=validatehistory&token=' . newToken() . '&year=' . $year_current . '">' . img_picto('', 'link', 'class="paddingright fa-color-unset"') . $langs->trans("ValidateHistory") . '</a>';
403
404
405
        print_barre_liste(img_picto('', 'unlink', 'class="paddingright fa-color-unset"') . $langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1, 0, $buttonbind);
406
//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
407
408
        print '<div class="div-table-responsive-no-min">';
409
        print '<table class="noborder centpercent">';
410
        print '<tr class="liste_titre"><td class="minwidth100">' . $langs->trans("Account") . '</td>';
411
        print '<td>' . $langs->trans("Label") . '</td>';
412
        for ($i = 1; $i <= 12; $i++) {
413
            $j = $i + getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) - 1;
414
            if ($j > 12) {
415
                $j -= 12;
416
            }
417
            $cursormonth = $j;
418
            if ($cursormonth > 12) {
419
                $cursormonth -= 12;
420
            }
421
            $cursoryear = ($cursormonth < getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1)) ? $y + 1 : $y;
422
            $tmp = dol_getdate(dol_get_last_day($cursoryear, $cursormonth, 'gmt'), false, 'gmt');
423
424
            print '<td width="60" class="right">';
425
            if (!empty($tmp['mday'])) {
426
                $param = 'search_date_startday=1&search_date_startmonth=' . $cursormonth . '&search_date_startyear=' . $cursoryear;
427
                $param .= '&search_date_endday=' . $tmp['mday'] . '&search_date_endmonth=' . $tmp['mon'] . '&search_date_endyear=' . $tmp['year'];
428
                $param .= '&search_month=' . $tmp['mon'] . '&search_year=' . $tmp['year'];
429
                print '<a href="' . DOL_URL_ROOT . '/accountancy/expensereport/list.php?' . $param . '">';
430
            }
431
            print $langs->trans('MonthShort' . str_pad((int) $j, 2, '0', STR_PAD_LEFT));
432
            if (!empty($tmp['mday'])) {
433
                print '</a>';
434
            }
435
            print '</td>';
436
        }
437
        print '<td width="60" class="right"><b>' . $langs->trans("Total") . '</b></td></tr>';
438
439
        $sql = "SELECT " . $db->ifsql('aa.account_number IS NULL', "'tobind'", 'aa.account_number') . " AS codecomptable,";
440
        $sql .= " " . $db->ifsql('aa.label IS NULL', "'tobind'", 'aa.label') . " AS intitule,";
441
        for ($i = 1; $i <= 12; $i++) {
442
            $j = $i + getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) - 1;
443
            if ($j > 12) {
444
                $j -= 12;
445
            }
446
            $sql .= "  SUM(" . $db->ifsql("MONTH(er.date_debut) = " . ((int) $j), "erd.total_ht", "0") . ") AS month" . str_pad((int) $j, 2, "0", STR_PAD_LEFT) . ",";
447
        }
448
        $sql .= " SUM(erd.total_ht) as total";
449
        $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
450
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
451
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
452
        $sql .= " WHERE er.date_debut >= '" . $db->idate($search_date_start) . "'";
453
        $sql .= " AND er.date_debut <= '" . $db->idate($search_date_end) . "'";
454
// Define begin binding date
455
        if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
456
            $sql .= " AND er.date_debut >= '" . $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) . "'";
457
        }
458
        $sql .= " AND er.fk_statut IN (" . ExpenseReport::STATUS_APPROVED . ", " . ExpenseReport::STATUS_CLOSED . ")";
459
        $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
460
        $sql .= " AND aa.account_number IS NULL";
461
        $sql .= " GROUP BY erd.fk_code_ventilation,aa.account_number,aa.label";
462
        $sql .= ' ORDER BY aa.account_number';
463
464
        dol_syslog('/accountancy/expensereport/index.php', LOG_DEBUG);
465
        $resql = $db->query($sql);
466
        if ($resql) {
467
            $num = $db->num_rows($resql);
468
469
            while ($row = $db->fetch_row($resql)) {
470
                print '<tr class="oddeven">';
471
                print '<td>';
472
                if ($row[0] == 'tobind') {
473
                    print '<span class="opacitymedium">' . $langs->trans("Unknown") . '</span>';
474
                } else {
475
                    print length_accountg($row[0]);
476
                }
477
                print '</td>';
478
                print '<td>';
479
                if ($row[0] == 'tobind') {
480
                    $startmonth = getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1);
481
                    if ($startmonth > 12) {
482
                        $startmonth -= 12;
483
                    }
484
                    $startyear = ($startmonth < getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1)) ? $y + 1 : $y;
485
                    $endmonth = getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) + 11;
486
                    if ($endmonth > 12) {
487
                        $endmonth -= 12;
488
                    }
489
                    $endyear = ($endmonth < getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1)) ? $y + 1 : $y;
490
                    print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT . '/accountancy/expensereport/list.php?search_date_startday=1&search_date_startmonth=' . ((int) $startmonth) . '&search_date_startyear=' . ((int) $startyear) . '&search_date_endday=&search_date_endmonth=' . ((int) $endmonth) . '&search_date_endyear=' . ((int) $endyear), $langs->transnoentitiesnoconv("ToBind"));
491
                } else {
492
                    print $row[1];
493
                }
494
                print '</td>';
495
                for ($i = 2; $i <= 13; $i++) {
496
                    $cursormonth = (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) + $i - 2);
497
                    if ($cursormonth > 12) {
498
                        $cursormonth -= 12;
499
                    }
500
                    $cursoryear = ($cursormonth < getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1)) ? $y + 1 : $y;
501
                    $tmp = dol_getdate(dol_get_last_day($cursoryear, $cursormonth, 'gmt'), false, 'gmt');
502
503
                    print '<td class="right nowraponall amount">';
504
                    print price($row[$i]);
505
                    // Add link to make binding
506
                    if (!empty(price2num($row[$i]))) {
507
                        print '<a href="' . $_SERVER['PHP_SELF'] . '?action=validatehistory&year=' . $y . '&validatemonth=' . ((int) $cursormonth) . '&validateyear=' . ((int) $cursoryear) . '&token=' . newToken() . '">';
508
                        print img_picto($langs->trans("ValidateHistory") . ' (' . $langs->trans('Month' . str_pad($cursormonth, 2, '0', STR_PAD_LEFT)) . ' ' . $cursoryear . ')', 'link', 'class="marginleft2"');
509
                        print '</a>';
510
                    }
511
                    print '</td>';
512
                }
513
                print '<td class="right nowraponall amount"><b>' . price($row[14]) . '</b></td>';
514
                print '</tr>';
515
            }
516
            $db->free($resql);
517
518
            if ($num == 0) {
519
                print '<tr class="oddeven"><td colspan="16">';
520
                print '<span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span>';
521
                print '</td></tr>';
522
            }
523
        } else {
524
            print $db->lasterror(); // Show last sql error
525
        }
526
        print "</table>\n";
527
        print '</div>';
528
529
530
        print '<br>';
531
532
533
        print_barre_liste(img_picto('', 'link', 'class="paddingright fa-color-unset"') . $langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
534
//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
535
536
537
        print '<div class="div-table-responsive-no-min">';
538
        print '<table class="noborder centpercent">';
539
        print '<tr class="liste_titre"><td class="minwidth100">' . $langs->trans("Account") . '</td>';
540
        print '<td>' . $langs->trans("Label") . '</td>';
541
        for ($i = 1; $i <= 12; $i++) {
542
            $j = $i + getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) - 1;
543
            if ($j > 12) {
544
                $j -= 12;
545
            }
546
            print '<td width="60" class="right">' . $langs->trans('MonthShort' . str_pad((int) $j, 2, '0', STR_PAD_LEFT)) . '</td>';
547
        }
548
        print '<td width="60" class="right"><b>' . $langs->trans("Total") . '</b></td></tr>';
549
550
        $sql = "SELECT " . $db->ifsql('aa.account_number IS NULL', "'tobind'", 'aa.account_number') . " AS codecomptable,";
551
        $sql .= "  " . $db->ifsql('aa.label IS NULL', "'tobind'", 'aa.label') . " AS intitule,";
552
        for ($i = 1; $i <= 12; $i++) {
553
            $j = $i + getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) - 1;
554
            if ($j > 12) {
555
                $j -= 12;
556
            }
557
            $sql .= " SUM(" . $db->ifsql("MONTH(er.date_debut) = " . ((int) $j), "erd.total_ht", "0") . ") AS month" . str_pad((int) $j, 2, "0", STR_PAD_LEFT) . ",";
558
        }
559
        $sql .= " ROUND(SUM(erd.total_ht),2) as total";
560
        $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
561
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
562
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
563
        $sql .= " WHERE er.date_debut >= '" . $db->idate($search_date_start) . "'";
564
        $sql .= " AND er.date_debut <= '" . $db->idate($search_date_end) . "'";
565
// Define begin binding date
566
        if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
567
            $sql .= " AND er.date_debut >= '" . $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) . "'";
568
        }
569
        $sql .= " AND er.fk_statut IN (" . ExpenseReport::STATUS_APPROVED . ", " . ExpenseReport::STATUS_CLOSED . ")";
570
        $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
571
        $sql .= " AND aa.account_number IS NOT NULL";
572
        $sql .= " GROUP BY erd.fk_code_ventilation,aa.account_number,aa.label";
573
574
        dol_syslog('htdocs/accountancy/expensereport/index.php');
575
        $resql = $db->query($sql);
576
        if ($resql) {
577
            $num = $db->num_rows($resql);
578
579
            while ($row = $db->fetch_row($resql)) {
580
                print '<tr class="oddeven">';
581
                print '<td>';
582
                if ($row[0] == 'tobind') {
583
                    print '<span class="opacitymedium">' . $langs->trans("Unknown") . '</span>';
584
                } else {
585
                    print length_accountg($row[0]);
586
                }
587
                print '</td>';
588
589
                print '<td>';
590
                if ($row[0] == 'tobind') {
591
                    print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT . '/accountancy/expensereport/list.php?search_year=' . ((int) $y), $langs->transnoentitiesnoconv("ToBind"));
592
                } else {
593
                    print $row[1];
594
                }
595
                print '</td>';
596
                for ($i = 2; $i <= 13; $i++) {
597
                    print '<td class="right nowraponall amount">';
598
                    print price($row[$i]);
599
                    print '</td>';
600
                }
601
                print '<td class="right nowraponall amount"><b>' . price($row[14]) . '</b></td>';
602
                print '</tr>';
603
            }
604
            $db->free($resql);
605
606
            if ($num == 0) {
607
                print '<tr class="oddeven"><td colspan="16">';
608
                print '<span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span>';
609
                print '</td></tr>';
610
            }
611
        } else {
612
            print $db->lasterror(); // Show last sql error
613
        }
614
        print "</table>\n";
615
        print '</div>';
616
617
618
619
        if (getDolGlobalString('SHOW_TOTAL_OF_PREVIOUS_LISTS_IN_LIN_PAGE')) { // This part of code looks strange. Why showing a report that should rely on result of this step ?
620
            print '<br>';
621
            print '<br>';
622
623
            print_barre_liste($langs->trans("OtherInfo"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
624
            //print load_fiche_titre($langs->trans("OtherInfo"), '', '');
625
626
            print '<div class="div-table-responsive-no-min">';
627
            print '<table class="noborder centpercent">';
628
            print '<tr class="liste_titre"><td class="left">' . $langs->trans("Total") . '</td>';
629
            for ($i = 1; $i <= 12; $i++) {
630
                $j = $i + getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) - 1;
631
                if ($j > 12) {
632
                    $j -= 12;
633
                }
634
                print '<td width="60" class="right">' . $langs->trans('MonthShort' . str_pad($j, 2, '0', STR_PAD_LEFT)) . '</td>';
635
            }
636
            print '<td width="60" class="right"><b>' . $langs->trans("Total") . '</b></td></tr>';
637
638
            $sql = "SELECT '" . $db->escape($langs->trans("TotalExpenseReport")) . "' AS label,";
639
            for ($i = 1; $i <= 12; $i++) {
640
                $j = $i + getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1) - 1;
641
                if ($j > 12) {
642
                    $j -= 12;
643
                }
644
                $sql .= " SUM(" . $db->ifsql("MONTH(er.date_create) = " . ((int) $j), "erd.total_ht", "0") . ") AS month" . str_pad((int) $j, 2, "0", STR_PAD_LEFT) . ",";
645
            }
646
            $sql .= " SUM(erd.total_ht) as total";
647
            $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
648
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
649
            $sql .= " WHERE er.date_debut >= '" . $db->idate($search_date_start) . "'";
650
            $sql .= " AND er.date_debut <= '" . $db->idate($search_date_end) . "'";
651
            // Define begin binding date
652
            if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
653
                $sql .= " AND er.date_debut >= '" . $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) . "'";
654
            }
655
            $sql .= " AND er.fk_statut IN (" . ExpenseReport::STATUS_APPROVED . ", " . ExpenseReport::STATUS_CLOSED . ")";
656
            $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
657
658
            dol_syslog('htdocs/accountancy/expensereport/index.php');
659
            $resql = $db->query($sql);
660
            if ($resql) {
661
                $num = $db->num_rows($resql);
662
663
                while ($row = $db->fetch_row($resql)) {
664
                    print '<tr><td>' . $row[0] . '</td>';
665
                    for ($i = 1; $i <= 12; $i++) {
666
                        print '<td class="right nowraponall amount">' . price($row[$i]) . '</td>';
667
                    }
668
                    print '<td class="right nowraponall amount"><b>' . price($row[13]) . '</b></td>';
669
                    print '</tr>';
670
                }
671
672
                $db->free($resql);
673
            } else {
674
                print $db->lasterror(); // Show last sql error
675
            }
676
            print "</table>\n";
677
            print '</div>';
678
        }
679
680
// End of page
681
        llxFooter();
682
        $db->close();
683
    }
684
685
    /**
686
     * \file        htdocs/accountancy/expensereport/lines.php
687
     * \ingroup     Accountancy (Double entries)
688
     * \brief       Page of detail of the lines of ventilation of expense reports
689
     */
690
    public function lines()
691
    {
692
        global $conf;
693
        global $db;
694
        global $user;
695
        global $hookmanager;
696
        global $user;
697
        global $menumanager;
698
        global $langs;
699
        global $mysoc;
700
701
// Load translation files required by the page
702
        $langs->loadLangs(array("compta", "bills", "other", "accountancy", "trips", "productbatch", "hrm"));
703
704
        $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
705
706
        $account_parent = GETPOSTINT('account_parent');
707
        $changeaccount = GETPOST('changeaccount');
708
// Search Getpost
709
        $search_login = GETPOST('search_login', 'alpha');
710
        $search_expensereport = GETPOST('search_expensereport', 'alpha');
711
        $search_label = GETPOST('search_label', 'alpha');
712
        $search_desc = GETPOST('search_desc', 'alpha');
713
        $search_amount = GETPOST('search_amount', 'alpha');
714
        $search_account = GETPOST('search_account', 'alpha');
715
        $search_vat = GETPOST('search_vat', 'alpha');
716
        $search_date_startday = GETPOSTINT('search_date_startday');
717
        $search_date_startmonth = GETPOSTINT('search_date_startmonth');
718
        $search_date_startyear = GETPOSTINT('search_date_startyear');
719
        $search_date_endday = GETPOSTINT('search_date_endday');
720
        $search_date_endmonth = GETPOSTINT('search_date_endmonth');
721
        $search_date_endyear = GETPOSTINT('search_date_endyear');
722
        $search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear);   // Use tzserver
723
        $search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
724
725
// Load variable for pagination
726
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : getDolGlobalString('ACCOUNTING_LIMIT_LIST_VENTILATION', $conf->liste_limit);
727
        $sortfield = GETPOST('sortfield', 'aZ09comma');
728
        $sortorder = GETPOST('sortorder', 'aZ09comma');
729
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
730
        if (empty($page) || $page < 0) {
731
            $page = 0;
732
        }
733
        $offset = $limit * $page;
734
        $pageprev = $page - 1;
735
        $pagenext = $page + 1;
736
        if (!$sortfield) {
737
            $sortfield = "erd.date, erd.rowid";
738
        }
739
        if (!$sortorder) {
740
            if (getDolGlobalInt('ACCOUNTING_LIST_SORT_VENTILATION_DONE') > 0) {
741
                $sortorder = "DESC";
742
            } else {
743
                $sortorder = "ASC";
744
            }
745
        }
746
747
// Security check
748
        if (!isModEnabled('accounting')) {
749
            accessforbidden();
750
        }
751
        if ($user->socid > 0) {
752
            accessforbidden();
753
        }
754
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
755
            accessforbidden();
756
        }
757
758
759
        $formaccounting = new FormAccounting($db);
760
761
762
        /*
763
         * Actions
764
         */
765
766
// Purge search criteria
767
        if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // Both test are required to be compatible with all browsers
768
            $search_login = '';
769
            $search_expensereport = '';
770
            $search_label = '';
771
            $search_desc = '';
772
            $search_amount = '';
773
            $search_account = '';
774
            $search_vat = '';
775
            $search_date_startday = '';
776
            $search_date_startmonth = '';
777
            $search_date_startyear = '';
778
            $search_date_endday = '';
779
            $search_date_endmonth = '';
780
            $search_date_endyear = '';
781
            $search_date_start = '';
782
            $search_date_end = '';
783
        }
784
785
        if (is_array($changeaccount) && count($changeaccount) > 0 && $user->hasRight('accounting', 'bind', 'write')) {
786
            $error = 0;
787
788
            if (!(GETPOSTINT('account_parent') >= 0)) {
789
                $error++;
790
                setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Account")), null, 'errors');
791
            }
792
793
            if (!$error) {
794
                $db->begin();
795
796
                $sql1 = "UPDATE " . MAIN_DB_PREFIX . "expensereport_det as erd";
797
                $sql1 .= " SET erd.fk_code_ventilation=" . (GETPOSTINT('account_parent') > 0 ? GETPOSTINT('account_parent') : '0');
798
                $sql1 .= ' WHERE erd.rowid IN (' . $db->sanitize(implode(',', $changeaccount)) . ')';
799
800
                dol_syslog('accountancy/expensereport/lines.php::changeaccount sql= ' . $sql1);
801
                $resql1 = $db->query($sql1);
802
                if (!$resql1) {
803
                    $error++;
804
                    setEventMessages($db->lasterror(), null, 'errors');
805
                }
806
                if (!$error) {
807
                    $db->commit();
808
                    setEventMessages($langs->trans("Save"), null, 'mesgs');
809
                } else {
810
                    $db->rollback();
811
                    setEventMessages($db->lasterror(), null, 'errors');
812
                }
813
814
                $account_parent = ''; // Protection to avoid to mass apply it a second time
815
            }
816
        }
817
818
        if (GETPOST('sortfield') == 'erd.date, erd.rowid') {
819
            $value = (GETPOST('sortorder') == 'asc,asc' ? 0 : 1);
820
            require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
821
            $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_DONE", $value, 'yesno', 0, '', $conf->entity);
822
        }
823
824
825
        /*
826
         * View
827
         */
828
829
        $form = new Form($db);
830
        $formother = new FormOther($db);
831
832
        $help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#Liaisons_comptables';
833
834
        llxHeader('', $langs->trans("ExpenseReportsVentilation") . ' - ' . $langs->trans("Dispatched"), $help_url);
835
836
        print '<script type="text/javascript">
837
			$(function () {
838
				$(\'#select-all\').click(function(event) {
839
				    // Iterate each checkbox
840
				    $(\':checkbox\').each(function() {
841
				    	this.checked = true;
842
				    });
843
			    });
844
			    $(\'#unselect-all\').click(function(event) {
845
				    // Iterate each checkbox
846
				    $(\':checkbox\').each(function() {
847
				    	this.checked = false;
848
				    });
849
			    });
850
			});
851
			 </script>';
852
853
        /*
854
         * Expense reports lines
855
         */
856
        $sql = "SELECT er.ref, er.rowid as erid,";
857
        $sql .= " erd.rowid, erd.fk_c_type_fees, erd.comments, erd.total_ht, erd.fk_code_ventilation, erd.tva_tx, erd.vat_src_code, erd.date,";
858
        $sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label,";
859
        $sql .= " u.rowid as userid, u.login, u.lastname, u.firstname, u.email, u.gender, u.employee, u.photo, u.statut,";
860
        $sql .= " aa.label, aa.labelshort, aa.account_number";
861
        $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport as er";
862
        $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "expensereport_det as erd ON er.rowid = erd.fk_expensereport";
863
        $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
864
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees";
865
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = er.fk_user_author";
866
        $sql .= " WHERE erd.fk_code_ventilation > 0";
867
        $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
868
        $sql .= " AND er.fk_statut IN (" . ExpenseReport::STATUS_APPROVED . ", " . ExpenseReport::STATUS_CLOSED . ")";
869
// Add search filter like
870
        if (strlen(trim($search_login))) {
871
            $sql .= natural_search("u.login", $search_login);
872
        }
873
        if (strlen(trim($search_expensereport))) {
874
            $sql .= natural_search("er.ref", $search_expensereport);
875
        }
876
        if (strlen(trim($search_label))) {
877
            $sql .= natural_search("f.label", $search_label);
878
        }
879
        if (strlen(trim($search_desc))) {
880
            $sql .= natural_search("er.comments", $search_desc);
881
        }
882
        if (strlen(trim($search_amount))) {
883
            $sql .= natural_search("erd.total_ht", $search_amount, 1);
884
        }
885
        if (strlen(trim($search_account))) {
886
            $sql .= natural_search("aa.account_number", $search_account);
887
        }
888
        if (strlen(trim($search_vat))) {
889
            $sql .= natural_search("erd.tva_tx", price2num($search_vat), 1);
890
        }
891
        if ($search_date_start) {
892
            $sql .= " AND erd.date >= '" . $db->idate($search_date_start) . "'";
893
        }
894
        if ($search_date_end) {
895
            $sql .= " AND erd.date <= '" . $db->idate($search_date_end) . "'";
896
        }
897
        $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
898
899
        $sql .= $db->order($sortfield, $sortorder);
900
901
// Count total nb of records
902
        $nbtotalofrecords = '';
903
        if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
904
            $result = $db->query($sql);
905
            $nbtotalofrecords = $db->num_rows($result);
906
            if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
907
                $page = 0;
908
                $offset = 0;
909
            }
910
        }
911
912
        $sql .= $db->plimit($limit + 1, $offset);
913
914
        dol_syslog("accountancy/expensereport/lines.php", LOG_DEBUG);
915
        $result = $db->query($sql);
916
        if ($result) {
917
            $num_lines = $db->num_rows($result);
918
            $i = 0;
919
920
            $param = '';
921
            if (!empty($contextpage) && $contextpage != $_SERVER['PHP_SELF']) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $contextpage seems to never exist and therefore empty should always be true.
Loading history...
922
                $param .= '&contextpage=' . urlencode($contextpage);
923
            }
924
            if ($limit > 0 && $limit != $conf->liste_limit) {
925
                $param .= '&limit=' . ((int) $limit);
926
            }
927
            if ($search_login) {
928
                $param .= '&search_login=' . urlencode($search_login);
929
            }
930
            if ($search_expensereport) {
931
                $param .= "&search_expensereport=" . urlencode($search_expensereport);
932
            }
933
            if ($search_label) {
934
                $param .= "&search_label=" . urlencode($search_label);
935
            }
936
            if ($search_desc) {
937
                $param .= "&search_desc=" . urlencode($search_desc);
938
            }
939
            if ($search_account) {
940
                $param .= "&search_account=" . urlencode($search_account);
941
            }
942
            if ($search_vat) {
943
                $param .= "&search_vat=" . urlencode($search_vat);
944
            }
945
            if ($search_date_startday) {
946
                $param .= '&search_date_startday=' . urlencode((string) ($search_date_startday));
947
            }
948
            if ($search_date_startmonth) {
949
                $param .= '&search_date_startmonth=' . urlencode((string) ($search_date_startmonth));
950
            }
951
            if ($search_date_startyear) {
952
                $param .= '&search_date_startyear=' . urlencode((string) ($search_date_startyear));
953
            }
954
            if ($search_date_endday) {
955
                $param .= '&search_date_endday=' . urlencode((string) ($search_date_endday));
956
            }
957
            if ($search_date_endmonth) {
958
                $param .= '&search_date_endmonth=' . urlencode((string) ($search_date_endmonth));
959
            }
960
            if ($search_date_endyear) {
961
                $param .= '&search_date_endyear=' . urlencode((string) ($search_date_endyear));
962
            }
963
964
            print '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">' . "\n";
965
            print '<input type="hidden" name="action" value="ventil">';
966
            if ($optioncss != '') {
967
                print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
968
            }
969
            print '<input type="hidden" name="token" value="' . newToken() . '">';
970
            print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
971
            print '<input type="hidden" name="sortfield" value="' . $sortfield . '">';
972
            print '<input type="hidden" name="sortorder" value="' . $sortorder . '">';
973
            print '<input type="hidden" name="page" value="' . $page . '">';
974
975
            // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
976
            print_barre_liste($langs->trans("ExpenseReportLinesDone"), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
977
            print '<span class="opacitymedium">' . $langs->trans("DescVentilDoneExpenseReport") . '</span><br>';
978
979
            print '<br><div class="inline-block divButAction paddingbottom">' . $langs->trans("ChangeAccount") . ' ';
980
            print $formaccounting->select_account($account_parent, 'account_parent', 2, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone valignmiddle');
981
            print '<input type="submit" class="button small valignmiddle" value="' . $langs->trans("ChangeBinding") . '"/></div>';
982
983
            $moreforfilter = '';
984
985
            print '<div class="div-table-responsive">';
986
            print '<table class="tagtable liste' . ($moreforfilter ? " listwithfilterbefore" : "") . '">' . "\n";
987
988
            print '<tr class="liste_titre_filter">';
989
            print '<td class="liste_titre"><input type="text" name="search_login" class="maxwidth50" value="' . $search_login . '"></td>';
990
            print '<td class="liste_titre"></td>';
991
            print '<td><input type="text" class="flat maxwidth50" name="search_expensereport" value="' . dol_escape_htmltag($search_expensereport) . '"></td>';
992
            if (getDolGlobalString('ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE')) {
993
                print '<td class="liste_titre"></td>';
994
            }
995
            print '<td class="liste_titre center">';
996
            print '<div class="nowrapfordate">';
997
            print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
998
            print '</div>';
999
            print '<div class="nowrapfordate">';
1000
            print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1001
            print '</div>';
1002
            print '</td>';
1003
            print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
1004
            print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
1005
            print '<td class="liste_titre right"><input type="text" class="flat maxwidth50" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
1006
            print '<td class="liste_titre center"><input type="text" class="flat maxwidth50" name="search_vat" size="1" placeholder="%" value="' . dol_escape_htmltag($search_vat) . '"></td>';
1007
            print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_account" value="' . dol_escape_htmltag($search_account) . '"></td>';
1008
            print '<td class="liste_titre center">';
1009
            $searchpicto = $form->showFilterButtons();
1010
            print $searchpicto;
1011
            print '</td>';
1012
            print "</tr>\n";
1013
1014
            print '<tr class="liste_titre">';
1015
            print_liste_field_titre("Employees", $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
1016
            print_liste_field_titre("LineId", $_SERVER['PHP_SELF'], "erd.rowid", "", $param, '', $sortfield, $sortorder);
1017
            print_liste_field_titre("ExpenseReport", $_SERVER['PHP_SELF'], "er.ref", "", $param, '', $sortfield, $sortorder);
1018
            if (getDolGlobalString('ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE')) {
1019
                print_liste_field_titre("DateValidation", $_SERVER['PHP_SELF'], "er.date_valid", "", $param, '', $sortfield, $sortorder, 'center ');
1020
            }
1021
            print_liste_field_titre("DateOfLine", $_SERVER['PHP_SELF'], "erd.date, erd.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
1022
            print_liste_field_titre("TypeFees", $_SERVER['PHP_SELF'], "f.label", "", $param, '', $sortfield, $sortorder);
1023
            print_liste_field_titre("Description", $_SERVER['PHP_SELF'], "erd.comments", "", $param, '', $sortfield, $sortorder);
1024
            print_liste_field_titre("Amount", $_SERVER['PHP_SELF'], "erd.total_ht", "", $param, '', $sortfield, $sortorder, 'right ');
1025
            print_liste_field_titre("VATRate", $_SERVER['PHP_SELF'], "erd.tva_tx", "", $param, '', $sortfield, $sortorder, 'center ');
1026
            print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "aa.account_number", "", $param, '', $sortfield, $sortorder);
1027
            $checkpicto = $form->showCheckAddButtons();
1028
            print_liste_field_titre($checkpicto, '', '', '', '', '', '', '', 'center ');
1029
            print "</tr>\n";
1030
1031
            $expensereportstatic = new ExpenseReport($db);
1032
            $accountingaccountstatic = new AccountingAccount($db);
1033
            $userstatic = new User($db);
1034
1035
            $i = 0;
1036
            while ($i < min($num_lines, $limit)) {
1037
                $objp = $db->fetch_object($result);
1038
1039
                $expensereportstatic->ref = $objp->ref;
1040
                $expensereportstatic->id = $objp->erid;
1041
1042
                $userstatic->id = $objp->userid;
1043
                $userstatic->ref = $objp->label;
1044
                $userstatic->login = $objp->login;
1045
                $userstatic->statut = $objp->statut;
1046
                $userstatic->email = $objp->email;
1047
                $userstatic->gender = $objp->gender;
1048
                $userstatic->firstname = $objp->firstname;
1049
                $userstatic->lastname = $objp->lastname;
1050
                $userstatic->employee = $objp->employee;
1051
                $userstatic->photo = $objp->photo;
1052
1053
                $accountingaccountstatic->rowid = $objp->fk_compte;
1054
                $accountingaccountstatic->label = $objp->label;
1055
                $accountingaccountstatic->labelshort = $objp->labelshort;
1056
                $accountingaccountstatic->account_number = $objp->account_number;
1057
1058
                print '<tr class="oddeven">';
1059
1060
                // Login
1061
                print '<td class="nowraponall">';
1062
                print $userstatic->getNomUrl(-1, '', 0, 0, 24, 1, 'login', '', 1);
1063
                print '</td>';
1064
1065
                // Line id
1066
                print '<td>' . $objp->rowid . '</td>';
1067
1068
                // Ref Expense report
1069
                print '<td>' . $expensereportstatic->getNomUrl(1) . '</td>';
1070
1071
                // Date validation
1072
                if (getDolGlobalString('ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE')) {
1073
                    print '<td class="center">' . dol_print_date($db->jdate($objp->date_valid), 'day') . '</td>';
1074
                }
1075
1076
                print '<td class="center">' . dol_print_date($db->jdate($objp->date), 'day') . '</td>';
1077
1078
                // Fees label
1079
                print '<td class="tdoverflow">' . ($langs->trans($objp->type_fees_code) == $objp->type_fees_code ? $objp->type_fees_label : $langs->trans(($objp->type_fees_code))) . '</td>';
1080
1081
                // Fees description -- Can be null
1082
                print '<td>';
1083
                $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1));
1084
                $trunclength = getDolGlobalString('ACCOUNTING_LENGTH_DESCRIPTION', 32);
1085
                print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments);
1086
                print '</td>';
1087
1088
                // Amount without taxes
1089
                print '<td class="right nowraponall amount">' . price($objp->total_ht) . '</td>';
1090
1091
                // Vat rate
1092
                print '<td class="center">' . vatrate($objp->tva_tx . ($objp->vat_src_code ? ' (' . $objp->vat_src_code . ')' : '')) . '</td>';
1093
1094
                // Accounting account affected
1095
                print '<td>';
1096
                print $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1);
1097
                print ' <a class="editfielda reposition marginleftonly marginrightonly" href="./card.php?id=' . $objp->rowid . '&backtopage=' . urlencode($_SERVER['PHP_SELF'] . ($param ? '?' . $param : '')) . '">';
1098
                print img_edit();
1099
                print '</a></td>';
1100
                print '<td class="center"><input type="checkbox" class="checkforaction" name="changeaccount[]" value="' . $objp->rowid . '"/></td>';
1101
1102
                print "</tr>";
1103
                $i++;
1104
            }
1105
            if ($num_lines == 0) {
1106
                $colspan = 10;
1107
                if (getDolGlobalString('ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE')) {
1108
                    $colspan++;
1109
                }
1110
                print '<tr><td colspan="' . $colspan . '"><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
1111
            }
1112
1113
            print "</table>";
1114
            print "</div>";
1115
1116
            if ($nbtotalofrecords > $limit) {
1117
                print_barre_liste('', $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, '', 0, '', '', $limit, 1);
1118
            }
1119
1120
            print '</form>';
1121
        } else {
1122
            print $db->lasterror();
1123
        }
1124
1125
// End of page
1126
        llxFooter();
1127
        $db->close();
1128
    }
1129
1130
    /**
1131
     * \file        htdocs/accountancy/expensereport/list.php
1132
     * \ingroup     Accountancy (Double entries)
1133
     * \brief       Ventilation page from expense reports
1134
     */
1135
    public function list()
1136
    {
1137
        global $conf;
1138
        global $db;
1139
        global $user;
1140
        global $hookmanager;
1141
        global $user;
1142
        global $menumanager;
1143
        global $langs;
1144
        global $mysoc;
1145
1146
// Load translation files required by the page
1147
        $langs->loadLangs(array("bills", "companies", "compta", "accountancy", "other", "trips", "productbatch", "hrm"));
1148
1149
        $action = GETPOST('action', 'aZ09');
1150
        $massaction = GETPOST('massaction', 'alpha');
1151
        $confirm = GETPOST('confirm', 'alpha');
1152
        $toselect = GETPOST('toselect', 'array');
1153
        $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'accountancyexpensereportlist'; // To manage different context of search
1154
        $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
1155
1156
1157
// Select Box
1158
        $mesCasesCochees = GETPOST('toselect', 'array');
1159
1160
// Search Getpost
1161
        $search_login = GETPOST('search_login', 'alpha');
1162
        $search_lineid = GETPOST('search_lineid', 'alpha');
1163
        $search_expensereport = GETPOST('search_expensereport', 'alpha');
1164
        $search_label = GETPOST('search_label', 'alpha');
1165
        $search_desc = GETPOST('search_desc', 'alpha');
1166
        $search_amount = GETPOST('search_amount', 'alpha');
1167
        $search_account = GETPOST('search_account', 'alpha');
1168
        $search_vat = GETPOST('search_vat', 'alpha');
1169
        $search_date_startday = GETPOSTINT('search_date_startday');
1170
        $search_date_startmonth = GETPOSTINT('search_date_startmonth');
1171
        $search_date_startyear = GETPOSTINT('search_date_startyear');
1172
        $search_date_endday = GETPOSTINT('search_date_endday');
1173
        $search_date_endmonth = GETPOSTINT('search_date_endmonth');
1174
        $search_date_endyear = GETPOSTINT('search_date_endyear');
1175
        $search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear);   // Use tzserver
1176
        $search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
1177
1178
// Define begin binding date
1179
        if (empty($search_date_start) && getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
1180
            $search_date_start = $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING'));
1181
        }
1182
1183
// Load variable for pagination
1184
        $limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : getDolGlobalString('ACCOUNTING_LIMIT_LIST_VENTILATION', $conf->liste_limit);
1185
        $sortfield = GETPOST('sortfield', 'aZ09comma');
1186
        $sortorder = GETPOST('sortorder', 'aZ09comma');
1187
        $page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
1188
        if (empty($page) || $page < 0) {
1189
            $page = 0;
1190
        }
1191
        $offset = $limit * $page;
1192
        $pageprev = $page - 1;
1193
        $pagenext = $page + 1;
1194
        if (!$sortfield) {
1195
            $sortfield = "erd.date, erd.rowid";
1196
        }
1197
        if (!$sortorder) {
1198
            if (getDolGlobalInt('ACCOUNTING_LIST_SORT_VENTILATION_TODO') > 0) {
1199
                $sortorder = "DESC";
1200
            } else {
1201
                $sortorder = "ASC";
1202
            }
1203
        }
1204
1205
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1206
        $hookmanager->initHooks(array('accountancyexpensereportlist'));
1207
1208
        $formaccounting = new FormAccounting($db);
1209
        $accounting = new AccountingAccount($db);
1210
1211
        $chartaccountcode = dol_getIdFromCode($db, getDolGlobalInt('CHARTOFACCOUNTS'), 'accounting_system', 'rowid', 'pcg_version');
1212
1213
// Security check
1214
        if (!isModEnabled('accounting')) {
1215
            accessforbidden();
1216
        }
1217
        if ($user->socid > 0) {
1218
            accessforbidden();
1219
        }
1220
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
1221
            accessforbidden();
1222
        }
1223
1224
1225
        /*
1226
         * Actions
1227
         */
1228
1229
        if (GETPOST('cancel', 'alpha')) {
1230
            $action = 'list';
1231
            $massaction = '';
1232
        }
1233
        if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
1234
            $massaction = '';
1235
        }
1236
1237
        $parameters = array();
1238
        $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 does not exist. Did you maybe mean $objectlabel?
Loading history...
1239
        if ($reshook < 0) {
1240
            setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1241
        }
1242
1243
        if (empty($reshook)) {
1244
            // Purge search criteria
1245
            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
1246
                $search_login = '';
1247
                $search_expensereport = '';
1248
                $search_label = '';
1249
                $search_desc = '';
1250
                $search_amount = '';
1251
                $search_account = '';
1252
                $search_vat = '';
1253
                $search_date_startday = '';
1254
                $search_date_startmonth = '';
1255
                $search_date_startyear = '';
1256
                $search_date_endday = '';
1257
                $search_date_endmonth = '';
1258
                $search_date_endyear = '';
1259
                $search_date_start = '';
1260
                $search_date_end = '';
1261
                $search_country = '';
1262
                $search_tvaintra = '';
1263
            }
1264
1265
            // Mass actions
1266
            $objectclass = 'ExpenseReport';
1267
            $objectlabel = 'ExpenseReport';
1268
            $permissiontoread = $user->hasRight('accounting', 'read');
1269
            $permissiontodelete = $user->hasRight('accounting', 'delete');
1270
            $uploaddir = $conf->expensereport->dir_output;
1271
            include DOL_DOCUMENT_ROOT . '/core/actions_massactions.inc.php';
1272
        }
1273
1274
1275
        if ($massaction == 'ventil' && $user->hasRight('accounting', 'bind', 'write')) {
1276
            $msg = '';
1277
1278
            if (!empty($mesCasesCochees)) {
1279
                $msg = '<div>' . $langs->trans("SelectedLines") . ': ' . count($mesCasesCochees) . '</div>';
1280
                $msg .= '<div class="detail">';
1281
                $cpt = 0;
1282
                $ok = 0;
1283
                $ko = 0;
1284
1285
                foreach ($mesCasesCochees as $maLigneCochee) {
1286
                    $maLigneCourante = explode("_", $maLigneCochee);
1287
                    $monId = $maLigneCourante[0];
1288
                    $monCompte = GETPOST('codeventil' . $monId);
1289
1290
                    if ($monCompte <= 0) {
1291
                        $msg .= '<div><span class="error">' . $langs->trans("Lineofinvoice") . ' ' . $monId . ' - ' . $langs->trans("NoAccountSelected") . '</span></div>';
1292
                        $ko++;
1293
                    } else {
1294
                        $sql = " UPDATE " . MAIN_DB_PREFIX . "expensereport_det";
1295
                        $sql .= " SET fk_code_ventilation = " . ((int) $monCompte);
1296
                        $sql .= " WHERE rowid = " . ((int) $monId);
1297
1298
                        $accountventilated = new AccountingAccount($db);
1299
                        $accountventilated->fetch($monCompte, '', 1);
1300
1301
                        dol_syslog('accountancy/expensereport/list.php:: sql=' . $sql, LOG_DEBUG);
1302
                        if ($db->query($sql)) {
1303
                            $msg .= '<div><span class="green">' . $langs->trans("LineOfExpenseReport") . ' ' . $monId . ' - ' . $langs->trans("VentilatedinAccount") . ' : ' . length_accountg($accountventilated->account_number) . '</span></div>';
1304
                            $ok++;
1305
                        } else {
1306
                            $msg .= '<div><span class="error">' . $langs->trans("ErrorDB") . ' : ' . $langs->trans("Lineofinvoice") . ' ' . $monId . ' - ' . $langs->trans("NotVentilatedinAccount") . ' : ' . length_accountg($accountventilated->account_number) . '<br> <pre>' . $sql . '</pre></span></div>';
1307
                            $ko++;
1308
                        }
1309
                    }
1310
1311
                    $cpt++;
1312
                }
1313
                $msg .= '</div>';
1314
                $msg .= '<div>' . $langs->trans("EndProcessing") . '</div>';
1315
            }
1316
        }
1317
1318
        if (GETPOST('sortfield') == 'erd.date, erd.rowid') {
1319
            $value = (GETPOST('sortorder') == 'asc,asc' ? 0 : 1);
1320
            require_once DOL_DOCUMENT_ROOT . '/core/lib/admin.lib.php';
1321
            $res = dolibarr_set_const($db, "ACCOUNTING_LIST_SORT_VENTILATION_TODO", $value, 'yesno', 0, '', $conf->entity);
1322
        }
1323
1324
1325
        /*
1326
         * View
1327
         */
1328
1329
        $form = new Form($db);
1330
        $formother = new FormOther($db);
1331
1332
        $help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#Liaisons_comptables';
1333
1334
        llxHeader('', $langs->trans("ExpenseReportsVentilation"), $help_url);
1335
1336
        if (empty($chartaccountcode)) {
1337
            print $langs->trans("ErrorChartOfAccountSystemNotSelected");
1338
            // End of page
1339
            llxFooter();
1340
            $db->close();
1341
            exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1342
        }
1343
1344
// Expense report lines
1345
        $sql = "SELECT er.ref, er.rowid as erid, er.date_debut, er.date_valid,";
1346
        $sql .= " erd.rowid, erd.fk_c_type_fees, erd.comments, erd.total_ht as price, erd.fk_code_ventilation, erd.tva_tx as tva_tx_line, erd.vat_src_code, erd.date,";
1347
        $sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label, f.accountancy_code as code_buy,";
1348
        $sql .= " u.rowid as userid, u.login, u.lastname, u.firstname, u.email, u.gender, u.employee, u.photo, u.statut,";
1349
        $sql .= " aa.rowid as aarowid";
1350
        $parameters = array();
1351
        $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
1352
        $sql .= $hookmanager->resPrint;
1353
        $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport as er";
1354
        $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "expensereport_det as erd ON er.rowid = erd.fk_expensereport";
1355
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees";
1356
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = er.fk_user_author";
1357
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON f.accountancy_code = aa.account_number AND aa.fk_pcg_version = '" . $db->escape($chartaccountcode) . "' AND aa.entity = " . $conf->entity;
1358
        $sql .= " WHERE er.fk_statut IN (" . ExpenseReport::STATUS_APPROVED . ", " . ExpenseReport::STATUS_CLOSED . ") AND erd.fk_code_ventilation <= 0";
1359
// Add search filter like
1360
        if (strlen(trim($search_login))) {
1361
            $sql .= natural_search("u.login", $search_login);
1362
        }
1363
        if (strlen(trim($search_expensereport))) {
1364
            $sql .= natural_search("er.ref", $search_expensereport);
1365
        }
1366
        if (strlen(trim($search_label))) {
1367
            $sql .= natural_search("f.label", $search_label);
1368
        }
1369
        if (strlen(trim($search_desc))) {
1370
            $sql .= natural_search("erd.comments", $search_desc);
1371
        }
1372
        if (strlen(trim($search_amount))) {
1373
            $sql .= natural_search("erd.total_ht", $search_amount, 1);
1374
        }
1375
        if (strlen(trim($search_account))) {
1376
            $sql .= natural_search("aa.account_number", $search_account);
1377
        }
1378
        if (strlen(trim($search_vat))) {
1379
            $sql .= natural_search("erd.tva_tx", $search_vat, 1);
1380
        }
1381
        if ($search_date_start) {
1382
            $sql .= " AND erd.date >= '" . $db->idate($search_date_start) . "'";
1383
        }
1384
        if ($search_date_end) {
1385
            $sql .= " AND erd.date <= '" . $db->idate($search_date_end) . "'";
1386
        }
1387
        $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
1388
1389
// Add where from hooks
1390
        $parameters = array();
1391
        $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
1392
        $sql .= $hookmanager->resPrint;
1393
1394
        $sql .= $db->order($sortfield, $sortorder);
1395
1396
// Count total nb of records
1397
        $nbtotalofrecords = '';
1398
        if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
1399
            $result = $db->query($sql);
1400
            $nbtotalofrecords = $db->num_rows($result);
1401
            if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
1402
                $page = 0;
1403
                $offset = 0;
1404
            }
1405
        }
1406
//print $sql;
1407
1408
        $sql .= $db->plimit($limit + 1, $offset);
1409
1410
        dol_syslog("accountancy/expensereport/list.php", LOG_DEBUG);
1411
// MAX_JOIN_SIZE can be very low (ex: 300000) on some limited configurations (ex: https://www.online.net/fr/hosting/online-perso)
1412
// This big SELECT command may exceed the MAX_JOIN_SIZE limit => Therefore we use SQL_BIG_SELECTS=1 to disable the MAX_JOIN_SIZE security
1413
        if ($db->type == 'mysqli') {
1414
            $db->query("SET SQL_BIG_SELECTS=1");
1415
        }
1416
1417
        $result = $db->query($sql);
1418
        if ($result) {
1419
            $num_lines = $db->num_rows($result);
1420
            $i = 0;
1421
1422
            $arrayofselected = is_array($toselect) ? $toselect : array();
1423
1424
            $param = '';
1425
            if (!empty($contextpage) && $contextpage != $_SERVER['PHP_SELF']) {
1426
                $param .= '&contextpage=' . urlencode($contextpage);
1427
            }
1428
            if ($limit > 0 && $limit != $conf->liste_limit) {
1429
                $param .= '&limit=' . ((int) $limit);
1430
            }
1431
            if ($search_login) {
1432
                $param .= '&search_login=' . urlencode($search_login);
1433
            }
1434
            if ($search_lineid) {
1435
                $param .= '&search_lineid=' . urlencode($search_lineid);
1436
            }
1437
            if ($search_date_startday) {
1438
                $param .= '&search_date_startday=' . urlencode((string) ($search_date_startday));
1439
            }
1440
            if ($search_date_startmonth) {
1441
                $param .= '&search_date_startmonth=' . urlencode((string) ($search_date_startmonth));
1442
            }
1443
            if ($search_date_startyear) {
1444
                $param .= '&search_date_startyear=' . urlencode((string) ($search_date_startyear));
1445
            }
1446
            if ($search_date_endday) {
1447
                $param .= '&search_date_endday=' . urlencode((string) ($search_date_endday));
1448
            }
1449
            if ($search_date_endmonth) {
1450
                $param .= '&search_date_endmonth=' . urlencode((string) ($search_date_endmonth));
1451
            }
1452
            if ($search_date_endyear) {
1453
                $param .= '&search_date_endyear=' . urlencode((string) ($search_date_endyear));
1454
            }
1455
            if ($search_expensereport) {
1456
                $param .= '&search_expensereport=' . urlencode($search_expensereport);
1457
            }
1458
            if ($search_label) {
1459
                $param .= '&search_label=' . urlencode($search_label);
1460
            }
1461
            if ($search_desc) {
1462
                $param .= '&search_desc=' . urlencode($search_desc);
1463
            }
1464
            if ($search_amount) {
1465
                $param .= '&search_amount=' . urlencode($search_amount);
1466
            }
1467
            if ($search_vat) {
1468
                $param .= '&search_vat=' . urlencode($search_vat);
1469
            }
1470
1471
            $arrayofmassactions = array(
1472
                'ventil' => img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans("Ventilate")
1473
            );
1474
            $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
1475
1476
            print '<form action="' . $_SERVER['PHP_SELF'] . '" method="post">' . "\n";
1477
            print '<input type="hidden" name="action" value="ventil">';
1478
            if ($optioncss != '') {
1479
                print '<input type="hidden" name="optioncss" value="' . $optioncss . '">';
1480
            }
1481
            print '<input type="hidden" name="token" value="' . newToken() . '">';
1482
            print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
1483
            print '<input type="hidden" name="sortfield" value="' . $sortfield . '">';
1484
            print '<input type="hidden" name="sortorder" value="' . $sortorder . '">';
1485
            print '<input type="hidden" name="page" value="' . $page . '">';
1486
1487
            // @phan-suppress-next-line PhanPluginSuspiciousParamOrder
1488
            print_barre_liste($langs->trans("ExpenseReportLines"), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
1489
1490
            print '<span class="opacitymedium">' . $langs->trans("DescVentilTodoExpenseReport") . '</span></br><br>';
1491
1492
            if (!empty($msg)) {
1493
                print $msg . '<br>';
1494
            }
1495
1496
            $moreforfilter = '';
1497
1498
            print '<div class="div-table-responsive">';
1499
            print '<table class="tagtable liste' . ($moreforfilter ? " listwithfilterbefore" : "") . '">' . "\n";
1500
1501
            // We add search filter
1502
            print '<tr class="liste_titre_filter">';
1503
            print '<td class="liste_titre"><input type="text" name="search_login" class="maxwidth50" value="' . $search_login . '"></td>';
1504
            print '<td class="liste_titre"></td>';
1505
            print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_expensereport" value="' . dol_escape_htmltag($search_expensereport) . '"></td>';
1506
            if (getDolGlobalString('ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE')) {
1507
                print '<td class="liste_titre"></td>';
1508
            }
1509
            print '<td class="liste_titre center">';
1510
            print '<div class="nowrapfordate">';
1511
            print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1512
            print '</div>';
1513
            print '<div class="nowrapfordate">';
1514
            print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1515
            print '</div>';
1516
            print '</td>';
1517
            print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="' . dol_escape_htmltag($search_label) . '"></td>';
1518
            print '<td class="liste_titre"><input type="text" class="flat maxwidthonsmartphone" name="search_desc" value="' . dol_escape_htmltag($search_desc) . '"></td>';
1519
            print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_amount" value="' . dol_escape_htmltag($search_amount) . '"></td>';
1520
            print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_vat" placeholder="%" size="1" value="' . dol_escape_htmltag($search_vat) . '"></td>';
1521
            print '<td class="liste_titre"></td>';
1522
            print '<td class="liste_titre"></td>';
1523
            print '<td class="center liste_titre">';
1524
            $searchpicto = $form->showFilterButtons();
1525
            print $searchpicto;
1526
            print '</td>';
1527
            print '</tr>';
1528
1529
            print '<tr class="liste_titre">';
1530
            print_liste_field_titre("Employee", $_SERVER['PHP_SELF'], "u.login", $param, "", "", $sortfield, $sortorder);
1531
            print_liste_field_titre("LineId", $_SERVER['PHP_SELF'], "erd.rowid", "", $param, '', $sortfield, $sortorder);
1532
            print_liste_field_titre("ExpenseReport", $_SERVER['PHP_SELF'], "er.ref", "", $param, '', $sortfield, $sortorder);
1533
            if (getDolGlobalString('ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE')) {
1534
                print_liste_field_titre("DateValidation", $_SERVER['PHP_SELF'], "er.date_valid", "", $param, '', $sortfield, $sortorder, 'center ');
1535
            }
1536
            print_liste_field_titre("DateOfLine", $_SERVER['PHP_SELF'], "erd.date, erd.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
1537
            print_liste_field_titre("TypeFees", $_SERVER['PHP_SELF'], "f.label", "", $param, '', $sortfield, $sortorder);
1538
            print_liste_field_titre("Description", $_SERVER['PHP_SELF'], "erd.comments", "", $param, '', $sortfield, $sortorder);
1539
            print_liste_field_titre("Amount", $_SERVER['PHP_SELF'], "erd.total_ht", "", $param, '', $sortfield, $sortorder, 'right maxwidth50 ');
1540
            print_liste_field_titre("VATRate", $_SERVER['PHP_SELF'], "erd.tva_tx", "", $param, '', $sortfield, $sortorder, 'right ');
1541
            print_liste_field_titre("DataUsedToSuggestAccount", '', '', '', '', '', '', '', 'nowraponall ');
1542
            print_liste_field_titre("AccountAccountingSuggest", '', '', '', '', '', '', '', '');
1543
            $checkpicto = '';
1544
            if ($massactionbutton) {
1545
                $checkpicto = $form->showCheckAddButtons('checkforselect', 1);
1546
            }
1547
            print_liste_field_titre($checkpicto, '', '', '', '', '', '', '', 'center ');
1548
            print "</tr>\n";
1549
1550
1551
            $expensereport_static = new ExpenseReport($db);
1552
            $userstatic = new User($db);
1553
            $form = new Form($db);
1554
1555
            while ($i < min($num_lines, $limit)) {
1556
                $objp = $db->fetch_object($result);
1557
1558
                $objp->aarowid_suggest = '';
1559
                $objp->aarowid_suggest = $objp->aarowid;
1560
1561
                $expensereport_static->ref = $objp->ref;
1562
                $expensereport_static->id = $objp->erid;
1563
1564
                $userstatic->id = $objp->userid;
1565
                $userstatic->login = $objp->login;
1566
                $userstatic->statut = $objp->statut;
1567
                $userstatic->email = $objp->email;
1568
                $userstatic->gender = $objp->gender;
1569
                $userstatic->firstname = $objp->firstname;
1570
                $userstatic->lastname = $objp->lastname;
1571
                $userstatic->employee = $objp->employee;
1572
                $userstatic->photo = $objp->photo;
1573
1574
                print '<tr class="oddeven">';
1575
1576
                // Login
1577
                print '<td class="nowraponall">';
1578
                print $userstatic->getNomUrl(-1, '', 0, 0, 24, 1, 'login', '', 1);
1579
                print '</td>';
1580
1581
                // Line id
1582
                print '<td>' . $objp->rowid . '</td>';
1583
1584
                // Ref Expense report
1585
                print '<td>' . $expensereport_static->getNomUrl(1) . '</td>';
1586
1587
                // Date validation
1588
                if (getDolGlobalString('ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE')) {
1589
                    print '<td class="center">' . dol_print_date($db->jdate($objp->date_valid), 'day') . '</td>';
1590
                }
1591
1592
                // Date
1593
                print '<td class="center">' . dol_print_date($db->jdate($objp->date), 'day') . '</td>';
1594
1595
                // Fees label
1596
                print '<td>';
1597
                print($langs->trans($objp->type_fees_code) == $objp->type_fees_code ? $objp->type_fees_label : $langs->trans(($objp->type_fees_code)));
1598
                print '</td>';
1599
1600
                // Fees description -- Can be null
1601
                print '<td>';
1602
                $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1));
1603
                $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION', 32);
1604
                print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments);
1605
                print '</td>';
1606
1607
                // Amount without taxes
1608
                print '<td class="right nowraponall amount">';
1609
                print price($objp->price);
1610
                print '</td>';
1611
1612
                // Vat rate
1613
                print '<td class="right">';
1614
                print vatrate($objp->tva_tx_line . ($objp->vat_src_code ? ' (' . $objp->vat_src_code . ')' : ''));
1615
                print '</td>';
1616
1617
                // Current account
1618
                print '<td>';
1619
                print length_accountg(html_entity_decode($objp->code_buy));
1620
                print '</td>';
1621
1622
                // Suggested accounting account
1623
                print '<td>';
1624
                print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil' . $objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
1625
                print '</td>';
1626
1627
                print '<td class="center">';
1628
                print '<input type="checkbox" class="flat checkforselect checkforselect' . $objp->rowid . '" name="toselect[]" value="' . $objp->rowid . "_" . $i . '"' . ($objp->aarowid ? "checked" : "") . '/>';
1629
                print '</td>';
1630
1631
                print "</tr>";
1632
                $i++;
1633
            }
1634
            if ($num_lines == 0) {
1635
                print '<tr><td colspan="13"><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
1636
            }
1637
1638
            print '</table>';
1639
            print "</div>";
1640
1641
            print '</form>';
1642
        } else {
1643
            print $db->error();
1644
        }
1645
        if ($db->type == 'mysqli') {
1646
            $db->query("SET SQL_BIG_SELECTS=0"); // Enable MAX_JOIN_SIZE limitation
1647
        }
1648
1649
// Add code to auto check the box when we select an account
1650
        print '<script type="text/javascript">
1651
jQuery(document).ready(function() {
1652
	jQuery(".codeventil").change(function() {
1653
		var s=$(this).attr("id").replace("codeventil", "")
1654
		console.log(s+" "+$(this).val());
1655
		if ($(this).val() == -1) jQuery(".checkforselect"+s).prop("checked", false);
1656
		else jQuery(".checkforselect"+s).prop("checked", true);
1657
	});
1658
});
1659
</script>';
1660
1661
// End of page
1662
        llxFooter();
1663
        $db->close();
1664
    }
1665
}
1666