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

AccountingJournalController::sellsjournal()   F

Complexity

Conditions 123
Paths > 20000

Size

Total Lines 790
Code Lines 515

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 123
eloc 515
nc 11010048
nop 0
dl 0
loc 790
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) 2007-2010  Laurent Destailleur     <[email protected]>
4
 * Copyright (C) 2007-2010  Jean Heimburger         <[email protected]>
5
 * Copyright (C) 2011       Juanjo Menent           <[email protected]>
6
 * Copyright (C) 2012       Regis Houssin           <[email protected]>
7
 * Copyright (C) 2013       Christophe Battarel     <[email protected]>
8
 * Copyright (C) 2013-2023  Alexandre Spangaro      <[email protected]>
9
 * Copyright (C) 2013-2016  Florian Henry           <[email protected]>
10
 * Copyright (C) 2013-2016  Olivier Geffroy         <[email protected]>
11
 * Copyright (C) 2014       Raphaël Doursenaud      <[email protected]>
12
 * Copyright (C) 2018-2021  Frédéric France         <[email protected]>
13
 * Copyright (C) 2018       Eric Seigne             <[email protected]>
14
 * Copyright (C) 2024		MDW						<[email protected]>
15
 * Copyright (C) 2024       Rafael San José         <[email protected]>
16
 *
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 3 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29
 */
30
31
namespace DoliModules\Accounting\Controller;
32
33
global $conf;
34
global $db;
35
global $user;
36
global $hookmanager;
37
global $user;
38
global $menumanager;
39
global $langs;
40
global $mysoc;
41
42
use ChargeSociales;
43
use DoliCore\Base\DolibarrController;
44
use DoliModules\Accounting\Model\AccountingAccount;
45
use DoliModules\Accounting\Model\AccountingJournal;
46
use DoliModules\Adherent\Model\Subscription;
47
use DoliModules\Bank\Model\Account;
48
use DoliModules\Bank\Model\AccountLine;
49
use DoliModules\Bank\Model\PaymentVarious;
50
use DoliModules\Billing\Model\Facture;
51
use DoliModules\Company\Model\Societe;
52
use DoliModules\Donation\Model\PaymentDonation;
53
use DoliModules\ExpenseReport\Model\PaymentExpenseReport;
54
use DoliModules\Supplier\Model\FactureFournisseur;
55
use DoliModules\Supplier\Model\PaiementFourn;
56
use DoliModules\User\Model\User;
57
use Paiement;
58
use PaymentLoan;
59
use PaymentSalary;
60
use Tva;
61
62
// Load Dolibarr environment
63
require BASE_PATH . '/main.inc.php';
64
require_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php';
65
require_once DOL_DOCUMENT_ROOT . '/compta/sociales/class/chargesociales.class.php';
66
require_once DOL_DOCUMENT_ROOT . '/compta/tva/class/tva.class.php';
67
require_once BASE_PATH . '/../Dolibarr/Lib/Accounting.php';
68
require_once BASE_PATH . '/../Dolibarr/Lib/Bank.php';
69
require_once BASE_PATH . '/../Dolibarr/Lib/Company.php';
70
require_once BASE_PATH . '/../Dolibarr/Lib/Date.php';
71
require_once BASE_PATH . '/../Dolibarr/Lib/Report.php';
72
require_once DOL_DOCUMENT_ROOT . '/loan/class/loan.class.php';
73
require_once DOL_DOCUMENT_ROOT . '/loan/class/paymentloan.class.php';
74
require_once DOL_DOCUMENT_ROOT . '/salaries/class/paymentsalary.class.php';
75
76
class AccountingJournalController extends DolibarrController
77
{
78
    public function index(bool $executeActions = true): bool
79
    {
80
        return $this->bankjournal();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->bankjournal() returns the type null which is incompatible with the type-hinted return boolean.
Loading history...
Bug introduced by
Are you sure the usage of $this->bankjournal() targeting DoliModules\Accounting\C...ntroller::bankjournal() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
81
    }
82
83
    /**
84
     *  \file       htdocs/accountancy/journal/bankjournal.php
85
     *  \ingroup    Accountancy (Double entries)
86
     *  \brief      Page with bank journal
87
     */
88
    public function bankjournal()
89
    {
90
        global $conf;
91
        global $db;
92
        global $user;
93
        global $hookmanager;
94
        global $user;
95
        global $menumanager;
96
        global $langs;
97
        global $mysoc;
98
99
// Load translation files required by the page
100
        $langs->loadLangs(array("companies", "other", "compta", "banks", "bills", "donations", "loan", "accountancy", "trips", "salaries", "hrm", "members"));
101
102
// Multi journal
103
        $id_journal = GETPOSTINT('id_journal');
104
105
        $date_startmonth = GETPOSTINT('date_startmonth');
106
        $date_startday = GETPOSTINT('date_startday');
107
        $date_startyear = GETPOSTINT('date_startyear');
108
        $date_endmonth = GETPOSTINT('date_endmonth');
109
        $date_endday = GETPOSTINT('date_endday');
110
        $date_endyear = GETPOSTINT('date_endyear');
111
        $in_bookkeeping = GETPOST('in_bookkeeping', 'aZ09');
112
        if ($in_bookkeeping == '') {
113
            $in_bookkeeping = 'notyet';
114
        }
115
116
        $now = dol_now();
117
118
        $action = GETPOST('action', 'aZ09');
119
120
// Security check
121
        if (!isModEnabled('accounting')) {
122
            accessforbidden();
123
        }
124
        if ($user->socid > 0) {
125
            accessforbidden();
126
        }
127
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
128
            accessforbidden();
129
        }
130
131
132
        /*
133
         * Actions
134
         */
135
136
        $error = 0;
137
138
        $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
139
        $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
140
141
        if (empty($date_startmonth)) {
142
            // Period by default on transfer
143
            $dates = getDefaultDatesForTransfer();
144
            $date_start = $dates['date_start'];
145
            $pastmonthyear = $dates['pastmonthyear'];
146
            $pastmonth = $dates['pastmonth'];
147
        }
148
        if (empty($date_endmonth)) {
149
            // Period by default on transfer
150
            $dates = getDefaultDatesForTransfer();
151
            $date_end = $dates['date_end'];
152
            $pastmonthyear = $dates['pastmonthyear'];
153
            $pastmonth = $dates['pastmonth'];
154
        }
155
156
        if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
157
            $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
158
            $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
159
        }
160
161
        $sql  = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.amount_main_currency, b.label, b.rappro, b.num_releve, b.num_chq, b.fk_type, b.fk_account,";
162
        $sql .= " ba.courant, ba.ref as baref, ba.account_number, ba.fk_accountancy_journal,";
163
        $sql .= " soc.rowid as socid, soc.nom as name, soc.email as email, bu1.type as typeop_company,";
164
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
165
            $sql .= " spe.accountancy_code_customer as code_compta,";
166
            $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
167
        } else {
168
            $sql .= " soc.code_compta,";
169
            $sql .= " soc.code_compta_fournisseur,";
170
        }
171
        $sql .= " u.accountancy_code, u.rowid as userid, u.lastname as lastname, u.firstname as firstname, u.email as useremail, u.statut as userstatus,";
172
        $sql .= " bu2.type as typeop_user,";
173
        $sql .= " bu3.type as typeop_payment, bu4.type as typeop_payment_supplier";
174
        $sql .= " FROM " . MAIN_DB_PREFIX . "bank as b";
175
        $sql .= " JOIN " . MAIN_DB_PREFIX . "bank_account as ba on b.fk_account=ba.rowid";
176
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu1 ON bu1.fk_bank = b.rowid AND bu1.type='company'";
177
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu2 ON bu2.fk_bank = b.rowid AND bu2.type='user'";
178
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu3 ON bu3.fk_bank = b.rowid AND bu3.type='payment'";
179
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url as bu4 ON bu4.fk_bank = b.rowid AND bu4.type='payment_supplier'";
180
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe as soc on bu1.url_id=soc.rowid";
181
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
182
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = soc.rowid AND spe.entity = " . ((int) $conf->entity);
183
        }
184
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "user as u on bu2.url_id=u.rowid";
185
        $sql .= " WHERE ba.fk_accountancy_journal=" . ((int) $id_journal);
186
        $sql .= ' AND b.amount <> 0 AND ba.entity IN (' . getEntity('bank_account', 0) . ')'; // We don't share object for accountancy
187
        if ($date_start && $date_end) {
188
            $sql .= " AND b.dateo >= '" . $db->idate($date_start) . "' AND b.dateo <= '" . $db->idate($date_end) . "'";
189
        }
190
// Define begin binding date
191
        if (getDolGlobalInt('ACCOUNTING_DATE_START_BINDING')) {
192
            $sql .= " AND b.dateo >= '" . $db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING')) . "'";
193
        }
194
// Already in bookkeeping or not
195
        if ($in_bookkeeping == 'already') {
196
            $sql .= " AND (b.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab  WHERE ab.doc_type='bank') )";
197
        }
198
        if ($in_bookkeeping == 'notyet') {
199
            $sql .= " AND (b.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab  WHERE ab.doc_type='bank') )";
200
        }
201
        $sql .= " ORDER BY b.datev";
202
//print $sql;
203
204
        $object = new Account($db);
205
        $paymentstatic = new Paiement($db);
206
        $paymentsupplierstatic = new PaiementFourn($db);
207
        $societestatic = new Societe($db);
0 ignored issues
show
Deprecated Code introduced by
The class DoliModules\Company\Model\Societe has been deprecated: Use Company instead! ( Ignorable by Annotation )

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

207
        $societestatic = /** @scrutinizer ignore-deprecated */ new Societe($db);
Loading history...
208
        $userstatic = new User($db);
209
        $bankaccountstatic = new Account($db);
210
        $chargestatic = new ChargeSociales($db);
211
        $paymentdonstatic = new PaymentDonation($db);
212
        $paymentvatstatic = new Tva($db);
213
        $paymentsalstatic = new PaymentSalary($db);
214
        $paymentexpensereportstatic = new PaymentExpenseReport($db);
215
        $paymentvariousstatic = new PaymentVarious($db);
216
        $paymentloanstatic = new PaymentLoan($db);
217
        $accountLinestatic = new AccountLine($db);
218
        $paymentsubscriptionstatic = new Subscription($db);
219
220
        $tmppayment = new Paiement($db);
221
        $tmpinvoice = new Facture($db);
222
223
        $accountingaccount = new AccountingAccount($db);
224
225
// Get code of finance journal
226
        $accountingjournalstatic = new AccountingJournal($db);
227
        $accountingjournalstatic->fetch($id_journal);
228
        $journal = $accountingjournalstatic->code;
229
        $journal_label = $accountingjournalstatic->label;
230
231
        $tabcompany = array();
232
        $tabuser = array();
233
        $tabpay = array();
234
        $tabbq = array();
235
        $tabtp = array();
236
        $tabtype = array();
237
        $tabmoreinfo = array();
238
239
        '
240
@phan-var-force array<array{id:mixed,name:mixed,code_compta:string,email:string}> $tabcompany
241
@phan-var-force array<array{id:int,name:string,lastname:string,firstname:string,email:string,accountancy_code:string,status:int> $tabuser
242
@phan-var-force array<int,array{date:string,type_payment:string,ref:string,fk_bank:int,ban_account_ref:string,fk_bank_account:int,lib:string,type:string}> $tabpay
243
@phan-var-force array<array{lib:string,date?:int|string,type_payment?:string,ref?:string,fk_bank?:int,ban_account_ref?:string,fk_bank_account?:int,type?:string,bank_account_ref?:string,paymentid?:int,paymentsupplierid?:int,soclib?:string,paymentscid?:int,paymentdonationid?:int,paymentsubscriptionid?:int,paymentvatid?:int,paymentsalid?:int,paymentexpensereport?:int,paymentvariousid?:int,account_various?:string,paymentloanid?:int}> $tabtp
244
';
245
246
//print $sql;
247
        dol_syslog("accountancy/journal/bankjournal.php", LOG_DEBUG);
248
        $result = $db->query($sql);
249
        if ($result) {
250
            $num = $db->num_rows($result);
251
            //print $sql;
252
253
            // Variables
254
            $account_supplier = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER', 'NotDefined'); // NotDefined is a reserved word
255
            $account_customer = getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER', 'NotDefined'); // NotDefined is a reserved word
256
            $account_employee = getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT', 'NotDefined'); // NotDefined is a reserved word
257
            $account_pay_vat = getDolGlobalString('ACCOUNTING_VAT_PAY_ACCOUNT', 'NotDefined'); // NotDefined is a reserved word
258
            $account_pay_donation = getDolGlobalString('DONATION_ACCOUNTINGACCOUNT', 'NotDefined'); // NotDefined is a reserved word
259
            $account_pay_subscription = getDolGlobalString('ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT', 'NotDefined'); // NotDefined is a reserved word
260
            $account_transfer = getDolGlobalString('ACCOUNTING_ACCOUNT_TRANSFER_CASH', 'NotDefined'); // NotDefined is a reserved word
261
262
            // Loop on each line into llx_bank table. For each line, we should get:
263
            // one line tabpay = line into bank
264
            // one line for bank record = tabbq
265
            // one line for thirdparty record = tabtp
266
            $i = 0;
267
            while ($i < $num) {
268
                $obj = $db->fetch_object($result);
269
270
                $lineisapurchase = -1;
271
                $lineisasale = -1;
272
                // Old method to detect if it's a sale or purchase
273
                if ($obj->label == '(SupplierInvoicePayment)' || $obj->label == '(SupplierInvoicePaymentBack)') {
274
                    $lineisapurchase = 1;
275
                }
276
                if ($obj->label == '(CustomerInvoicePayment)' || $obj->label == '(CustomerInvoicePaymentBack)') {
277
                    $lineisasale = 1;
278
                }
279
                // Try a more reliable method to detect if record is a supplier payment or a customer payment
280
                if ($lineisapurchase < 0) {
281
                    if ($obj->typeop_payment_supplier == 'payment_supplier') {
282
                        $lineisapurchase = 1;
283
                    }
284
                }
285
                if ($lineisasale < 0) {
286
                    if ($obj->typeop_payment == 'payment') {
287
                        $lineisasale = 1;
288
                    }
289
                }
290
                //var_dump($obj->type_payment); //var_dump($obj->type_payment_supplier);
291
                //var_dump($lineisapurchase); //var_dump($lineisasale);
292
293
                // Set accountancy code for bank
294
                $compta_bank = $obj->account_number;
295
296
                // Set accountancy code for thirdparty (example: '411CU...' or '411' if no subledger account defined on customer)
297
                $compta_soc = 'NotDefined';
298
                if ($lineisapurchase > 0) {
299
                    $compta_soc = (($obj->code_compta_fournisseur != "") ? $obj->code_compta_fournisseur : $account_supplier);
300
                }
301
                if ($lineisasale > 0) {
302
                    $compta_soc = (!empty($obj->code_compta) ? $obj->code_compta : $account_customer);
303
                }
304
305
                $tabcompany[$obj->rowid] = array(
306
                    'id' => $obj->socid,
307
                    'name' => $obj->name,
308
                    'code_compta' => $compta_soc,
309
                    'email' => $obj->email
310
                );
311
312
                // Set accountancy code for user
313
                // $obj->accountancy_code is the accountancy_code of table u=user but it is defined only if a link with type 'user' exists)
314
                $compta_user = (!empty($obj->accountancy_code) ? $obj->accountancy_code : '');
315
316
                $tabuser[$obj->rowid] = array(
317
                    'id' => $obj->userid,
318
                    'name' => dolGetFirstLastname($obj->firstname, $obj->lastname),
319
                    'lastname' => $obj->lastname,
320
                    'firstname' => $obj->firstname,
321
                    'email' => $obj->useremail,
322
                    'accountancy_code' => $compta_user,
323
                    'status' => $obj->userstatus
324
                );
325
326
                // Variable bookkeeping ($obj->rowid is Bank Id)
327
                $tabpay[$obj->rowid]["date"] = $db->jdate($obj->do);
328
                $tabpay[$obj->rowid]["type_payment"] = $obj->fk_type; // CHQ, VIR, LIQ, CB, ...
329
                $tabpay[$obj->rowid]["ref"] = $obj->label; // By default. Not unique. May be changed later
330
                $tabpay[$obj->rowid]["fk_bank"] = $obj->rowid;
331
                $tabpay[$obj->rowid]["bank_account_ref"] = $obj->baref;
332
                $tabpay[$obj->rowid]["fk_bank_account"] = $obj->fk_account;
333
                $reg = array();
334
                if (preg_match('/^\((.*)\)$/i', $obj->label, $reg)) {
335
                    $tabpay[$obj->rowid]["lib"] = $langs->trans($reg[1]);
336
                } else {
337
                    $tabpay[$obj->rowid]["lib"] = dol_trunc($obj->label, 60);
338
                }
339
340
                // Load of url links to the line into llx_bank (so load llx_bank_url)
341
                $links = $object->get_url($obj->rowid); // Get an array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> )
342
343
                // By default
344
                $tabpay[$obj->rowid]['type'] = 'unknown'; // Can be SOLD, miscellaneous entry, payment of patient, or any old record with no links in bank_url.
345
                $tabtype[$obj->rowid] = 'unknown';
346
                $tabmoreinfo[$obj->rowid] = array();
347
348
                $amounttouse = $obj->amount;
349
                if (!empty($obj->amount_main_currency)) {
350
                    // If $obj->amount_main_currency is set, it means that $obj->amount is not in same currency, we must use $obj->amount_main_currency
351
                    $amounttouse = $obj->amount_main_currency;
352
                }
353
354
                // get_url may return -1 which is not traversable
355
                if (is_array($links) && count($links) > 0) {
356
                    // Test if entry is for a social contribution, salary or expense report.
357
                    // In such a case, we will ignore the bank url line for user
358
                    $is_sc = false;
359
                    $is_salary = false;
360
                    $is_expensereport = false;
361
                    foreach ($links as $v) {
362
                        if ($v['type'] == 'sc') {
363
                            $is_sc = true;
364
                            break;
365
                        }
366
                        if ($v['type'] == 'payment_salary') {
367
                            $is_salary = true;
368
                            break;
369
                        }
370
                        if ($v['type'] == 'payment_expensereport') {
371
                            $is_expensereport = true;
372
                            break;
373
                        }
374
                    }
375
                    // Now loop on each link of record in bank (code similar to bankentries_list.php)
376
                    foreach ($links as $key => $val) {
377
                        if ($links[$key]['type'] == 'user' && !$is_sc && !$is_salary && !$is_expensereport) {
378
                            continue;
379
                        }
380
                        if (in_array($links[$key]['type'], array('sc', 'payment_sc', 'payment', 'payment_supplier', 'payment_vat', 'payment_expensereport', 'banktransfert', 'payment_donation', 'member', 'payment_loan', 'payment_salary', 'payment_various'))) {
381
                            // So we excluded 'company' and 'user' here. We want only payment lines
382
383
                            // We save tabtype for a future use, to remember what kind of payment it is
384
                            $tabpay[$obj->rowid]['type'] = $links[$key]['type'];
385
                            $tabtype[$obj->rowid] = $links[$key]['type'];
386
                            /* phpcs:disable -- Code does nothing at this moment -> commented
387
                            } elseif (in_array($links[$key]['type'], array('company', 'user'))) {
388
                                if ($tabpay[$obj->rowid]['type'] == 'unknown') {
389
                                    // We can guess here it is a bank record for a thirdparty company or a user.
390
                                    // But we won't be able to record somewhere else than into a waiting account, because there is no other journal to record the contreparty.
391
                                }
392
                            */ // phpcs::enable
393
                        }
394
395
                        // Special case to ask later to add more request to get information for old links without company link.
396
                        if ($links[$key]['type'] == 'withdraw') {
397
                            $tabmoreinfo[$obj->rowid]['withdraw'] = 1;
398
                        }
399
400
                        if ($links[$key]['type'] == 'payment') {
401
                            $paymentstatic->id = $links[$key]['url_id'];
402
                            $paymentstatic->ref = $links[$key]['url_id'];
403
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentstatic->getNomUrl(2, '', ''); // TODO Do not include list of invoice in tooltip, the dol_string_nohtmltag is ko with this
404
                            $tabpay[$obj->rowid]["paymentid"] = $paymentstatic->id;
405
                        } elseif ($links[$key]['type'] == 'payment_supplier') {
406
                            $paymentsupplierstatic->id = $links[$key]['url_id'];
407
                            $paymentsupplierstatic->ref = $links[$key]['url_id'];
408
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsupplierstatic->getNomUrl(2);
409
                            $tabpay[$obj->rowid]["paymentsupplierid"] = $paymentsupplierstatic->id;
410
                        } elseif ($links[$key]['type'] == 'company') {
411
                            $societestatic->id = $links[$key]['url_id'];
412
                            $societestatic->name = $links[$key]['label'];
413
                            $societestatic->email = $tabcompany[$obj->rowid]['email'];
414
                            $tabpay[$obj->rowid]["soclib"] = $societestatic->getNomUrl(1, '', 30);
415
                            if ($compta_soc) {
416
                                if (empty($tabtp[$obj->rowid][$compta_soc])) {
417
                                    $tabtp[$obj->rowid][$compta_soc] = $amounttouse;
418
                                } else {
419
                                    $tabtp[$obj->rowid][$compta_soc] += $amounttouse;
420
                                }
421
                            }
422
                        } elseif ($links[$key]['type'] == 'user') {
423
                            $userstatic->id = $links[$key]['url_id'];
424
                            $userstatic->name = $links[$key]['label'];
425
                            $userstatic->email = $tabuser[$obj->rowid]['email'];
426
                            $userstatic->firstname = $tabuser[$obj->rowid]['firstname'];
427
                            $userstatic->lastname = $tabuser[$obj->rowid]['lastname'];
428
                            $userstatic->statut = $tabuser[$obj->rowid]['status'];
429
                            $userstatic->status = $tabuser[$obj->rowid]['status'];
430
                            $userstatic->accountancy_code = $tabuser[$obj->rowid]['accountancy_code'];
431
                            if ($userstatic->id > 0) {
432
                                $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0);
433
                            } else {
434
                                $tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen, but happens with old data when id of user was not saved on expense report payment.
435
                            }
436
                            if ($compta_user) {
437
                                $tabtp[$obj->rowid][$compta_user] += $amounttouse;
438
                            }
439
                        } elseif ($links[$key]['type'] == 'sc') {
440
                            $chargestatic->id = $links[$key]['url_id'];
441
                            $chargestatic->ref = $links[$key]['url_id'];
442
443
                            $tabpay[$obj->rowid]["lib"] .= ' '.$chargestatic->getNomUrl(2);
444
                            $reg = array();
445
                            if (preg_match('/^\((.*)\)$/i', $links[$key]['label'], $reg)) {
446
                                if ($reg[1] == 'socialcontribution') {
447
                                    $reg[1] = 'SocialContribution';
448
                                }
449
                                $chargestatic->label = $langs->trans($reg[1]);
450
                            } else {
451
                                $chargestatic->label = $links[$key]['label'];
452
                            }
453
                            $chargestatic->ref = $chargestatic->label;
454
                            $tabpay[$obj->rowid]["soclib"] = $chargestatic->getNomUrl(1, 30);
455
                            $tabpay[$obj->rowid]["paymentscid"] = $chargestatic->id;
456
457
                            // Retrieve the accounting code of the social contribution of the payment from link of payment.
458
                            // Note: We have the social contribution id, it can be faster to get accounting code from social contribution id.
459
                            $sqlmid = "SELECT cchgsoc.accountancy_code";
460
                            $sqlmid .= " FROM ".MAIN_DB_PREFIX."c_chargesociales cchgsoc";
461
                            $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."chargesociales as chgsoc ON chgsoc.fk_type = cchgsoc.id";
462
                            $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."paiementcharge as paycharg ON paycharg.fk_charge = chgsoc.rowid";
463
                            $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."bank_url as bkurl ON bkurl.url_id=paycharg.rowid AND bkurl.type = 'payment_sc'";
464
                            $sqlmid .= " WHERE bkurl.fk_bank = ".((int) $obj->rowid);
465
466
                            dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=".$sqlmid, LOG_DEBUG);
467
                            $resultmid = $db->query($sqlmid);
468
                            if ($resultmid) {
469
                                $objmid = $db->fetch_object($resultmid);
470
                                $tabtp[$obj->rowid][$objmid->accountancy_code] += $amounttouse;
471
                            }
472
                        } elseif ($links[$key]['type'] == 'payment_donation') {
473
                            $paymentdonstatic->id = $links[$key]['url_id'];
474
                            $paymentdonstatic->ref = $links[$key]['url_id'];
475
                            $paymentdonstatic->fk_donation = $links[$key]['url_id'];
476
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentdonstatic->getNomUrl(2);
477
                            $tabpay[$obj->rowid]["paymentdonationid"] = $paymentdonstatic->id;
478
                            $tabtp[$obj->rowid][$account_pay_donation] += $amounttouse;
479
                        } elseif ($links[$key]['type'] == 'member') {
480
                            $paymentsubscriptionstatic->id = $links[$key]['url_id'];
481
                            $paymentsubscriptionstatic->ref = $links[$key]['url_id'];
482
                            $paymentsubscriptionstatic->label = $links[$key]['label'];
483
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsubscriptionstatic->getNomUrl(2);
484
                            $tabpay[$obj->rowid]["paymentsubscriptionid"] = $paymentsubscriptionstatic->id;
485
                            $paymentsubscriptionstatic->fetch($paymentsubscriptionstatic->id);
486
                            $tabtp[$obj->rowid][$account_pay_subscription] += $amounttouse;
487
                        } elseif ($links[$key]['type'] == 'payment_vat') {				// Payment VAT
488
                            $paymentvatstatic->id = $links[$key]['url_id'];
489
                            $paymentvatstatic->ref = $links[$key]['url_id'];
490
                            $paymentvatstatic->label = $links[$key]['label'];
491
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentvatstatic->getNomUrl(2);
492
                            $tabpay[$obj->rowid]["paymentvatid"] = $paymentvatstatic->id;
493
                            $tabtp[$obj->rowid][$account_pay_vat] += $amounttouse;
494
                        } elseif ($links[$key]['type'] == 'payment_salary') {
495
                            $paymentsalstatic->id = $links[$key]['url_id'];
496
                            $paymentsalstatic->ref = $links[$key]['url_id'];
497
                            $paymentsalstatic->label = $links[$key]['label'];
498
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsalstatic->getNomUrl(2);
499
                            $tabpay[$obj->rowid]["paymentsalid"] = $paymentsalstatic->id;
500
501
                            // This part of code is no more required. it is here to solve case where a link were missing (with v14.0.0) and keep writing in accountancy complete.
502
                            // Note: A better way to fix this is to delete payment of salary and recreate it, or to fix the bookkeeping table manually after.
503
                            if (getDolGlobalString('ACCOUNTANCY_AUTOFIX_MISSING_LINK_TO_USER_ON_SALARY_BANK_PAYMENT')) {
504
                                $tmpsalary = new Salary($db);
0 ignored issues
show
Bug introduced by
The type DoliModules\Accounting\Controller\Salary was not found. Did you mean Salary? If so, make sure to prefix the type with \.
Loading history...
505
                                $tmpsalary->fetch($paymentsalstatic->id);
506
                                $tmpsalary->fetch_user($tmpsalary->fk_user);
507
508
                                $userstatic->id = $tmpsalary->user->id;
509
                                $userstatic->name = $tmpsalary->user->name;
510
                                $userstatic->email = $tmpsalary->user->email;
511
                                $userstatic->firstname = $tmpsalary->user->firstname;
512
                                $userstatic->lastname = $tmpsalary->user->lastname;
513
                                $userstatic->statut = $tmpsalary->user->status;
514
                                $userstatic->accountancy_code = $tmpsalary->user->accountancy_code;
515
516
                                if ($userstatic->id > 0) {
517
                                    $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0);
518
                                } else {
519
                                    $tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen
520
                                }
521
522
                                if (empty($obj->typeop_user)) {	// Add test to avoid to add amount twice if a link already exists also on user.
523
                                    $compta_user = $userstatic->accountancy_code;
524
                                    if ($compta_user) {
525
                                        $tabtp[$obj->rowid][$compta_user] += $amounttouse;
526
                                        $tabuser[$obj->rowid] = array(
527
                                            'id' => $userstatic->id,
528
                                            'name' => dolGetFirstLastname($userstatic->firstname, $userstatic->lastname),
529
                                            'lastname' => $userstatic->lastname,
530
                                            'firstname' => $userstatic->firstname,
531
                                            'email' => $userstatic->email,
532
                                            'accountancy_code' => $compta_user,
533
                                            'status' => $userstatic->status
534
                                        );
535
                                    }
536
                                }
537
                            }
538
                        } elseif ($links[$key]['type'] == 'payment_expensereport') {
539
                            $paymentexpensereportstatic->id = $links[$key]['url_id'];
540
                            $tabpay[$obj->rowid]["lib"] .= $paymentexpensereportstatic->getNomUrl(2);
541
                            $tabpay[$obj->rowid]["paymentexpensereport"] = $paymentexpensereportstatic->id;
542
                        } elseif ($links[$key]['type'] == 'payment_various') {
543
                            $paymentvariousstatic->id = $links[$key]['url_id'];
544
                            $paymentvariousstatic->ref = $links[$key]['url_id'];
545
                            $paymentvariousstatic->label = $links[$key]['label'];
546
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentvariousstatic->getNomUrl(2);
547
                            $tabpay[$obj->rowid]["paymentvariousid"] = $paymentvariousstatic->id;
548
                            $paymentvariousstatic->fetch($paymentvariousstatic->id);
549
                            $account_various = (!empty($paymentvariousstatic->accountancy_code) ? $paymentvariousstatic->accountancy_code : 'NotDefined'); // NotDefined is a reserved word
550
                            $account_subledger = (!empty($paymentvariousstatic->subledger_account) ? $paymentvariousstatic->subledger_account : ''); // NotDefined is a reserved word
551
                            $tabpay[$obj->rowid]["account_various"] = $account_various;
552
                            $tabtp[$obj->rowid][$account_subledger] += $amounttouse;
553
                        } elseif ($links[$key]['type'] == 'payment_loan') {
554
                            $paymentloanstatic->id = $links[$key]['url_id'];
555
                            $paymentloanstatic->ref = $links[$key]['url_id'];
556
                            $paymentloanstatic->fk_loan = $links[$key]['url_id'];
557
                            $tabpay[$obj->rowid]["lib"] .= ' '.$paymentloanstatic->getNomUrl(2);
558
                            $tabpay[$obj->rowid]["paymentloanid"] = $paymentloanstatic->id;
559
                            //$tabtp[$obj->rowid][$account_pay_loan] += $amounttouse;
560
                            $sqlmid = 'SELECT pl.amount_capital, pl.amount_insurance, pl.amount_interest, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest';
561
                            $sqlmid .= ' FROM '.MAIN_DB_PREFIX.'payment_loan as pl, '.MAIN_DB_PREFIX.'loan as l';
562
                            $sqlmid .= ' WHERE l.rowid = pl.fk_loan AND pl.fk_bank = '.((int) $obj->rowid);
563
564
                            dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=".$sqlmid, LOG_DEBUG);
565
                            $resultmid = $db->query($sqlmid);
566
                            if ($resultmid) {
567
                                $objmid = $db->fetch_object($resultmid);
568
                                $tabtp[$obj->rowid][$objmid->accountancy_account_capital] -= $objmid->amount_capital;
569
                                $tabtp[$obj->rowid][$objmid->accountancy_account_insurance] -= $objmid->amount_insurance;
570
                                $tabtp[$obj->rowid][$objmid->accountancy_account_interest] -= $objmid->amount_interest;
571
                            }
572
                        } elseif ($links[$key]['type'] == 'banktransfert') {
573
                            $accountLinestatic->fetch($links[$key]['url_id']);
574
                            $tabpay[$obj->rowid]["lib"] .= ' '.$langs->trans("BankTransfer").'- '.$accountLinestatic ->getNomUrl(1);
575
                            $tabtp[$obj->rowid][$account_transfer] += $amounttouse;
576
                            $bankaccountstatic->fetch($tabpay[$obj->rowid]['fk_bank_account']);
577
                            $tabpay[$obj->rowid]["soclib"] = $bankaccountstatic->getNomUrl(2);
578
                        }
579
                    }
580
                }
581
582
                if (empty($tabbq[$obj->rowid][$compta_bank])) {
583
                    $tabbq[$obj->rowid][$compta_bank] = $amounttouse;
584
                } else {
585
                    $tabbq[$obj->rowid][$compta_bank] += $amounttouse;
586
                }
587
588
                // If no links were found to know the amount on thirdparty, we try to guess it.
589
                // This may happens on bank entries without the links lines to 'company'.
590
                if (empty($tabtp[$obj->rowid]) && !empty($tabmoreinfo[$obj->rowid]['withdraw'])) {	// If we don't find 'company' link because it is an old 'withdraw' record
591
                    foreach ($links as $key => $val) {
592
                        if ($links[$key]['type'] == 'payment') {
593
                            // Get thirdparty
594
                            $tmppayment->fetch($links[$key]['url_id']);
595
                            $arrayofamounts = $tmppayment->getAmountsArray();
596
                            if (is_array($arrayofamounts)) {
597
                                foreach ($arrayofamounts as $invoiceid => $amount) {
598
                                    $tmpinvoice->fetch($invoiceid);
599
                                    $tmpinvoice->fetch_thirdparty();
600
                                    if ($tmpinvoice->thirdparty->code_compta_client) {
601
                                        $tabtp[$obj->rowid][$tmpinvoice->thirdparty->code_compta_client] += $amount;
602
                                    }
603
                                }
604
                            }
605
                        }
606
                    }
607
                }
608
609
                // If no links were found to know the amount on thirdparty/user, we init it to account 'NotDefined'.
610
                if (empty($tabtp[$obj->rowid])) {
611
                    $tabtp[$obj->rowid]['NotDefined'] = $tabbq[$obj->rowid][$compta_bank];
612
                }
613
614
                // Check account number is ok
615
                /*if ($action == 'writebookkeeping')		// Make test now in such a case
616
                {
617
                    reset($tabbq[$obj->rowid]);
618
                    $first_key_tabbq = key($tabbq[$obj->rowid]);
619
                    if (empty($first_key_tabbq))
620
                    {
621
                        $error++;
622
                        setEventMessages($langs->trans('ErrorAccountancyCodeOnBankAccountNotDefined', $obj->baref), null, 'errors');
623
                    }
624
                    reset($tabtp[$obj->rowid]);
625
                    $first_key_tabtp = key($tabtp[$obj->rowid]);
626
                    if (empty($first_key_tabtp))
627
                    {
628
                        $error++;
629
                        setEventMessages($langs->trans('ErrorAccountancyCodeOnThirdPartyNotDefined'), null, 'errors');
630
                    }
631
                }*/
632
633
                // if($obj->socid)$tabtp[$obj->rowid][$compta_soc] += $amounttouse;
634
635
                $i++;
636
            }
637
        } else {
638
            dol_print_error($db);
639
        }
640
641
642
//var_dump($tabpay);
643
//var_dump($tabcompany);
644
//var_dump($tabbq);
645
//var_dump($tabtp);
646
//var_dump($tabtype);
647
648
// Write bookkeeping
649
        if (!$error && $action == 'writebookkeeping') {
650
            $now = dol_now();
651
652
            $accountingaccountcustomer = new AccountingAccount($db);
653
            $accountingaccountcustomer->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER'), true);
654
655
            $accountingaccountsupplier = new AccountingAccount($db);
656
            $accountingaccountsupplier->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), true);
657
658
            $accountingaccountpayment = new AccountingAccount($db);
659
            $accountingaccountpayment->fetch(null, getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT'), true);
660
661
            $accountingaccountsuspense = new AccountingAccount($db);
662
            $accountingaccountsuspense->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE'), true);
663
664
            $error = 0;
665
            foreach ($tabpay as $key => $val) {		// $key is rowid into llx_bank
666
                $date = dol_print_date($val["date"], 'day');
667
668
                $ref = getSourceDocRef($val, $tabtype[$key]);
669
670
                $errorforline = 0;
671
672
                $totalcredit = 0;
673
                $totaldebit = 0;
674
675
                $db->begin();
676
677
                // Introduce a protection. Total of tabtp must be total of tabbq
678
                //var_dump($tabpay);
679
                //var_dump($tabtp);
680
                //var_dump($tabbq);exit;
681
682
                // Bank
683
                if (!$errorforline && is_array($tabbq[$key])) {
684
                    // Line into bank account
685
                    foreach ($tabbq[$key] as $k => $mt) {
686
                        if ($mt) {
687
                            $accountingaccount->fetch(null, $k, true);	// $k is accounting bank account. TODO We should use a cache here to avoid this fetch
688
                            $account_label = $accountingaccount->label;
689
690
                            $reflabel = '';
691
                            if (!empty($val['lib'])) {
692
                                $reflabel .= dol_string_nohtmltag($val['lib'])." - ";
693
                            }
694
                            $reflabel .= $langs->trans("Bank").' '.dol_string_nohtmltag($val['bank_account_ref']);
695
                            if (!empty($val['soclib'])) {
696
                                $reflabel .= " - ".dol_string_nohtmltag($val['soclib']);
697
                            }
698
699
                            $bookkeeping = new BookKeeping($db);
700
                            $bookkeeping->doc_date = $val["date"];
701
                            $bookkeeping->doc_ref = $ref;
702
                            $bookkeeping->doc_type = 'bank';
703
                            $bookkeeping->fk_doc = $key;
704
                            $bookkeeping->fk_docdet = $val["fk_bank"];
705
706
                            $bookkeeping->numero_compte = $k;
707
                            $bookkeeping->label_compte = $account_label;
708
709
                            $bookkeeping->label_operation = $reflabel;
710
                            $bookkeeping->montant = $mt;
711
                            $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
712
                            $bookkeeping->debit = ($mt >= 0 ? $mt : 0);
713
                            $bookkeeping->credit = ($mt < 0 ? -$mt : 0);
714
                            $bookkeeping->code_journal = $journal;
715
                            $bookkeeping->journal_label = $langs->transnoentities($journal_label);
716
                            $bookkeeping->fk_user_author = $user->id;
717
                            $bookkeeping->date_creation = $now;
718
719
                            // No subledger_account value for the bank line but add a specific label_operation
720
                            $bookkeeping->subledger_account = '';
721
                            $bookkeeping->label_operation = $reflabel;
722
                            $bookkeeping->entity = $conf->entity;
723
724
                            $totaldebit += $bookkeeping->debit;
725
                            $totalcredit += $bookkeeping->credit;
726
727
                            $result = $bookkeeping->create($user);
728
                            if ($result < 0) {
729
                                if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {	// Already exists
730
                                    $error++;
731
                                    $errorforline++;
732
                                    setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
733
                                } else {
734
                                    $error++;
735
                                    $errorforline++;
736
                                    setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
737
                                }
738
                            }
739
                        }
740
                    }
741
                }
742
743
                // Third party
744
                if (!$errorforline) {
745
                    if (is_array($tabtp[$key])) {
746
                        // Line into thirdparty account
747
                        foreach ($tabtp[$key] as $k => $mt) {
748
                            if ($mt) {
749
                                $lettering = false;
750
751
                                $reflabel = '';
752
                                if (!empty($val['lib'])) {
753
                                    $reflabel .= dol_string_nohtmltag($val['lib']).($val['soclib'] ? " - " : "");
754
                                }
755
                                if ($tabtype[$key] == 'banktransfert') {
756
                                    $reflabel .= dol_string_nohtmltag($langs->transnoentitiesnoconv('TransitionalAccount').' '.$account_transfer);
757
                                } else {
758
                                    $reflabel .= dol_string_nohtmltag($val['soclib']);
759
                                }
760
761
                                $bookkeeping = new BookKeeping($db);
762
                                $bookkeeping->doc_date = $val["date"];
763
                                $bookkeeping->doc_ref = $ref;
764
                                $bookkeeping->doc_type = 'bank';
765
                                $bookkeeping->fk_doc = $key;
766
                                $bookkeeping->fk_docdet = $val["fk_bank"];
767
768
                                $bookkeeping->label_operation = $reflabel;
769
                                $bookkeeping->montant = $mt;
770
                                $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
771
                                $bookkeeping->debit = ($mt < 0 ? -$mt : 0);
772
                                $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
773
                                $bookkeeping->code_journal = $journal;
774
                                $bookkeeping->journal_label = $langs->transnoentities($journal_label);
775
                                $bookkeeping->fk_user_author = $user->id;
776
                                $bookkeeping->date_creation = $now;
777
778
                                if ($tabtype[$key] == 'payment') {	// If payment is payment of customer invoice, we get ref of invoice
779
                                    $lettering = true;
780
                                    $bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
781
                                    $bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
782
                                    $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER');
783
                                    $bookkeeping->label_compte = $accountingaccountcustomer->label;
784
                                } elseif ($tabtype[$key] == 'payment_supplier') {	// If payment is payment of supplier invoice, we get ref of invoice
785
                                    $lettering = true;
786
                                    $bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
787
                                    $bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
788
                                    $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER');
789
                                    $bookkeeping->label_compte = $accountingaccountsupplier->label;
790
                                } elseif ($tabtype[$key] == 'payment_expensereport') {
791
                                    $bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
792
                                    $bookkeeping->subledger_label = $tabuser[$key]['name'];
793
                                    $bookkeeping->numero_compte = getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT');
794
                                    $bookkeeping->label_compte = $accountingaccountpayment->label;
795
                                } elseif ($tabtype[$key] == 'payment_salary') {
796
                                    $bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
797
                                    $bookkeeping->subledger_label = $tabuser[$key]['name'];
798
                                    $bookkeeping->numero_compte = getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT');
799
                                    $bookkeeping->label_compte = $accountingaccountpayment->label;
800
                                } elseif (in_array($tabtype[$key], array('sc', 'payment_sc'))) {   // If payment is payment of social contribution
801
                                    $bookkeeping->subledger_account = '';
802
                                    $bookkeeping->subledger_label = '';
803
                                    $accountingaccount->fetch(null, $k, true);	// TODO Use a cache
804
                                    $bookkeeping->numero_compte = $k;
805
                                    $bookkeeping->label_compte = $accountingaccount->label;
806
                                } elseif ($tabtype[$key] == 'payment_vat') {
807
                                    $bookkeeping->subledger_account = '';
808
                                    $bookkeeping->subledger_label = '';
809
                                    $accountingaccount->fetch(null, $k, true);		// TODO Use a cache
810
                                    $bookkeeping->numero_compte = $k;
811
                                    $bookkeeping->label_compte = $accountingaccount->label;
812
                                } elseif ($tabtype[$key] == 'payment_donation') {
813
                                    $bookkeeping->subledger_account = '';
814
                                    $bookkeeping->subledger_label = '';
815
                                    $accountingaccount->fetch(null, $k, true);		// TODO Use a cache
816
                                    $bookkeeping->numero_compte = $k;
817
                                    $bookkeeping->label_compte = $accountingaccount->label;
818
                                } elseif ($tabtype[$key] == 'member') {
819
                                    $bookkeeping->subledger_account = '';
820
                                    $bookkeeping->subledger_label = '';
821
                                    $accountingaccount->fetch(null, $k, true);		// TODO Use a cache
822
                                    $bookkeeping->numero_compte = $k;
823
                                    $bookkeeping->label_compte = $accountingaccount->label;
824
                                } elseif ($tabtype[$key] == 'payment_loan') {
825
                                    $bookkeeping->subledger_account = '';
826
                                    $bookkeeping->subledger_label = '';
827
                                    $accountingaccount->fetch(null, $k, true);		// TODO Use a cache
828
                                    $bookkeeping->numero_compte = $k;
829
                                    $bookkeeping->label_compte = $accountingaccount->label;
830
                                } elseif ($tabtype[$key] == 'payment_various') {
831
                                    $bookkeeping->subledger_account = $k;
832
                                    $bookkeeping->subledger_label = $tabcompany[$key]['name'];
833
                                    $accountingaccount->fetch(null, $tabpay[$key]["account_various"], true);	// TODO Use a cache
834
                                    $bookkeeping->numero_compte = $tabpay[$key]["account_various"];
835
                                    $bookkeeping->label_compte = $accountingaccount->label;
836
                                } elseif ($tabtype[$key] == 'banktransfert') {
837
                                    $bookkeeping->subledger_account = '';
838
                                    $bookkeeping->subledger_label = '';
839
                                    $accountingaccount->fetch(null, $k, true);		// TODO Use a cache
840
                                    $bookkeeping->numero_compte = $k;
841
                                    $bookkeeping->label_compte = $accountingaccount->label;
842
                                } else {
843
                                    if ($tabtype[$key] == 'unknown') {	// Unknown transaction, we will use a waiting account for thirdparty.
844
                                        // Temporary account
845
                                        $bookkeeping->subledger_account = '';
846
                                        $bookkeeping->subledger_label = '';
847
                                        $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE');
848
                                        $bookkeeping->label_compte = $accountingaccountsuspense->label;
849
                                    }
850
                                }
851
                                $bookkeeping->label_operation = $reflabel;
852
                                $bookkeeping->entity = $conf->entity;
853
854
                                $totaldebit += $bookkeeping->debit;
855
                                $totalcredit += $bookkeeping->credit;
856
857
                                $result = $bookkeeping->create($user);
858
                                if ($result < 0) {
859
                                    if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {	// Already exists
860
                                        $error++;
861
                                        $errorforline++;
862
                                        setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
863
                                    } else {
864
                                        $error++;
865
                                        $errorforline++;
866
                                        setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
867
                                    }
868
                                } else {
869
                                    if ($lettering && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
870
                                        require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
871
                                        $lettering_static = new Lettering($db);
872
                                        $nb_lettering = $lettering_static->bookkeepingLetteringAll(array($bookkeeping->id));
873
                                    }
874
                                }
875
                            }
876
                        }
877
                    } else {	// If thirdparty unknown, output the waiting account
878
                        foreach ($tabbq[$key] as $k => $mt) {
879
                            if ($mt) {
880
                                $reflabel = '';
881
                                if (!empty($val['lib'])) {
882
                                    $reflabel .= dol_string_nohtmltag($val['lib'])." - ";
883
                                }
884
                                $reflabel .= dol_string_nohtmltag('WaitingAccount');
885
886
                                $bookkeeping = new BookKeeping($db);
887
                                $bookkeeping->doc_date = $val["date"];
888
                                $bookkeeping->doc_ref = $ref;
889
                                $bookkeeping->doc_type = 'bank';
890
                                $bookkeeping->fk_doc = $key;
891
                                $bookkeeping->fk_docdet = $val["fk_bank"];
892
                                $bookkeeping->montant = $mt;
893
                                $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
894
                                $bookkeeping->debit = ($mt < 0 ? -$mt : 0);
895
                                $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
896
                                $bookkeeping->code_journal = $journal;
897
                                $bookkeeping->journal_label = $langs->transnoentities($journal_label);
898
                                $bookkeeping->fk_user_author = $user->id;
899
                                $bookkeeping->date_creation = $now;
900
                                $bookkeeping->label_compte = '';
901
                                $bookkeeping->label_operation = $reflabel;
902
                                $bookkeeping->entity = $conf->entity;
903
904
                                $totaldebit += $bookkeeping->debit;
905
                                $totalcredit += $bookkeeping->credit;
906
907
                                $result = $bookkeeping->create($user);
908
909
                                if ($result < 0) {
910
                                    if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {	// Already exists
911
                                        $error++;
912
                                        $errorforline++;
913
                                        setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
914
                                    } else {
915
                                        $error++;
916
                                        $errorforline++;
917
                                        setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
918
                                    }
919
                                }
920
                            }
921
                        }
922
                    }
923
                }
924
925
                if (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT')) {
926
                    $error++;
927
                    $errorforline++;
928
                    setEventMessages('We tried to insert a non balanced transaction in book for '.$ref.'. Canceled. Surely a bug.', null, 'errors');
929
                }
930
931
                if (!$errorforline) {
932
                    $db->commit();
933
                } else {
934
                    //print 'KO for line '.$key.' '.$error.'<br>';
935
                    $db->rollback();
936
937
                    $MAXNBERRORS = 5;
938
                    if ($error >= $MAXNBERRORS) {
939
                        setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped").' (>'.$MAXNBERRORS.')', null, 'errors');
940
                        break; // Break in the foreach
941
                    }
942
                }
943
            }
944
945
            if (empty($error) && count($tabpay) > 0) {
946
                setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
947
            } elseif (count($tabpay) == $error) {
948
                setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
949
            } else {
950
                setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
951
            }
952
953
            $action = '';
954
955
            // Must reload data, so we make a redirect
956
            if (count($tabpay) != $error) {
957
                $param = 'id_journal='.$id_journal;
958
                $param .= '&date_startday='.$date_startday;
959
                $param .= '&date_startmonth='.$date_startmonth;
960
                $param .= '&date_startyear='.$date_startyear;
961
                $param .= '&date_endday='.$date_endday;
962
                $param .= '&date_endmonth='.$date_endmonth;
963
                $param .= '&date_endyear='.$date_endyear;
964
                $param .= '&in_bookkeeping='.$in_bookkeeping;
965
                header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
966
                exit;
967
            }
968
        }
969
970
971
972
// Export
973
        if ($action == 'exportcsv') {		// ISO and not UTF8 !
974
            $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
975
976
            $filename = 'journal';
977
            $type_export = 'journal';
978
            include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
979
980
            // CSV header line
981
            print '"'.$langs->transnoentitiesnoconv("BankId").'"'.$sep;
982
            print '"'.$langs->transnoentitiesnoconv("Date").'"'.$sep;
983
            print '"'.$langs->transnoentitiesnoconv("PaymentMode").'"'.$sep;
984
            print '"'.$langs->transnoentitiesnoconv("AccountAccounting").'"'.$sep;
985
            print '"'.$langs->transnoentitiesnoconv("LedgerAccount").'"'.$sep;
986
            print '"'.$langs->transnoentitiesnoconv("SubledgerAccount").'"'.$sep;
987
            print '"'.$langs->transnoentitiesnoconv("Label").'"'.$sep;
988
            print '"'.$langs->transnoentitiesnoconv("AccountingDebit").'"'.$sep;
989
            print '"'.$langs->transnoentitiesnoconv("AccountingCredit").'"'.$sep;
990
            print '"'.$langs->transnoentitiesnoconv("Journal").'"'.$sep;
991
            print '"'.$langs->transnoentitiesnoconv("Note").'"'.$sep;
992
            print "\n";
993
994
            foreach ($tabpay as $key => $val) {
995
                $date = dol_print_date($val["date"], 'day');
996
997
                $ref = getSourceDocRef($val, $tabtype[$key]);
998
999
                // Bank
1000
                foreach ($tabbq[$key] as $k => $mt) {
1001
                    if ($mt) {
1002
                        $reflabel = '';
1003
                        if (!empty($val['lib'])) {
1004
                            $reflabel .= dol_string_nohtmltag($val['lib'])." - ";
1005
                        }
1006
                        $reflabel .= $langs->trans("Bank").' '.dol_string_nohtmltag($val['bank_account_ref']);
1007
                        if (!empty($val['soclib'])) {
1008
                            $reflabel .= " - ".dol_string_nohtmltag($val['soclib']);
1009
                        }
1010
1011
                        print '"'.$key.'"'.$sep;
1012
                        print '"'.$date.'"'.$sep;
1013
                        print '"'.$val["type_payment"].'"'.$sep;
1014
                        print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1015
                        print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
1016
                        print "  ".$sep;
1017
                        print '"'.$reflabel.'"'.$sep;
1018
                        print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1019
                        print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1020
                        print '"'.$journal.'"'.$sep;
1021
                        print '"'.dol_string_nohtmltag($ref).'"'.$sep;
1022
                        print "\n";
1023
                    }
1024
                }
1025
1026
                // Third party
1027
                if (is_array($tabtp[$key])) {
1028
                    foreach ($tabtp[$key] as $k => $mt) {
1029
                        if ($mt) {
1030
                            $reflabel = '';
1031
                            if (!empty($val['lib'])) {
1032
                                $reflabel .= dol_string_nohtmltag($val['lib']).($val['soclib'] ? " - " : "");
1033
                            }
1034
                            if ($tabtype[$key] == 'banktransfert') {
1035
                                $reflabel .= dol_string_nohtmltag($langs->transnoentitiesnoconv('TransitionalAccount').' '.$account_transfer);
1036
                            } else {
1037
                                $reflabel .= dol_string_nohtmltag($val['soclib']);
1038
                            }
1039
1040
                            print '"'.$key.'"'.$sep;
1041
                            print '"'.$date.'"'.$sep;
1042
                            print '"'.$val["type_payment"].'"'.$sep;
1043
                            print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1044
                            if ($tabtype[$key] == 'payment_supplier') {
1045
                                print '"'.getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER').'"'.$sep;
1046
                            } elseif ($tabtype[$key] == 'payment') {
1047
                                print '"'.getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER').'"'.$sep;
1048
                            } elseif ($tabtype[$key] == 'payment_expensereport') {
1049
                                print '"'.getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT').'"'.$sep;
1050
                            } elseif ($tabtype[$key] == 'payment_salary') {
1051
                                print '"'.getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT').'"'.$sep;
1052
                            } else {
1053
                                print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1054
                            }
1055
                            print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
1056
                            print '"'.$reflabel.'"'.$sep;
1057
                            print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1058
                            print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1059
                            print '"'.$journal.'"'.$sep;
1060
                            print '"'.dol_string_nohtmltag($ref).'"'.$sep;
1061
                            print "\n";
1062
                        }
1063
                    }
1064
                } else {	// If thirdparty unknown, output the waiting account
1065
                    foreach ($tabbq[$key] as $k => $mt) {
1066
                        if ($mt) {
1067
                            $reflabel = '';
1068
                            if (!empty($val['lib'])) {
1069
                                $reflabel .= dol_string_nohtmltag($val['lib'])." - ";
1070
                            }
1071
                            $reflabel .= dol_string_nohtmltag('WaitingAccount');
1072
1073
                            print '"'.$key.'"'.$sep;
1074
                            print '"'.$date.'"'.$sep;
1075
                            print '"'.$val["type_payment"].'"'.$sep;
1076
                            print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE')).'"'.$sep;
1077
                            print '"'.length_accounta(getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE')).'"'.$sep;
1078
                            print $sep;
1079
                            print '"'.$reflabel.'"'.$sep;
1080
                            print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1081
                            print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1082
                            print '"'.$journal.'"'.$sep;
1083
                            print '"'.dol_string_nohtmltag($ref).'"'.$sep;
1084
                            print "\n";
1085
                        }
1086
                    }
1087
                }
1088
            }
1089
        }
1090
1091
1092
        /*
1093
         * View
1094
         */
1095
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/journal_bankjournal.php');
1096
1097
        $db->close();
1098
1099
        /**
1100
         * Return source for doc_ref of a bank transaction
1101
         *
1102
         * @param 	array 	$val			Array of val
1103
         * @param 	string	$typerecord		Type of record ('payment', 'payment_supplier', 'payment_expensereport', 'payment_vat', ...)
1104
         * @return 	string					A string label to describe a record into llx_bank_url
1105
         */
1106
        function getSourceDocRef($val, $typerecord)
1107
        {
1108
            global $db, $langs;
1109
1110
            // Defined the docref into $ref (We start with $val['ref'] by default and we complete according to other data)
1111
            // WE MUST HAVE SAME REF FOR ALL LINES WE WILL RECORD INTO THE BOOKKEEPING
1112
            $ref = $val['ref'];
1113
            if ($ref == '(SupplierInvoicePayment)' || $ref == '(SupplierInvoicePaymentBack)') {
1114
                $ref = $langs->transnoentitiesnoconv('Supplier');
1115
            }
1116
            if ($ref == '(CustomerInvoicePayment)' || $ref == '(CustomerInvoicePaymentBack)') {
1117
                $ref = $langs->transnoentitiesnoconv('Customer');
1118
            }
1119
            if ($ref == '(SocialContributionPayment)') {
1120
                $ref = $langs->transnoentitiesnoconv('SocialContribution');
1121
            }
1122
            if ($ref == '(DonationPayment)') {
1123
                $ref = $langs->transnoentitiesnoconv('Donation');
1124
            }
1125
            if ($ref == '(SubscriptionPayment)') {
1126
                $ref = $langs->transnoentitiesnoconv('Subscription');
1127
            }
1128
            if ($ref == '(ExpenseReportPayment)') {
1129
                $ref = $langs->transnoentitiesnoconv('Employee');
1130
            }
1131
            if ($ref == '(LoanPayment)') {
1132
                $ref = $langs->transnoentitiesnoconv('Loan');
1133
            }
1134
            if ($ref == '(payment_salary)') {
1135
                $ref = $langs->transnoentitiesnoconv('Employee');
1136
            }
1137
1138
            $sqlmid = '';
1139
            if ($typerecord == 'payment') {
1140
                if (getDolGlobalInt('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
1141
                    $sqlmid = "SELECT payfac.fk_facture as id, ".$db->ifsql('f1.rowid IS NULL', 'f.ref', 'f1.ref')." as ref";
1142
                    $sqlmid .= " FROM ".$db->prefix()."paiement_facture as payfac";
1143
                    $sqlmid .= " LEFT JOIN ".$db->prefix()."facture as f ON f.rowid = payfac.fk_facture";
1144
                    $sqlmid .= " LEFT JOIN ".$db->prefix()."societe_remise_except as sre ON sre.fk_facture_source = payfac.fk_facture";
1145
                    $sqlmid .= " LEFT JOIN ".$db->prefix()."facture as f1 ON f1.rowid = sre.fk_facture";
1146
                    $sqlmid .= " WHERE payfac.fk_paiement=".((int) $val['paymentid']);
1147
                } else {
1148
                    $sqlmid = "SELECT payfac.fk_facture as id, f.ref as ref";
1149
                    $sqlmid .= " FROM ".$db->prefix()."paiement_facture as payfac";
1150
                    $sqlmid .= " INNER JOIN ".$db->prefix()."facture as f ON f.rowid = payfac.fk_facture";
1151
                    $sqlmid .= " WHERE payfac.fk_paiement=".((int) $val['paymentid']);
1152
                }
1153
                $ref = $langs->transnoentitiesnoconv("Invoice");
1154
            } elseif ($typerecord == 'payment_supplier') {
1155
                $sqlmid = 'SELECT payfac.fk_facturefourn as id, f.ref';
1156
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."paiementfourn_facturefourn as payfac, ".MAIN_DB_PREFIX."facture_fourn as f";
1157
                $sqlmid .= " WHERE payfac.fk_facturefourn = f.rowid AND payfac.fk_paiementfourn=".((int) $val["paymentsupplierid"]);
1158
                $ref = $langs->transnoentitiesnoconv("SupplierInvoice");
1159
            } elseif ($typerecord == 'payment_expensereport') {
1160
                $sqlmid = 'SELECT e.rowid as id, e.ref';
1161
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_expensereport as pe, ".MAIN_DB_PREFIX."expensereport as e";
1162
                $sqlmid .= " WHERE pe.rowid=".((int) $val["paymentexpensereport"])." AND pe.fk_expensereport = e.rowid";
1163
                $ref = $langs->transnoentitiesnoconv("ExpenseReport");
1164
            } elseif ($typerecord == 'payment_salary') {
1165
                $sqlmid = 'SELECT s.rowid as ref';
1166
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_salary as s";
1167
                $sqlmid .= " WHERE s.rowid=".((int) $val["paymentsalid"]);
1168
                $ref = $langs->transnoentitiesnoconv("SalaryPayment");
1169
            } elseif ($typerecord == 'sc') {
1170
                $sqlmid = 'SELECT sc.rowid as ref';
1171
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."paiementcharge as sc";
1172
                $sqlmid .= " WHERE sc.rowid=".((int) $val["paymentscid"]);
1173
                $ref = $langs->transnoentitiesnoconv("SocialContribution");
1174
            } elseif ($typerecord == 'payment_vat') {
1175
                $sqlmid = 'SELECT v.rowid as ref';
1176
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."tva as v";
1177
                $sqlmid .= " WHERE v.rowid=".((int) $val["paymentvatid"]);
1178
                $ref = $langs->transnoentitiesnoconv("PaymentVat");
1179
            } elseif ($typerecord == 'payment_donation') {
1180
                $sqlmid = 'SELECT payd.fk_donation as ref';
1181
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_donation as payd";
1182
                $sqlmid .= " WHERE payd.fk_donation=".((int) $val["paymentdonationid"]);
1183
                $ref = $langs->transnoentitiesnoconv("Donation");
1184
            } elseif ($typerecord == 'payment_loan') {
1185
                $sqlmid = 'SELECT l.rowid as ref';
1186
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_loan as l";
1187
                $sqlmid .= " WHERE l.rowid=".((int) $val["paymentloanid"]);
1188
                $ref = $langs->transnoentitiesnoconv("LoanPayment");
1189
            } elseif ($typerecord == 'payment_various') {
1190
                $sqlmid = 'SELECT v.rowid as ref';
1191
                $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_various as v";
1192
                $sqlmid .= " WHERE v.rowid=".((int) $val["paymentvariousid"]);
1193
                $ref = $langs->transnoentitiesnoconv("VariousPayment");
1194
            }
1195
            // Add warning
1196
            if (empty($sqlmid)) {
1197
                dol_syslog("Found a typerecord=".$typerecord." not supported", LOG_WARNING);
1198
            }
1199
1200
            if ($sqlmid) {
1201
                dol_syslog("accountancy/journal/bankjournal.php::sqlmid=".$sqlmid, LOG_DEBUG);
1202
                $resultmid = $db->query($sqlmid);
1203
                if ($resultmid) {
1204
                    while ($objmid = $db->fetch_object($resultmid)) {
1205
                        $ref .= ' '.$objmid->ref;
1206
                    }
1207
                } else {
1208
                    dol_print_error($db);
1209
                }
1210
            }
1211
1212
            $ref = dol_trunc($langs->transnoentitiesnoconv("BankId").' '.$val['fk_bank'].' - '.$ref, 295); // 295 + 3 dots (...) is < than max size of 300
1213
            return $ref;
1214
        }
1215
    }
1216
1217
    /**
1218
     * \file        htdocs/accountancy/journal/expensereportsjournal.php
1219
     * \ingroup     Accountancy (Double entries)
1220
     * \brief       Page with expense reports journal
1221
     */
1222
    public function expensereportjournal()
1223
    {
1224
        global $conf;
1225
        global $db;
1226
        global $user;
1227
        global $hookmanager;
1228
        global $user;
1229
        global $menumanager;
1230
        global $langs;
1231
        global $mysoc;
1232
1233
// Load translation files required by the page
1234
        $langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "trips", "errors"));
1235
1236
        $id_journal = GETPOSTINT('id_journal');
1237
        $action = GETPOST('action', 'aZ09');
1238
1239
        $date_startmonth = GETPOST('date_startmonth');
1240
        $date_startday = GETPOST('date_startday');
1241
        $date_startyear = GETPOST('date_startyear');
1242
        $date_endmonth = GETPOST('date_endmonth');
1243
        $date_endday = GETPOST('date_endday');
1244
        $date_endyear = GETPOST('date_endyear');
1245
        $in_bookkeeping = GETPOST('in_bookkeeping');
1246
        if ($in_bookkeeping == '') {
1247
            $in_bookkeeping = 'notyet';
1248
        }
1249
1250
        $now = dol_now();
1251
1252
        $hookmanager->initHooks(array('expensereportsjournal'));
1253
        $parameters = array();
1254
1255
// Security check
1256
        if (!isModEnabled('accounting')) {
1257
            accessforbidden();
1258
        }
1259
        if ($user->socid > 0) {
1260
            accessforbidden();
1261
        }
1262
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
1263
            accessforbidden();
1264
        }
1265
1266
        $error = 0;
1267
        $errorforinvoice = array();
1268
1269
1270
        /*
1271
         * Actions
1272
         */
1273
1274
        $accountingaccount = new AccountingAccount($db);
1275
1276
// Get information of journal
1277
        $accountingjournalstatic = new AccountingJournal($db);
1278
        $accountingjournalstatic->fetch($id_journal);
1279
        $journal = $accountingjournalstatic->code;
1280
        $journal_label = $accountingjournalstatic->label;
1281
1282
        $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
1283
        $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
1284
1285
        if (empty($date_startmonth)) {
1286
            // Period by default on transfer
1287
            $dates = getDefaultDatesForTransfer();
1288
            $date_start = $dates['date_start'];
1289
            $pastmonthyear = $dates['pastmonthyear'];
1290
            $pastmonth = $dates['pastmonth'];
1291
        }
1292
        if (empty($date_endmonth)) {
1293
            // Period by default on transfer
1294
            $dates = getDefaultDatesForTransfer();
1295
            $date_end = $dates['date_end'];
1296
            $pastmonthyear = $dates['pastmonthyear'];
1297
            $pastmonth = $dates['pastmonth'];
1298
        }
1299
1300
        if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
1301
            $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
1302
            $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
1303
        }
1304
1305
        $sql = "SELECT er.rowid, er.ref, er.date_debut as de,";
1306
        $sql .= " erd.rowid as erdid, erd.comments, erd.total_ht, erd.total_tva, erd.total_localtax1, erd.total_localtax2, erd.tva_tx, erd.total_ttc, erd.fk_code_ventilation, erd.vat_src_code, ";
1307
        $sql .= " u.rowid as uid, u.firstname, u.lastname, u.accountancy_code as user_accountancy_account,";
1308
        $sql .= " f.accountancy_code, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte";
1309
        $parameters = array();
1310
        $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
1311
        $sql .= $hookmanager->resPrint;
1312
        $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
1313
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees";
1314
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = erd.fk_code_ventilation";
1315
        $sql .= " JOIN " . MAIN_DB_PREFIX . "expensereport as er ON er.rowid = erd.fk_expensereport";
1316
        $sql .= " JOIN " . MAIN_DB_PREFIX . "user as u ON u.rowid = er.fk_user_author";
1317
        $parameters = array();
1318
        $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
1319
        $sql .= $hookmanager->resPrint;
1320
        $sql .= " WHERE er.fk_statut > 0";
1321
        $sql .= " AND erd.fk_code_ventilation > 0";
1322
        $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy
1323
        if ($date_start && $date_end) {
1324
            $sql .= " AND er.date_debut >= '" . $db->idate($date_start) . "' AND er.date_debut <= '" . $db->idate($date_end) . "'";
1325
        }
1326
// Define begin binding date
1327
        if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
1328
            $sql .= " AND er.date_debut >= '" . $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) . "'";
1329
        }
1330
// Already in bookkeeping or not
1331
        if ($in_bookkeeping == 'already') {
1332
            $sql .= " AND er.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab  WHERE ab.doc_type='expense_report')";
1333
        }
1334
        if ($in_bookkeeping == 'notyet') {
1335
            $sql .= " AND er.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab  WHERE ab.doc_type='expense_report')";
1336
        }
1337
        $parameters = array();
1338
        $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
1339
        $sql .= $hookmanager->resPrint;
1340
        $sql .= " ORDER BY er.date_debut";
1341
1342
        dol_syslog('accountancy/journal/expensereportsjournal.php', LOG_DEBUG);
1343
        $result = $db->query($sql);
1344
        if ($result) {
1345
            $taber = array();
1346
            $tabht = array();
1347
            $tabtva = array();
1348
            $def_tva = array();
1349
            $tabttc = array();
1350
            $tablocaltax1 = array();
1351
            $tablocaltax2 = array();
1352
            $tabuser = array();
1353
1354
            $num = $db->num_rows($result);
1355
1356
            // Variables
1357
            $account_salary = getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT', 'NotDefined');
1358
            $account_vat = getDolGlobalString('ACCOUNTING_VAT_BUY_ACCOUNT', 'NotDefined');
1359
1360
            $i = 0;
1361
            while ($i < $num) {
1362
                $obj = $db->fetch_object($result);
1363
1364
                // Controls
1365
                $compta_user = (!empty($obj->user_accountancy_account)) ? $obj->user_accountancy_account : $account_salary;
1366
                $compta_fees = $obj->compte;
1367
1368
                $vatdata = getTaxesFromId($obj->tva_tx . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : ''), $mysoc, $mysoc, 0);
1369
                $compta_tva = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
1370
                $compta_localtax1 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $cpttva seems to be never defined.
Loading history...
1371
                $compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
1372
1373
                // Define array to display all VAT rates that use this accounting account $compta_tva
1374
                if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
1375
                    $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx) . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : '')] = (vatrate($obj->tva_tx) . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : ''));
1376
                }
1377
1378
                $taber[$obj->rowid]["date"] = $db->jdate($obj->de);
1379
                $taber[$obj->rowid]["ref"] = $obj->ref;
1380
                $taber[$obj->rowid]["comments"] = $obj->comments;
1381
                $taber[$obj->rowid]["fk_expensereportdet"] = $obj->erdid;
1382
1383
                // Avoid warnings
1384
                if (!isset($tabttc[$obj->rowid][$compta_user])) {
1385
                    $tabttc[$obj->rowid][$compta_user] = 0;
1386
                }
1387
                if (!isset($tabht[$obj->rowid][$compta_fees])) {
1388
                    $tabht[$obj->rowid][$compta_fees] = 0;
1389
                }
1390
                if (!isset($tabtva[$obj->rowid][$compta_tva])) {
1391
                    $tabtva[$obj->rowid][$compta_tva] = 0;
1392
                }
1393
                if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
1394
                    $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
1395
                }
1396
                if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
1397
                    $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
1398
                }
1399
1400
                $tabttc[$obj->rowid][$compta_user] += $obj->total_ttc;
1401
                $tabht[$obj->rowid][$compta_fees] += $obj->total_ht;
1402
                $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
1403
                $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
1404
                $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
1405
                $tabuser[$obj->rowid] = array(
1406
                    'id' => $obj->uid,
1407
                    'name' => dolGetFirstLastname($obj->firstname, $obj->lastname),
1408
                    'user_accountancy_code' => $obj->user_accountancy_account
1409
                );
1410
1411
                $i++;
1412
            }
1413
        } else {
1414
            dol_print_error($db);
1415
        }
1416
1417
// Load all unbound lines
1418
        $sql = "SELECT fk_expensereport, COUNT(erd.rowid) as nb";
1419
        $sql .= " FROM " . MAIN_DB_PREFIX . "expensereport_det as erd";
1420
        $sql .= " WHERE erd.fk_code_ventilation <= 0";
1421
        $sql .= " AND erd.total_ttc <> 0";
1422
        $sql .= " AND fk_expensereport IN (" . $db->sanitize(implode(",", array_keys($taber))) . ")";
1423
        $sql .= " GROUP BY fk_expensereport";
1424
        $resql = $db->query($sql);
1425
1426
        $num = $db->num_rows($resql);
1427
        $i = 0;
1428
        while ($i < $num) {
1429
            $obj = $db->fetch_object($resql);
1430
            if ($obj->nb > 0) {
1431
                $errorforinvoice[$obj->fk_expensereport] = 'somelinesarenotbound';
1432
            }
1433
            $i++;
1434
        }
1435
1436
// Bookkeeping Write
1437
        if ($action == 'writebookkeeping' && !$error) {
1438
            $now = dol_now();
1439
            $error = 0;
1440
1441
            $accountingaccountexpense = new AccountingAccount($db);
1442
            $accountingaccountexpense->fetch(null, getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT'), true);
1443
1444
            foreach ($taber as $key => $val) {      // Loop on each expense report
1445
                $errorforline = 0;
1446
1447
                $totalcredit = 0;
1448
                $totaldebit = 0;
1449
1450
                $db->begin();
1451
1452
                // Error if some lines are not binded/ready to be journalized
1453
                if (!empty($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
1454
                    $error++;
1455
                    $errorforline++;
1456
                    setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
1457
                }
1458
1459
                // Thirdparty
1460
                if (!$errorforline) {
1461
                    foreach ($tabttc[$key] as $k => $mt) {
1462
                        if ($mt) {
1463
                            $bookkeeping = new BookKeeping($db);
1464
                            $bookkeeping->doc_date = $val["date"];
1465
                            $bookkeeping->doc_ref = $val["ref"];
1466
                            $bookkeeping->date_creation = $now;
1467
                            $bookkeeping->doc_type = 'expense_report';
1468
                            $bookkeeping->fk_doc = $key;
1469
                            $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
1470
1471
                            $bookkeeping->subledger_account = $tabuser[$key]['user_accountancy_code'];
1472
                            $bookkeeping->subledger_label = $tabuser[$key]['name'];
1473
1474
                            $bookkeeping->numero_compte = getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT');
1475
                            $bookkeeping->label_compte = $accountingaccountexpense->label;
1476
1477
                            $bookkeeping->label_operation = $tabuser[$key]['name'];
1478
                            $bookkeeping->montant = $mt;
1479
                            $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
1480
                            $bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
1481
                            $bookkeeping->credit = ($mt > 0) ? $mt : 0;
1482
                            $bookkeeping->code_journal = $journal;
1483
                            $bookkeeping->journal_label = $langs->transnoentities($journal_label);
1484
                            $bookkeeping->fk_user_author = $user->id;
1485
                            $bookkeeping->entity = $conf->entity;
1486
1487
                            $totaldebit += $bookkeeping->debit;
1488
                            $totalcredit += $bookkeeping->credit;
1489
1490
                            $result = $bookkeeping->create($user);
1491
                            if ($result < 0) {
1492
                                if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
1493
                                    $error++;
1494
                                    $errorforline++;
1495
                                    $errorforinvoice[$key] = 'alreadyjournalized';
1496
                                    //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
1497
                                } else {
1498
                                    $error++;
1499
                                    $errorforline++;
1500
                                    $errorforinvoice[$key] = 'other';
1501
                                    setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
1502
                                }
1503
                            }
1504
                        }
1505
                    }
1506
                }
1507
1508
                // Fees
1509
                if (!$errorforline) {
1510
                    foreach ($tabht[$key] as $k => $mt) {
1511
                        if ($mt) {
1512
                            // get compte id and label
1513
                            if ($accountingaccount->fetch(null, $k, true)) {
1514
                                $bookkeeping = new BookKeeping($db);
1515
                                $bookkeeping->doc_date = $val["date"];
1516
                                $bookkeeping->doc_ref = $val["ref"];
1517
                                $bookkeeping->date_creation = $now;
1518
                                $bookkeeping->doc_type = 'expense_report';
1519
                                $bookkeeping->fk_doc = $key;
1520
                                $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
1521
1522
                                $bookkeeping->subledger_account = '';
1523
                                $bookkeeping->subledger_label = '';
1524
1525
                                $bookkeeping->numero_compte = $k;
1526
                                $bookkeeping->label_compte = $accountingaccount->label;
1527
1528
                                $bookkeeping->label_operation = $accountingaccount->label;
1529
                                $bookkeeping->montant = $mt;
1530
                                $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
1531
                                $bookkeeping->debit = ($mt > 0) ? $mt : 0;
1532
                                $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
1533
                                $bookkeeping->code_journal = $journal;
1534
                                $bookkeeping->journal_label = $langs->transnoentities($journal_label);
1535
                                $bookkeeping->fk_user_author = $user->id;
1536
                                $bookkeeping->entity = $conf->entity;
1537
1538
                                $totaldebit += $bookkeeping->debit;
1539
                                $totalcredit += $bookkeeping->credit;
1540
1541
                                $result = $bookkeeping->create($user);
1542
                                if ($result < 0) {
1543
                                    if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
1544
                                        $error++;
1545
                                        $errorforline++;
1546
                                        $errorforinvoice[$key] = 'alreadyjournalized';
1547
                                        //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
1548
                                    } else {
1549
                                        $error++;
1550
                                        $errorforline++;
1551
                                        $errorforinvoice[$key] = 'other';
1552
                                        setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
1553
                                    }
1554
                                }
1555
                            }
1556
                        }
1557
                    }
1558
                }
1559
1560
                // VAT
1561
                if (!$errorforline) {
1562
                    $listoftax = array(0, 1, 2);
1563
                    foreach ($listoftax as $numtax) {
1564
                        $arrayofvat = $tabtva;
1565
                        if ($numtax == 1) {
1566
                            $arrayofvat = $tablocaltax1;
1567
                        }
1568
                        if ($numtax == 2) {
1569
                            $arrayofvat = $tablocaltax2;
1570
                        }
1571
1572
                        foreach ($arrayofvat[$key] as $k => $mt) {
1573
                            if ($mt) {
1574
                                $accountingaccount->fetch(null, $k, true);  // TODO Use a cache for label
1575
                                $account_label = $accountingaccount->label;
1576
1577
                                // get compte id and label
1578
                                $bookkeeping = new BookKeeping($db);
1579
                                $bookkeeping->doc_date = $val["date"];
1580
                                $bookkeeping->doc_ref = $val["ref"];
1581
                                $bookkeeping->date_creation = $now;
1582
                                $bookkeeping->doc_type = 'expense_report';
1583
                                $bookkeeping->fk_doc = $key;
1584
                                $bookkeeping->fk_docdet = $val["fk_expensereportdet"];
1585
1586
                                $bookkeeping->subledger_account = '';
1587
                                $bookkeeping->subledger_label = '';
1588
1589
                                $bookkeeping->numero_compte = $k;
1590
                                $bookkeeping->label_compte = $account_label;
1591
1592
                                $bookkeeping->label_operation = $langs->trans("VAT") . ' ' . implode(', ', $def_tva[$key][$k]) . ' %';
1593
                                $bookkeeping->montant = $mt;
1594
                                $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
1595
                                $bookkeeping->debit = ($mt > 0) ? $mt : 0;
1596
                                $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
1597
                                $bookkeeping->code_journal = $journal;
1598
                                $bookkeeping->journal_label = $langs->transnoentities($journal_label);
1599
                                $bookkeeping->fk_user_author = $user->id;
1600
                                $bookkeeping->entity = $conf->entity;
1601
1602
                                $totaldebit += $bookkeeping->debit;
1603
                                $totalcredit += $bookkeeping->credit;
1604
1605
                                $result = $bookkeeping->create($user);
1606
                                if ($result < 0) {
1607
                                    if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
1608
                                        $error++;
1609
                                        $errorforline++;
1610
                                        $errorforinvoice[$key] = 'alreadyjournalized';
1611
                                        //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
1612
                                    } else {
1613
                                        $error++;
1614
                                        $errorforline++;
1615
                                        $errorforinvoice[$key] = 'other';
1616
                                        setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
1617
                                    }
1618
                                }
1619
                            }
1620
                        }
1621
                    }
1622
                }
1623
1624
                // Protection against a bug on lines before
1625
                if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
1626
                    $error++;
1627
                    $errorforline++;
1628
                    $errorforinvoice[$key] = 'amountsnotbalanced';
1629
                    setEventMessages('We tried to insert a non balanced transaction in book for ' . $val["ref"] . '. Canceled. Surely a bug.', null, 'errors');
1630
                }
1631
1632
                if (!$errorforline) {
1633
                    $db->commit();
1634
                } else {
1635
                    $db->rollback();
1636
1637
                    if ($error >= 10) {
1638
                        setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
1639
                        break; // Break in the foreach
1640
                    }
1641
                }
1642
            }
1643
1644
            $tabpay = $taber;
1645
1646
            if (empty($error) && count($tabpay) > 0) {
1647
                setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
1648
            } elseif (count($tabpay) == $error) {
1649
                setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
1650
            } else {
1651
                setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
1652
            }
1653
1654
            $action = '';
1655
1656
            // Must reload data, so we make a redirect
1657
            if (count($tabpay) != $error) {
1658
                $param = 'id_journal=' . $id_journal;
1659
                $param .= '&date_startday=' . $date_startday;
1660
                $param .= '&date_startmonth=' . $date_startmonth;
1661
                $param .= '&date_startyear=' . $date_startyear;
1662
                $param .= '&date_endday=' . $date_endday;
1663
                $param .= '&date_endmonth=' . $date_endmonth;
1664
                $param .= '&date_endyear=' . $date_endyear;
1665
                $param .= '&in_bookkeeping=' . $in_bookkeeping;
1666
1667
                header("Location: " . $_SERVER['PHP_SELF'] . ($param ? '?' . $param : ''));
1668
                exit;
1669
            }
1670
        }
1671
1672
1673
        /*
1674
         * View
1675
         */
1676
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/journal_expensereportjournal.php');
1677
1678
        $db->close();
1679
        return true;
1680
    }
1681
1682
    /**
1683
     * \file        htdocs/accountancy/journal/purchasesjournal.php
1684
     * \ingroup     Accountancy (Double entries)
1685
     * \brief       Page with purchases journal
1686
     */
1687
    public function purchasesjournal()
1688
    {
1689
        global $conf;
1690
        global $db;
1691
        global $user;
1692
        global $hookmanager;
1693
        global $user;
1694
        global $menumanager;
1695
        global $langs;
1696
        global $mysoc;
1697
1698
// Load translation files required by the page
1699
        $langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "errors"));
1700
1701
        $id_journal = GETPOSTINT('id_journal');
1702
        $action = GETPOST('action', 'aZ09');
1703
1704
        $date_startmonth = GETPOST('date_startmonth');
1705
        $date_startday = GETPOST('date_startday');
1706
        $date_startyear = GETPOST('date_startyear');
1707
        $date_endmonth = GETPOST('date_endmonth');
1708
        $date_endday = GETPOST('date_endday');
1709
        $date_endyear = GETPOST('date_endyear');
1710
        $in_bookkeeping = GETPOST('in_bookkeeping');
1711
        if ($in_bookkeeping == '') {
1712
            $in_bookkeeping = 'notyet';
1713
        }
1714
1715
        $now = dol_now();
1716
1717
        $hookmanager->initHooks(array('purchasesjournal'));
1718
        $parameters = array();
1719
1720
// Security check
1721
        if (!isModEnabled('accounting')) {
1722
            accessforbidden();
1723
        }
1724
        if ($user->socid > 0) {
1725
            accessforbidden();
1726
        }
1727
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
1728
            accessforbidden();
1729
        }
1730
1731
        $error = 0;
1732
1733
1734
        /*
1735
         * Actions
1736
         */
1737
1738
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks
1739
1740
        $accountingaccount = new AccountingAccount($db);
1741
1742
// Get information of journal
1743
        $accountingjournalstatic = new AccountingJournal($db);
1744
        $accountingjournalstatic->fetch($id_journal);
1745
        $journal = $accountingjournalstatic->code;
1746
        $journal_label = $accountingjournalstatic->label;
1747
1748
        $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
1749
        $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
1750
1751
        if (empty($date_startmonth)) {
1752
            // Period by default on transfer
1753
            $dates = getDefaultDatesForTransfer();
1754
            $date_start = $dates['date_start'];
1755
            $pastmonthyear = $dates['pastmonthyear'];
1756
            $pastmonth = $dates['pastmonth'];
1757
        }
1758
        if (empty($date_endmonth)) {
1759
            // Period by default on transfer
1760
            $dates = getDefaultDatesForTransfer();
1761
            $date_end = $dates['date_end'];
1762
            $pastmonthyear = $dates['pastmonthyear'];
1763
            $pastmonth = $dates['pastmonth'];
1764
        }
1765
1766
        if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
1767
            $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
1768
            $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
1769
        }
1770
1771
        $sql = "SELECT f.rowid, f.ref as ref, f.type, f.datef as df, f.libelle as label, f.ref_supplier, f.date_lim_reglement as dlr, f.close_code, f.vat_reverse_charge,";
1772
        $sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.tva as total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.vat_src_code, fd.info_bits,";
1773
        $sql .= " p.default_vat_code AS product_buy_default_vat_code, p.tva_tx as product_buy_vat, p.localtax1_tx as product_buy_localvat1, p.localtax2_tx as product_buy_localvat2,";
1774
        $sql .= " co.code as country_code, co.label as country_label,";
1775
        $sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur, s.fk_pays,";
1776
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1777
            $sql .= " spe.accountancy_code_customer as code_compta,";
1778
            $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
1779
        } else {
1780
            $sql .= " s.code_compta as code_compta,";
1781
            $sql .= " s.code_compta_fournisseur,";
1782
        }
1783
        if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
1784
            $sql .= " ppe.accountancy_code_buy,";
1785
        } else {
1786
            $sql .= " p.accountancy_code_buy,";
1787
        }
1788
        $sql .= " aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte";
1789
        $parameters = array();
1790
        $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
1791
        $sql .= $hookmanager->resPrint;
1792
        $sql .= " FROM " . MAIN_DB_PREFIX . "facture_fourn_det as fd";
1793
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = fd.fk_product";
1794
        if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
1795
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
1796
        }
1797
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = fd.fk_code_ventilation";
1798
        $sql .= " JOIN " . MAIN_DB_PREFIX . "facture_fourn as f ON f.rowid = fd.fk_facture_fourn";
1799
        $sql .= " JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid = f.fk_soc";
1800
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_country as co ON co.rowid = s.fk_pays ";
1801
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1802
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
1803
        }
1804
        $parameters = array();
1805
        $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
1806
        $sql .= $hookmanager->resPrint;
1807
        $sql .= " WHERE f.fk_statut > 0";
1808
        $sql .= " AND fd.fk_code_ventilation > 0";
1809
        $sql .= " AND f.entity IN (" . getEntity('facture_fourn', 0) . ")"; // We don't share object for accountancy
1810
        if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
1811
            $sql .= " AND f.type IN (" . FactureFournisseur::TYPE_STANDARD . "," . FactureFournisseur::TYPE_REPLACEMENT . "," . FactureFournisseur::TYPE_CREDIT_NOTE . "," . FactureFournisseur::TYPE_SITUATION . ")";
1812
        } else {
1813
            $sql .= " AND f.type IN (" . FactureFournisseur::TYPE_STANDARD . "," . FactureFournisseur::TYPE_REPLACEMENT . "," . FactureFournisseur::TYPE_CREDIT_NOTE . "," . FactureFournisseur::TYPE_DEPOSIT . "," . FactureFournisseur::TYPE_SITUATION . ")";
1814
        }
1815
        if ($date_start && $date_end) {
1816
            $sql .= " AND f.datef >= '" . $db->idate($date_start) . "' AND f.datef <= '" . $db->idate($date_end) . "'";
1817
        }
1818
// Define begin binding date
1819
        if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
1820
            $sql .= " AND f.datef >= '" . $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) . "'";
1821
        }
1822
// Already in bookkeeping or not
1823
        if ($in_bookkeeping == 'already') {
1824
            $sql .= " AND f.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')";
1825
        }
1826
        if ($in_bookkeeping == 'notyet') {
1827
            $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')";
1828
        }
1829
        $parameters = array();
1830
        $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
1831
        $sql .= $hookmanager->resPrint;
1832
        $sql .= " ORDER BY f.datef";
1833
1834
        dol_syslog('accountancy/journal/purchasesjournal.php', LOG_DEBUG);
1835
        $result = $db->query($sql);
1836
        if ($result) {
1837
            $tabfac = array();
1838
            $tabht = array();
1839
            $tabtva = array();
1840
            $def_tva = array();
1841
            $tabttc = array();
1842
            $tablocaltax1 = array();
1843
            $tablocaltax2 = array();
1844
            $tabcompany = array();
1845
            $tabother = array();
1846
            $tabrctva = array();
1847
            $tabrclocaltax1 = array();
1848
            $tabrclocaltax2 = array();
1849
            $vatdata_cache = array();
1850
1851
            $num = $db->num_rows($result);
1852
1853
            // Variables
1854
            $cptfour = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER', 'NotDefined');
1855
            $cpttva = getDolGlobalString('ACCOUNTING_VAT_BUY_ACCOUNT', 'NotDefined');
1856
            $rcctva = getDolGlobalString('ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT', 'NotDefined');
1857
            $rcdtva = getDolGlobalString('ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT', 'NotDefined');
1858
            $country_code_in_EEC = getCountriesInEEC();     // This make a database call but there is a cache done into $conf->cache['country_code_in_EEC']
1859
1860
            $i = 0;
1861
            while ($i < $num) {
1862
                $obj = $db->fetch_object($result);
1863
1864
                // Controls
1865
                $compta_soc = ($obj->code_compta_fournisseur != "") ? $obj->code_compta_fournisseur : $cptfour;
1866
1867
                $compta_prod = $obj->compte;
1868
                if (empty($compta_prod)) {
1869
                    if ($obj->product_type == 0) {
1870
                        $compta_prod = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', 'NotDefined');
1871
                    } else {
1872
                        $compta_prod = getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT', 'NotDefined');
1873
                    }
1874
                }
1875
1876
                $tax_id = $obj->tva_tx . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : '');
1877
                if (array_key_exists($tax_id, $vatdata_cache)) {
1878
                    $vatdata = $vatdata_cache[$tax_id];
1879
                } else {
1880
                    $vatdata = getTaxesFromId($tax_id, $mysoc, $mysoc, 0);
1881
                    $vatdata_cache[$tax_id] = $vatdata;
1882
                }
1883
                $compta_tva = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
1884
                $compta_localtax1 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
1885
                $compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
1886
                $compta_counterpart_tva_npr = getDolGlobalString('ACCOUNTING_COUNTERPART_VAT_NPR', 'NotDefined');
1887
1888
                // Define array to display all VAT rates that use this accounting account $compta_tva
1889
                if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
1890
                    $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx) . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : '')] = (vatrate($obj->tva_tx) . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : ''));
1891
                }
1892
1893
                //$line = new SupplierInvoiceLine($db);
1894
                //$line->fetch($obj->fdid);
1895
1896
                $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df);
1897
                $tabfac[$obj->rowid]["datereg"] = $db->jdate($obj->dlr);
1898
                $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier . ' (' . $obj->ref . ')';
1899
                $tabfac[$obj->rowid]["refsologest"] = $obj->ref;
1900
                $tabfac[$obj->rowid]["refsuppliersologest"] = $obj->ref_supplier;
1901
                $tabfac[$obj->rowid]["type"] = $obj->type;
1902
                $tabfac[$obj->rowid]["description"] = $obj->description;
1903
                $tabfac[$obj->rowid]["close_code"] = $obj->close_code; // close_code = 'replaced' for replacement invoices (not used in most european countries)
1904
                //$tabfac[$obj->rowid]["fk_facturefourndet"] = $obj->fdid;
1905
1906
                // Avoid warnings
1907
                if (!isset($tabttc[$obj->rowid][$compta_soc])) {
1908
                    $tabttc[$obj->rowid][$compta_soc] = 0;
1909
                }
1910
                if (!isset($tabht[$obj->rowid][$compta_prod])) {
1911
                    $tabht[$obj->rowid][$compta_prod] = 0;
1912
                }
1913
                if (!isset($tabtva[$obj->rowid][$compta_tva])) {
1914
                    $tabtva[$obj->rowid][$compta_tva] = 0;
1915
                }
1916
                if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
1917
                    $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
1918
                }
1919
                if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
1920
                    $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
1921
                }
1922
1923
                // VAT Reverse charge
1924
                if (($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) && $obj->vat_reverse_charge == 1 && in_array($obj->country_code, $country_code_in_EEC)) {
1925
                    $rcvatdata = getTaxesFromId($obj->product_buy_vat . ($obj->product_buy_default_vat_code ? ' (' . $obj->product_buy_default_vat_code . ')' : ''), $mysoc, $mysoc, 0);
1926
                    $rcc_compta_tva = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva);
1927
                    $rcd_compta_tva = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva);
1928
                    $rcc_compta_localtax1 = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva);
1929
                    $rcd_compta_localtax1 = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva);
1930
                    $rcc_compta_localtax2 = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva);
1931
                    $rcd_compta_localtax2 = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva);
1932
                    if (price2num($obj->product_buy_vat) || !empty($obj->product_buy_default_vat_code)) {
1933
                        $vat_key = vatrate($obj->product_buy_vat) . ($obj->product_buy_default_vat_code ? ' (' . $obj->product_buy_default_vat_code . ')' : '');
1934
                        $val_value = $vat_key;
1935
                        $def_tva[$obj->rowid][$rcc_compta_tva][$vat_key] = $val_value;
1936
                        $def_tva[$obj->rowid][$rcd_compta_tva][$vat_key] = $val_value;
1937
                    }
1938
1939
                    if (!isset($tabrctva[$obj->rowid][$rcc_compta_tva])) {
1940
                        $tabrctva[$obj->rowid][$rcc_compta_tva] = 0;
1941
                    }
1942
                    if (!isset($tabrctva[$obj->rowid][$rcd_compta_tva])) {
1943
                        $tabrctva[$obj->rowid][$rcd_compta_tva] = 0;
1944
                    }
1945
                    if (!isset($tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1])) {
1946
                        $tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1] = 0;
1947
                    }
1948
                    if (!isset($tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1])) {
1949
                        $tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1] = 0;
1950
                    }
1951
                    if (!isset($tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2])) {
1952
                        $tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2] = 0;
1953
                    }
1954
                    if (!isset($tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2])) {
1955
                        $tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2] = 0;
1956
                    }
1957
1958
                    $rcvat = (float) price2num($obj->total_ttc * $obj->product_buy_vat / 100, 'MT');
1959
                    $rclocalvat1 = (float) price2num($obj->total_ttc * $obj->product_buy_localvat1 / 100, 'MT');
1960
                    $rclocalvat2 = (float) price2num($obj->total_ttc * $obj->product_buy_localvat2 / 100, 'MT');
1961
1962
                    $tabrctva[$obj->rowid][$rcd_compta_tva] += $rcvat;
1963
                    $tabrctva[$obj->rowid][$rcc_compta_tva] -= $rcvat;
1964
                    $tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1] += $rclocalvat1;
1965
                    $tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1] -= $rclocalvat1;
1966
                    $tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2] += $rclocalvat2;
1967
                    $tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2] -= $rclocalvat2;
1968
                }
1969
1970
                $tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc;
1971
                $tabht[$obj->rowid][$compta_prod] += $obj->total_ht;
1972
                $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
1973
                $tva_npr = ((($obj->info_bits & 1) == 1) ? 1 : 0);
1974
                if ($tva_npr) { // If NPR, we add an entry for counterpartWe into tabother
1975
                    $tabother[$obj->rowid][$compta_counterpart_tva_npr] += $obj->total_tva;
1976
                }
1977
                $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
1978
                $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
1979
                $tabcompany[$obj->rowid] = array(
1980
                    'id' => $obj->socid,
1981
                    'name' => $obj->name,
1982
                    'code_fournisseur' => $obj->code_fournisseur,
1983
                    'code_compta_fournisseur' => $compta_soc
1984
                );
1985
1986
                $i++;
1987
            }
1988
        } else {
1989
            dol_print_error($db);
1990
        }
1991
1992
// Check for too many invoices first.
1993
        if (count($tabfac) > 10000) { // Global config in htdocs/admin/const.php???
1994
            $error++;
1995
            setEventMessages("TooManyInvoicesToProcessPleaseUseAMoreSelectiveFilter", null, 'errors');
1996
        }
1997
1998
        $errorforinvoice = array();
1999
2000
        /*
2001
        // Old way, 1 query for each invoice
2002
        // Loop in invoices to detect lines with not binding lines
2003
        foreach ($tabfac as $key => $val) {     // Loop on each invoice
2004
            $sql = "SELECT COUNT(fd.rowid) as nb";
2005
            $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn_det as fd";
2006
            $sql .= " WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0";
2007
            $sql .= " AND fd.total_ttc <> 0 AND fk_facture_fourn = ".((int) $key);
2008
            $resql = $db->query($sql);
2009
            if ($resql) {
2010
                $obj = $db->fetch_object($resql);
2011
                if ($obj->nb > 0) {
2012
                    $errorforinvoice[$key] = 'somelinesarenotbound';
2013
                }
2014
            } else {
2015
                dol_print_error($db);
2016
            }
2017
        }
2018
        */
2019
// New way, single query, load all unbound lines
2020
        $sql = "
2021
SELECT
2022
    fk_facture_fourn,
2023
    COUNT(fd.rowid) as nb
2024
FROM
2025
    llx_facture_fourn_det as fd
2026
WHERE
2027
    fd.product_type <= 2
2028
    AND fd.fk_code_ventilation <= 0
2029
    AND fd.total_ttc <> 0
2030
	AND fk_facture_fourn IN (" . $db->sanitize(implode(",", array_keys($tabfac))) . ")
2031
GROUP BY fk_facture_fourn
2032
";
2033
        $resql = $db->query($sql);
2034
2035
        $num = $db->num_rows($resql);
2036
        $i = 0;
2037
        while ($i < $num) {
2038
            $obj = $db->fetch_object($resql);
2039
            if ($obj->nb > 0) {
2040
                $errorforinvoice[$obj->fk_facture_fourn] = 'somelinesarenotbound';
2041
            }
2042
            $i++;
2043
        }
2044
//var_dump($errorforinvoice);exit;
2045
2046
2047
2048
// Bookkeeping Write
2049
        if ($action == 'writebookkeeping' && !$error) {
2050
            $now = dol_now();
2051
            $error = 0;
2052
2053
            $companystatic = new Societe($db);
0 ignored issues
show
Deprecated Code introduced by
The class DoliModules\Company\Model\Societe has been deprecated: Use Company instead! ( Ignorable by Annotation )

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

2053
            $companystatic = /** @scrutinizer ignore-deprecated */ new Societe($db);
Loading history...
2054
            $invoicestatic = new FactureFournisseur($db);
2055
            $accountingaccountsupplier = new AccountingAccount($db);
2056
2057
            $accountingaccountsupplier->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), true);
2058
2059
            foreach ($tabfac as $key => $val) {     // Loop on each invoice
2060
                $errorforline = 0;
2061
2062
                $totalcredit = 0;
2063
                $totaldebit = 0;
2064
2065
                $db->begin();
2066
2067
                $companystatic->id = $tabcompany[$key]['id'];
2068
                $companystatic->name = $tabcompany[$key]['name'];
2069
                $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
2070
                $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
2071
                $companystatic->fournisseur = 1;
2072
2073
                $invoicestatic->id = $key;
2074
                $invoicestatic->ref = (string) $val["refsologest"];
2075
                $invoicestatic->ref_supplier = $val["refsuppliersologest"];
2076
                $invoicestatic->type = $val["type"];
2077
                $invoicestatic->description = html_entity_decode(dol_trunc($val["description"], 32));
2078
                $invoicestatic->close_code = $val["close_code"];
2079
2080
                $date = dol_print_date($val["date"], 'day');
2081
2082
                // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
2083
                $replacedinvoice = 0;
2084
                if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
2085
                    $replacedinvoice = 1;
2086
                    $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
2087
                    if ($alreadydispatched) {
2088
                        $replacedinvoice = 2;
2089
                    }
2090
                }
2091
2092
                // If not already into bookkeeping, we won't add it. If yes, do nothing (should not happen because creating replacement not possible if invoice is accounted)
2093
                if ($replacedinvoice == 1) {
2094
                    $db->rollback();
2095
                    continue;
2096
                }
2097
2098
                // Error if some lines are not binded/ready to be journalized
2099
                if ($errorforinvoice[$key] == 'somelinesarenotbound') {
2100
                    $error++;
2101
                    $errorforline++;
2102
                    setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
2103
                }
2104
2105
                // Thirdparty
2106
                if (!$errorforline) {
2107
                    foreach ($tabttc[$key] as $k => $mt) {
2108
                        $bookkeeping = new BookKeeping($db);
2109
                        $bookkeeping->doc_date = $val["date"];
2110
                        $bookkeeping->date_lim_reglement = $val["datereg"];
2111
                        $bookkeeping->doc_ref = $val["refsologest"];
2112
                        $bookkeeping->date_creation = $now;
2113
                        $bookkeeping->doc_type = 'supplier_invoice';
2114
                        $bookkeeping->fk_doc = $key;
2115
                        $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
2116
                        $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
2117
2118
                        $bookkeeping->subledger_account = $tabcompany[$key]['code_compta_fournisseur'];
2119
                        $bookkeeping->subledger_label = $tabcompany[$key]['name'];
2120
2121
                        $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER');
2122
                        $bookkeeping->label_compte = $accountingaccountsupplier->label;
2123
2124
                        $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("SubledgerAccount");
2125
                        $bookkeeping->montant = $mt;
2126
                        $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
2127
                        $bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
2128
                        $bookkeeping->credit = ($mt > 0) ? $mt : 0;
2129
                        $bookkeeping->code_journal = $journal;
2130
                        $bookkeeping->journal_label = $langs->transnoentities($journal_label);
2131
                        $bookkeeping->fk_user_author = $user->id;
2132
                        $bookkeeping->entity = $conf->entity;
2133
2134
                        $totaldebit += $bookkeeping->debit;
2135
                        $totalcredit += $bookkeeping->credit;
2136
2137
                        $result = $bookkeeping->create($user);
2138
                        if ($result < 0) {
2139
                            if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
2140
                                $error++;
2141
                                $errorforline++;
2142
                                $errorforinvoice[$key] = 'alreadyjournalized';
2143
                                //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
2144
                            } else {
2145
                                $error++;
2146
                                $errorforline++;
2147
                                $errorforinvoice[$key] = 'other';
2148
                                setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
2149
                            }
2150
                        } else {
2151
                            if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
2152
                                require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
2153
                                $lettering_static = new Lettering($db);
2154
2155
                                $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id));
2156
                            }
2157
                        }
2158
                    }
2159
                }
2160
2161
                // Product / Service
2162
                if (!$errorforline) {
2163
                    foreach ($tabht[$key] as $k => $mt) {
2164
                        $resultfetch = $accountingaccount->fetch(null, $k, true);   // TODO Use a cache
2165
                        $label_account = $accountingaccount->label;
2166
2167
                        // get compte id and label
2168
                        if ($resultfetch > 0) {
2169
                            $bookkeeping = new BookKeeping($db);
2170
                            $bookkeeping->doc_date = $val["date"];
2171
                            $bookkeeping->date_lim_reglement = $val["datereg"];
2172
                            $bookkeeping->doc_ref = $val["refsologest"];
2173
                            $bookkeeping->date_creation = $now;
2174
                            $bookkeeping->doc_type = 'supplier_invoice';
2175
                            $bookkeeping->fk_doc = $key;
2176
                            $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
2177
                            $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
2178
2179
                            if (getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
2180
                                if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
2181
                                    $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
2182
                                    $bookkeeping->subledger_label = $tabcompany[$key]['name'];
2183
                                } else {
2184
                                    $bookkeeping->subledger_account = '';
2185
                                    $bookkeeping->subledger_label = '';
2186
                                }
2187
                            } else {
2188
                                $bookkeeping->subledger_account = '';
2189
                                $bookkeeping->subledger_label = '';
2190
                            }
2191
2192
                            $bookkeeping->numero_compte = $k;
2193
                            $bookkeeping->label_compte = $label_account;
2194
2195
                            $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $label_account;
2196
                            $bookkeeping->montant = $mt;
2197
                            $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
2198
                            $bookkeeping->debit = ($mt > 0) ? $mt : 0;
2199
                            $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
2200
                            $bookkeeping->code_journal = $journal;
2201
                            $bookkeeping->journal_label = $langs->transnoentities($journal_label);
2202
                            $bookkeeping->fk_user_author = $user->id;
2203
                            $bookkeeping->entity = $conf->entity;
2204
2205
                            $totaldebit += $bookkeeping->debit;
2206
                            $totalcredit += $bookkeeping->credit;
2207
2208
                            $result = $bookkeeping->create($user);
2209
                            if ($result < 0) {
2210
                                if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
2211
                                    $error++;
2212
                                    $errorforline++;
2213
                                    $errorforinvoice[$key] = 'alreadyjournalized';
2214
                                    //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
2215
                                } else {
2216
                                    $error++;
2217
                                    $errorforline++;
2218
                                    $errorforinvoice[$key] = 'other';
2219
                                    setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
2220
                                }
2221
                            }
2222
                        }
2223
                    }
2224
                }
2225
2226
                // VAT
2227
                // var_dump($tabtva);
2228
                if (!$errorforline) {
2229
                    $listoftax = array(0, 1, 2);
2230
                    foreach ($listoftax as $numtax) {
2231
                        $arrayofvat = $tabtva;
2232
                        if ($numtax == 1) {
2233
                            $arrayofvat = $tablocaltax1;
2234
                        }
2235
                        if ($numtax == 2) {
2236
                            $arrayofvat = $tablocaltax2;
2237
                        }
2238
2239
                        // VAT Reverse charge
2240
                        if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
2241
                            $has_vat = false;
2242
                            foreach ($arrayofvat[$key] as $k => $mt) {
2243
                                if ($mt) {
2244
                                    $has_vat = true;
2245
                                }
2246
                            }
2247
2248
                            if (!$has_vat) {
2249
                                $arrayofvat = $tabrctva;
2250
                                if ($numtax == 1) {
2251
                                    $arrayofvat = $tabrclocaltax1;
2252
                                }
2253
                                if ($numtax == 2) {
2254
                                    $arrayofvat = $tabrclocaltax2;
2255
                                }
2256
                                if (!is_array($arrayofvat[$key])) {
2257
                                    $arrayofvat[$key] = array();
2258
                                }
2259
                            }
2260
                        }
2261
2262
                        foreach ($arrayofvat[$key] as $k => $mt) {
2263
                            if ($mt) {
2264
                                $accountingaccount->fetch(null, $k, true);      // TODO Use a cache for label
2265
                                $label_account = $accountingaccount->label;
2266
2267
                                $bookkeeping = new BookKeeping($db);
2268
                                $bookkeeping->doc_date = $val["date"];
2269
                                $bookkeeping->date_lim_reglement = $val["datereg"];
2270
                                $bookkeeping->doc_ref = $val["refsologest"];
2271
                                $bookkeeping->date_creation = $now;
2272
                                $bookkeeping->doc_type = 'supplier_invoice';
2273
                                $bookkeeping->fk_doc = $key;
2274
                                $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
2275
                                $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
2276
2277
                                $bookkeeping->subledger_account = '';
2278
                                $bookkeeping->subledger_label = '';
2279
2280
                                $bookkeeping->numero_compte = $k;
2281
                                $bookkeeping->label_compte = $label_account;
2282
2283
                                $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("VAT") . ' ' . implode(', ', $def_tva[$key][$k]) . ' %' . ($numtax ? ' - Localtax ' . $numtax : '');
2284
                                $bookkeeping->montant = $mt;
2285
                                $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
2286
                                $bookkeeping->debit = ($mt > 0) ? $mt : 0;
2287
                                $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
2288
                                $bookkeeping->code_journal = $journal;
2289
                                $bookkeeping->journal_label = $langs->transnoentities($journal_label);
2290
                                $bookkeeping->fk_user_author = $user->id;
2291
                                $bookkeeping->entity = $conf->entity;
2292
2293
                                $totaldebit += $bookkeeping->debit;
2294
                                $totalcredit += $bookkeeping->credit;
2295
2296
                                $result = $bookkeeping->create($user);
2297
                                if ($result < 0) {
2298
                                    if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
2299
                                        $error++;
2300
                                        $errorforline++;
2301
                                        $errorforinvoice[$key] = 'alreadyjournalized';
2302
                                        //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
2303
                                    } else {
2304
                                        $error++;
2305
                                        $errorforline++;
2306
                                        $errorforinvoice[$key] = 'other';
2307
                                        setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
2308
                                    }
2309
                                }
2310
                            }
2311
                        }
2312
                    }
2313
                }
2314
2315
                // Counterpart of VAT for VAT NPR
2316
                // var_dump($tabother);
2317
                if (!$errorforline && is_array($tabother[$key])) {
2318
                    foreach ($tabother[$key] as $k => $mt) {
2319
                        if ($mt) {
2320
                            $bookkeeping = new BookKeeping($db);
2321
                            $bookkeeping->doc_date = $val["date"];
2322
                            $bookkeeping->date_lim_reglement = $val["datereg"];
2323
                            $bookkeeping->doc_ref = $val["refsologest"];
2324
                            $bookkeeping->date_creation = $now;
2325
                            $bookkeeping->doc_type = 'supplier_invoice';
2326
                            $bookkeeping->fk_doc = $key;
2327
                            $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
2328
                            $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
2329
2330
                            $bookkeeping->subledger_account = '';
2331
                            $bookkeeping->subledger_label = '';
2332
2333
                            $bookkeeping->numero_compte = $k;
2334
2335
                            $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref_supplier . ' - ' . $langs->trans("VAT") . ' NPR';
2336
                            $bookkeeping->montant = $mt;
2337
                            $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
2338
                            $bookkeeping->debit = ($mt > 0) ? $mt : 0;
2339
                            $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
2340
                            $bookkeeping->code_journal = $journal;
2341
                            $bookkeeping->journal_label = $langs->transnoentities($journal_label);
2342
                            $bookkeeping->fk_user_author = $user->id;
2343
                            $bookkeeping->entity = $conf->entity;
2344
2345
                            $totaldebit += $bookkeeping->debit;
2346
                            $totalcredit += $bookkeeping->credit;
2347
2348
                            $result = $bookkeeping->create($user);
2349
                            if ($result < 0) {
2350
                                if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
2351
                                    $error++;
2352
                                    $errorforline++;
2353
                                    $errorforinvoice[$key] = 'alreadyjournalized';
2354
                                    //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
2355
                                } else {
2356
                                    $error++;
2357
                                    $errorforline++;
2358
                                    $errorforinvoice[$key] = 'other';
2359
                                    setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
2360
                                }
2361
                            }
2362
                        }
2363
                    }
2364
                }
2365
2366
                // Protection against a bug on lines before
2367
                if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
2368
                    $error++;
2369
                    $errorforline++;
2370
                    $errorforinvoice[$key] = 'amountsnotbalanced';
2371
                    setEventMessages('We tried to insert a non balanced transaction in book for ' . $invoicestatic->ref . '. Canceled. Surely a bug.', null, 'errors');
2372
                }
2373
2374
                if (!$errorforline) {
2375
                    $db->commit();
2376
                } else {
2377
                    $db->rollback();
2378
2379
                    if ($error >= 10) {
2380
                        setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
2381
                        break; // Break in the foreach
2382
                    }
2383
                }
2384
            }
2385
2386
            $tabpay = $tabfac;
2387
2388
            if (empty($error) && count($tabpay) > 0) {
2389
                setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
2390
            } elseif (count($tabpay) == $error) {
2391
                setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
2392
            } else {
2393
                setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
2394
            }
2395
2396
            $action = '';
2397
2398
            // Must reload data, so we make a redirect
2399
            if (count($tabpay) != $error) {
2400
                $param = 'id_journal=' . $id_journal;
2401
                $param .= '&date_startday=' . $date_startday;
2402
                $param .= '&date_startmonth=' . $date_startmonth;
2403
                $param .= '&date_startyear=' . $date_startyear;
2404
                $param .= '&date_endday=' . $date_endday;
2405
                $param .= '&date_endmonth=' . $date_endmonth;
2406
                $param .= '&date_endyear=' . $date_endyear;
2407
                $param .= '&in_bookkeeping=' . $in_bookkeeping;
2408
                header("Location: " . $_SERVER['PHP_SELF'] . ($param ? '?' . $param : ''));
2409
                exit;
2410
            }
2411
        }
2412
2413
        /*
2414
         * View
2415
         */
2416
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/journal_purchasesjournal.php');
2417
2418
        $db->close();
2419
        return true;
2420
    }
2421
2422
    /**
2423
     * \file        htdocs/accountancy/journal/sellsjournal.php
2424
     * \ingroup     Accountancy (Double entries)
2425
     * \brief       Page with sells journal
2426
     */
2427
    public function sellsjournal()
2428
    {
2429
        global $conf;
2430
        global $db;
2431
        global $user;
2432
        global $hookmanager;
2433
        global $user;
2434
        global $menumanager;
2435
        global $langs;
2436
        global $mysoc;
2437
2438
// Load translation files required by the page
2439
        $langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "errors"));
2440
2441
        $id_journal = GETPOSTINT('id_journal');
2442
        $action = GETPOST('action', 'aZ09');
2443
2444
        $date_startmonth = GETPOST('date_startmonth');
2445
        $date_startday = GETPOST('date_startday');
2446
        $date_startyear = GETPOST('date_startyear');
2447
        $date_endmonth = GETPOST('date_endmonth');
2448
        $date_endday = GETPOST('date_endday');
2449
        $date_endyear = GETPOST('date_endyear');
2450
        $in_bookkeeping = GETPOST('in_bookkeeping');
2451
        if ($in_bookkeeping == '') {
2452
            $in_bookkeeping = 'notyet';
2453
        }
2454
2455
        $now = dol_now();
2456
2457
        $hookmanager->initHooks(array('sellsjournal'));
2458
        $parameters = array();
2459
2460
// Security check
2461
        if (!isModEnabled('accounting')) {
2462
            accessforbidden();
2463
        }
2464
        if ($user->socid > 0) {
2465
            accessforbidden();
2466
        }
2467
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
2468
            accessforbidden();
2469
        }
2470
2471
        $error = 0;
2472
2473
2474
        /*
2475
         * Actions
2476
         */
2477
2478
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks
2479
2480
        $accountingaccount = new AccountingAccount($db);
2481
2482
// Get information of journal
2483
        $accountingjournalstatic = new AccountingJournal($db);
2484
        $accountingjournalstatic->fetch($id_journal);
2485
        $journal = $accountingjournalstatic->code;
2486
        $journal_label = $accountingjournalstatic->label;
2487
2488
        $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
2489
        $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
2490
2491
        if (empty($date_startmonth)) {
2492
            // Period by default on transfer
2493
            $dates = getDefaultDatesForTransfer();
2494
            $date_start = $dates['date_start'];
2495
            $pastmonthyear = $dates['pastmonthyear'];
2496
            $pastmonth = $dates['pastmonth'];
2497
        }
2498
        if (empty($date_endmonth)) {
2499
            // Period by default on transfer
2500
            $dates = getDefaultDatesForTransfer();
2501
            $date_end = $dates['date_end'];
2502
            $pastmonthyear = $dates['pastmonthyear'];
2503
            $pastmonth = $dates['pastmonth'];
2504
        }
2505
        if (getDolGlobalString('ACCOUNTANCY_JOURNAL_USE_CURRENT_MONTH')) {
2506
            $pastmonth += 1;
2507
        }
2508
2509
        if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
2510
            $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
2511
            $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
2512
        }
2513
2514
        $sql = "SELECT f.rowid, f.ref, f.type, f.situation_cycle_ref, f.datef as df, f.ref_client, f.date_lim_reglement as dlr, f.close_code, f.retained_warranty, f.revenuestamp,";
2515
        $sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.situation_percent, fd.vat_src_code, fd.info_bits,";
2516
        $sql .= " s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur,";
2517
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
2518
            $sql .= " spe.accountancy_code_customer as code_compta,";
2519
            $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
2520
        } else {
2521
            $sql .= " s.code_compta as code_compta,";
2522
            $sql .= " s.code_compta_fournisseur,";
2523
        }
2524
        $sql .= " p.rowid as pid, p.ref as pref, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte,";
2525
        if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
2526
            $sql .= " ppe.accountancy_code_sell";
2527
        } else {
2528
            $sql .= " p.accountancy_code_sell";
2529
        }
2530
        $parameters = array();
2531
        $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
2532
        $sql .= $hookmanager->resPrint;
2533
        $sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd";
2534
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = fd.fk_product";
2535
        if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
2536
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
2537
        }
2538
        $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = fd.fk_code_ventilation";
2539
        $sql .= " JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = fd.fk_facture";
2540
        $sql .= " JOIN " . MAIN_DB_PREFIX . "societe as s ON s.rowid = f.fk_soc";
2541
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
2542
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
2543
        }
2544
        $parameters = array();
2545
        $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
2546
        $sql .= $hookmanager->resPrint;
2547
        $sql .= " WHERE fd.fk_code_ventilation > 0";
2548
        $sql .= " AND f.entity IN (" . getEntity('invoice', 0) . ')'; // We don't share object for accountancy, we use source object sharing
2549
        $sql .= " AND f.fk_statut > 0";
2550
        if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) { // Non common setup
2551
            $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_SITUATION . ")";
2552
        } else {
2553
            $sql .= " AND f.type IN (" . Facture::TYPE_STANDARD . "," . Facture::TYPE_REPLACEMENT . "," . Facture::TYPE_CREDIT_NOTE . "," . Facture::TYPE_DEPOSIT . "," . Facture::TYPE_SITUATION . ")";
2554
        }
2555
        $sql .= " AND fd.product_type IN (0,1)";
2556
        if ($date_start && $date_end) {
2557
            $sql .= " AND f.datef >= '" . $db->idate($date_start) . "' AND f.datef <= '" . $db->idate($date_end) . "'";
2558
        }
2559
// Define begin binding date
2560
        if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
2561
            $sql .= " AND f.datef >= '" . $db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) . "'";
2562
        }
2563
// Already in bookkeeping or not
2564
        if ($in_bookkeeping == 'already') {
2565
            $sql .= " AND f.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')";
2566
            //  $sql .= " AND fd.rowid IN (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')";     // Useless, we save one line for all products with same account
2567
        }
2568
        if ($in_bookkeeping == 'notyet') {
2569
            $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')";
2570
            // $sql .= " AND fd.rowid NOT IN (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')";      // Useless, we save one line for all products with same account
2571
        }
2572
        $parameters = array();
2573
        $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
2574
        $sql .= $hookmanager->resPrint;
2575
        $sql .= " ORDER BY f.datef, f.ref";
2576
//print $sql;
2577
2578
        dol_syslog('accountancy/journal/sellsjournal.php', LOG_DEBUG);
2579
        $result = $db->query($sql);
2580
        if ($result) {
2581
            $tabfac = array();
2582
            $tabht = array();
2583
            $tabtva = array();
2584
            $def_tva = array();
2585
            $tabwarranty = array();
2586
            $tabrevenuestamp = array();
2587
            $tabttc = array();
2588
            $tablocaltax1 = array();
2589
            $tablocaltax2 = array();
2590
            $tabcompany = array();
2591
            $vatdata_cache = array();
2592
2593
            $num = $db->num_rows($result);
2594
2595
            // Variables
2596
            $cptcli = getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER', 'NotDefined');
2597
            $cpttva = getDolGlobalString('ACCOUNTING_VAT_SOLD_ACCOUNT', 'NotDefined');
2598
2599
            $i = 0;
2600
            while ($i < $num) {
2601
                $obj = $db->fetch_object($result);
2602
2603
                // Controls
2604
                $compta_soc = (!empty($obj->code_compta)) ? $obj->code_compta : $cptcli;
2605
2606
                $compta_prod = $obj->compte;
2607
                if (empty($compta_prod)) {
2608
                    if ($obj->product_type == 0) {
2609
                        $compta_prod = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT', 'NotDefined');
2610
                    } else {
2611
                        $compta_prod = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT', 'NotDefined');
2612
                    }
2613
                }
2614
2615
                //$compta_revenuestamp = getDolGlobalString('ACCOUNTING_REVENUESTAMP_SOLD_ACCOUNT', 'NotDefined');
2616
2617
                $tax_id = $obj->tva_tx . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : '');
2618
                if (array_key_exists($tax_id, $vatdata_cache)) {
2619
                    $vatdata = $vatdata_cache[$tax_id];
2620
                } else {
2621
                    $vatdata = getTaxesFromId($tax_id, $mysoc, $mysoc, 0);
2622
                    $vatdata_cache[$tax_id] = $vatdata;
2623
                }
2624
                $compta_tva = (!empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cpttva);
2625
                $compta_localtax1 = (!empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cpttva);
2626
                $compta_localtax2 = (!empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cpttva);
2627
2628
                // Define the array to store the detail of each vat rate and code for lines
2629
                if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
2630
                    $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx) . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : '')] = (vatrate($obj->tva_tx) . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : ''));
2631
                }
2632
2633
                // Create a compensation rate for situation invoice.
2634
                $situation_ratio = 1;
2635
                if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
2636
                    if ($obj->situation_cycle_ref) {
2637
                        // Avoid divide by 0
2638
                        if ($obj->situation_percent == 0) {
2639
                            $situation_ratio = 0;
2640
                        } else {
2641
                            $line = new FactureLigne($db);
2642
                            $line->fetch($obj->fdid);
2643
2644
                            // Situation invoices handling
2645
                            $prev_progress = $line->get_prev_progress($obj->rowid);
2646
2647
                            $situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
2648
                        }
2649
                    }
2650
                }
2651
2652
                $revenuestamp = (float) price2num($obj->revenuestamp, 'MT');
2653
2654
                // Invoice lines
2655
                $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df);
2656
                $tabfac[$obj->rowid]["datereg"] = $db->jdate($obj->dlr);
2657
                $tabfac[$obj->rowid]["ref"] = $obj->ref;
2658
                $tabfac[$obj->rowid]["type"] = $obj->type;
2659
                $tabfac[$obj->rowid]["description"] = $obj->label_compte;
2660
                $tabfac[$obj->rowid]["close_code"] = $obj->close_code; // close_code = 'replaced' for replacement invoices (not used in most european countries)
2661
                $tabfac[$obj->rowid]["revenuestamp"] = $revenuestamp;
2662
                //$tabfac[$obj->rowid]["fk_facturedet"] = $obj->fdid;
2663
2664
                // Avoid warnings
2665
                if (!isset($tabttc[$obj->rowid][$compta_soc])) {
2666
                    $tabttc[$obj->rowid][$compta_soc] = 0;
2667
                }
2668
                if (!isset($tabht[$obj->rowid][$compta_prod])) {
2669
                    $tabht[$obj->rowid][$compta_prod] = 0;
2670
                }
2671
                if (!isset($tabtva[$obj->rowid][$compta_tva])) {
2672
                    $tabtva[$obj->rowid][$compta_tva] = 0;
2673
                }
2674
                if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
2675
                    $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
2676
                }
2677
                if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
2678
                    $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
2679
                }
2680
2681
                // Compensation of data for invoice situation by using $situation_ratio. This works (nearly) for invoice that was not correctly recorded
2682
                // but it may introduces an error for situation invoices that were correctly saved. There is still rounding problem that differs between
2683
                // real data we should have stored and result obtained with a compensation.
2684
                // It also seems that credit notes on situation invoices are correctly saved (but it depends on the version used in fact).
2685
                // For credit notes, we hope to have situation_ratio = 1 so the compensation has no effect to avoid introducing troubles with credit notes.
2686
                if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
2687
                    $total_ttc = $obj->total_ttc * $situation_ratio;
2688
                } else {
2689
                    $total_ttc = $obj->total_ttc;
2690
                }
2691
2692
                // Move a part of the retained warrenty into the account of warranty
2693
                if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY') && $obj->retained_warranty > 0) {
2694
                    $retained_warranty = (float) price2num($total_ttc * $obj->retained_warranty / 100, 'MT');   // Calculate the amount of warrenty for this line (using the percent value)
2695
                    $tabwarranty[$obj->rowid][$compta_soc] += $retained_warranty;
2696
                    $total_ttc -= $retained_warranty;
2697
                }
2698
2699
                $tabttc[$obj->rowid][$compta_soc] += $total_ttc;
2700
                $tabht[$obj->rowid][$compta_prod] += $obj->total_ht * $situation_ratio;
2701
                $tva_npr = ((($obj->info_bits & 1) == 1) ? 1 : 0);
2702
                if (!$tva_npr) { // We ignore line if VAT is a NPR
2703
                    $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva * $situation_ratio;
2704
                }
2705
                $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1 * $situation_ratio;
2706
                $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2 * $situation_ratio;
2707
2708
                $compta_revenuestamp = 'NotDefined';
2709
                if (!empty($revenuestamp)) {
2710
                    $sqlrevenuestamp = "SELECT accountancy_code_sell FROM " . MAIN_DB_PREFIX . "c_revenuestamp";
2711
                    $sqlrevenuestamp .= " WHERE fk_pays = " . ((int) $mysoc->country_id);
2712
                    $sqlrevenuestamp .= " AND taux = " . ((float) $revenuestamp);
2713
                    $sqlrevenuestamp .= " AND active = 1";
2714
                    $resqlrevenuestamp = $db->query($sqlrevenuestamp);
2715
2716
                    if ($resqlrevenuestamp) {
2717
                        $num_rows_revenuestamp = $db->num_rows($resqlrevenuestamp);
2718
                        if ($num_rows_revenuestamp > 1) {
2719
                            dol_print_error($db, 'Failed 2 or more lines for the revenue stamp of your country. Check the dictionary of revenue stamp.');
2720
                        } else {
2721
                            $objrevenuestamp = $db->fetch_object($resqlrevenuestamp);
2722
                            if ($objrevenuestamp) {
2723
                                $compta_revenuestamp = $objrevenuestamp->accountancy_code_sell;
2724
                            }
2725
                        }
2726
                    }
2727
                }
2728
2729
                if (empty($tabrevenuestamp[$obj->rowid][$compta_revenuestamp]) && !empty($revenuestamp)) {
2730
                    // The revenue stamp was never seen for this invoice id=$obj->rowid
2731
                    $tabttc[$obj->rowid][$compta_soc] += $obj->revenuestamp;
2732
                    $tabrevenuestamp[$obj->rowid][$compta_revenuestamp] = $obj->revenuestamp;
2733
                }
2734
2735
                $tabcompany[$obj->rowid] = array(
2736
                    'id' => $obj->socid,
2737
                    'name' => $obj->name,
2738
                    'code_client' => $obj->code_client,
2739
                    'code_compta' => $compta_soc
2740
                );
2741
2742
                $i++;
2743
            }
2744
2745
            // After the loop on each line
2746
        } else {
2747
            dol_print_error($db);
2748
        }
2749
2750
// Check for too many invoices first.
2751
        if (count($tabfac) > 10000) {
2752
            $error++;
2753
            setEventMessages("TooManyInvoicesToProcessPleaseUseAMoreSelectiveFilter", null, 'errors');
2754
        }
2755
2756
        $errorforinvoice = array();
2757
2758
        /*
2759
        // Old way, 1 query for each invoice
2760
        // Loop on all invoices to detect lines without binded code (fk_code_ventilation <= 0)
2761
        foreach ($tabfac as $key => $val) {     // Loop on each invoice
2762
            $sql = "SELECT COUNT(fd.rowid) as nb";
2763
            $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
2764
            $sql .= " WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0";
2765
            $sql .= " AND fd.total_ttc <> 0 AND fk_facture = ".((int) $key);
2766
            $resql = $db->query($sql);
2767
            if ($resql) {
2768
                $obj = $db->fetch_object($resql);
2769
                if ($obj->nb > 0) {
2770
                    $errorforinvoice[$key] = 'somelinesarenotbound';
2771
                }
2772
            } else {
2773
                dol_print_error($db);
2774
            }
2775
        }
2776
        */
2777
// New way, single query, load all unbound lines
2778
2779
        $sql = "
2780
SELECT
2781
    fk_facture,
2782
    COUNT(fd.rowid) as nb
2783
FROM
2784
	" . MAIN_DB_PREFIX . "facturedet as fd
2785
WHERE
2786
    fd.product_type <= 2
2787
    AND fd.fk_code_ventilation <= 0
2788
    AND fd.total_ttc <> 0
2789
	AND fk_facture IN (" . $db->sanitize(implode(",", array_keys($tabfac))) . ")
2790
GROUP BY fk_facture
2791
";
2792
        $resql = $db->query($sql);
2793
2794
        $num = $db->num_rows($resql);
2795
        $i = 0;
2796
        while ($i < $num) {
2797
            $obj = $db->fetch_object($resql);
2798
            if ($obj->nb > 0) {
2799
                $errorforinvoice[$obj->fk_facture_fourn] = 'somelinesarenotbound';
2800
            }
2801
            $i++;
2802
        }
2803
//var_dump($errorforinvoice);exit;
2804
2805
// Bookkeeping Write
2806
        if ($action == 'writebookkeeping' && !$error) {
2807
            $now = dol_now();
2808
            $error = 0;
2809
2810
            $companystatic = new Societe($db);
0 ignored issues
show
Deprecated Code introduced by
The class DoliModules\Company\Model\Societe has been deprecated: Use Company instead! ( Ignorable by Annotation )

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

2810
            $companystatic = /** @scrutinizer ignore-deprecated */ new Societe($db);
Loading history...
2811
            $invoicestatic = new Facture($db);
2812
            $accountingaccountcustomer = new AccountingAccount($db);
2813
2814
            $accountingaccountcustomer->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER'), true);
2815
2816
            $accountingaccountcustomerwarranty = new AccountingAccount($db);
2817
2818
            $accountingaccountcustomerwarranty->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY'), true);
2819
2820
            foreach ($tabfac as $key => $val) {     // Loop on each invoice
2821
                $errorforline = 0;
2822
2823
                $totalcredit = 0;
2824
                $totaldebit = 0;
2825
2826
                $db->begin();
2827
2828
                $companystatic->id = $tabcompany[$key]['id'];
2829
                $companystatic->name = $tabcompany[$key]['name'];
2830
                $companystatic->code_compta = $tabcompany[$key]['code_compta'];
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

2830
                /** @scrutinizer ignore-deprecated */ $companystatic->code_compta = $tabcompany[$key]['code_compta'];

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2831
                $companystatic->code_compta_client = $tabcompany[$key]['code_compta'];
2832
                $companystatic->code_client = $tabcompany[$key]['code_client'];
2833
                $companystatic->client = 3;
2834
2835
                $invoicestatic->id = $key;
2836
                $invoicestatic->ref = (string) $val["ref"];
2837
                $invoicestatic->type = $val["type"];
2838
                $invoicestatic->close_code = $val["close_code"];
2839
2840
                $date = dol_print_date($val["date"], 'day');
2841
2842
                // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
2843
                $replacedinvoice = 0;
2844
                if ($invoicestatic->close_code == Facture::CLOSECODE_REPLACED) {
2845
                    $replacedinvoice = 1;
2846
                    $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
2847
                    if ($alreadydispatched) {
2848
                        $replacedinvoice = 2;
2849
                    }
2850
                }
2851
2852
                // If not already into bookkeeping, we won't add it. If yes, do nothing (should not happen because creating replacement not possible if invoice is accounted)
2853
                if ($replacedinvoice == 1) {
2854
                    $db->rollback();
2855
                    continue;
2856
                }
2857
2858
                // Error if some lines are not binded/ready to be journalized
2859
                if ($errorforinvoice[$key] == 'somelinesarenotbound') {
2860
                    $error++;
2861
                    $errorforline++;
2862
                    setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
2863
                }
2864
2865
                // Warranty
2866
                if (!$errorforline) {
2867
                    if (is_array($tabwarranty[$key])) {
2868
                        foreach ($tabwarranty[$key] as $k => $mt) {
2869
                            $bookkeeping = new BookKeeping($db);
2870
                            $bookkeeping->doc_date = $val["date"];
2871
                            $bookkeeping->date_lim_reglement = $val["datereg"];
2872
                            $bookkeeping->doc_ref = $val["ref"];
2873
                            $bookkeeping->date_creation = $now;
2874
                            $bookkeeping->doc_type = 'customer_invoice';
2875
                            $bookkeeping->fk_doc = $key;
2876
                            $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
2877
                            $bookkeeping->thirdparty_code = $companystatic->code_client;
2878
2879
                            $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
2880
                            $bookkeeping->subledger_label = $tabcompany[$key]['name'];
2881
2882
                            $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY');
2883
                            $bookkeeping->label_compte = $accountingaccountcustomerwarranty->label;
2884
2885
                            $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("Retainedwarranty");
2886
                            $bookkeeping->montant = $mt;
2887
                            $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
2888
                            $bookkeeping->debit = ($mt >= 0) ? $mt : 0;
2889
                            $bookkeeping->credit = ($mt < 0) ? -$mt : 0;
2890
                            $bookkeeping->code_journal = $journal;
2891
                            $bookkeeping->journal_label = $langs->transnoentities($journal_label);
2892
                            $bookkeeping->fk_user_author = $user->id;
2893
                            $bookkeeping->entity = $conf->entity;
2894
2895
                            $totaldebit += $bookkeeping->debit;
2896
                            $totalcredit += $bookkeeping->credit;
2897
2898
                            $result = $bookkeeping->create($user);
2899
                            if ($result < 0) {
2900
                                if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {    // Already exists
2901
                                    $error++;
2902
                                    $errorforline++;
2903
                                    $errorforinvoice[$key] = 'alreadyjournalized';
2904
                                    //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
2905
                                } else {
2906
                                    $error++;
2907
                                    $errorforline++;
2908
                                    $errorforinvoice[$key] = 'other';
2909
                                    setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
2910
                                }
2911
                            }
2912
                        }
2913
                    }
2914
                }
2915
2916
                // Thirdparty
2917
                if (!$errorforline) {
2918
                    foreach ($tabttc[$key] as $k => $mt) {
2919
                        $bookkeeping = new BookKeeping($db);
2920
                        $bookkeeping->doc_date = $val["date"];
2921
                        $bookkeeping->date_lim_reglement = $val["datereg"];
2922
                        $bookkeeping->doc_ref = $val["ref"];
2923
                        $bookkeeping->date_creation = $now;
2924
                        $bookkeeping->doc_type = 'customer_invoice';
2925
                        $bookkeeping->fk_doc = $key;
2926
                        $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
2927
                        $bookkeeping->thirdparty_code = $companystatic->code_client;
2928
2929
                        $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
2930
                        $bookkeeping->subledger_label = $tabcompany[$key]['name'];
2931
2932
                        $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER');
2933
                        $bookkeeping->label_compte = $accountingaccountcustomer->label;
2934
2935
                        $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("SubledgerAccount");
2936
                        $bookkeeping->montant = $mt;
2937
                        $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
2938
                        $bookkeeping->debit = ($mt >= 0) ? $mt : 0;
2939
                        $bookkeeping->credit = ($mt < 0) ? -$mt : 0;
2940
                        $bookkeeping->code_journal = $journal;
2941
                        $bookkeeping->journal_label = $langs->transnoentities($journal_label);
2942
                        $bookkeeping->fk_user_author = $user->id;
2943
                        $bookkeeping->entity = $conf->entity;
2944
2945
                        $totaldebit += $bookkeeping->debit;
2946
                        $totalcredit += $bookkeeping->credit;
2947
2948
                        $result = $bookkeeping->create($user);
2949
                        if ($result < 0) {
2950
                            if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
2951
                                $error++;
2952
                                $errorforline++;
2953
                                $errorforinvoice[$key] = 'alreadyjournalized';
2954
                                //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
2955
                            } else {
2956
                                $error++;
2957
                                $errorforline++;
2958
                                $errorforinvoice[$key] = 'other';
2959
                                setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
2960
                            }
2961
                        } else {
2962
                            if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
2963
                                require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
2964
                                $lettering_static = new Lettering($db);
2965
2966
                                $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id));
2967
                            }
2968
                        }
2969
                    }
2970
                }
2971
2972
                // Product / Service
2973
                if (!$errorforline) {
2974
                    foreach ($tabht[$key] as $k => $mt) {
2975
                        $resultfetch = $accountingaccount->fetch(null, $k, true);   // TODO Use a cache
2976
                        $label_account = $accountingaccount->label;
2977
2978
                        // get compte id and label
2979
                        if ($resultfetch > 0) {
2980
                            $bookkeeping = new BookKeeping($db);
2981
                            $bookkeeping->doc_date = $val["date"];
2982
                            $bookkeeping->date_lim_reglement = $val["datereg"];
2983
                            $bookkeeping->doc_ref = $val["ref"];
2984
                            $bookkeeping->date_creation = $now;
2985
                            $bookkeeping->doc_type = 'customer_invoice';
2986
                            $bookkeeping->fk_doc = $key;
2987
                            $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
2988
                            $bookkeeping->thirdparty_code = $companystatic->code_client;
2989
2990
                            if (getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT')) {
2991
                                if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
2992
                                    $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
2993
                                    $bookkeeping->subledger_label = $tabcompany[$key]['name'];
2994
                                } else {
2995
                                    $bookkeeping->subledger_account = '';
2996
                                    $bookkeeping->subledger_label = '';
2997
                                }
2998
                            } else {
2999
                                $bookkeeping->subledger_account = '';
3000
                                $bookkeeping->subledger_label = '';
3001
                            }
3002
3003
                            $bookkeeping->numero_compte = $k;
3004
                            $bookkeeping->label_compte = $label_account;
3005
3006
                            $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $label_account;
3007
                            $bookkeeping->montant = $mt;
3008
                            $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
3009
                            $bookkeeping->debit = ($mt < 0) ? -$mt : 0;
3010
                            $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
3011
                            $bookkeeping->code_journal = $journal;
3012
                            $bookkeeping->journal_label = $langs->transnoentities($journal_label);
3013
                            $bookkeeping->fk_user_author = $user->id;
3014
                            $bookkeeping->entity = $conf->entity;
3015
3016
                            $totaldebit += $bookkeeping->debit;
3017
                            $totalcredit += $bookkeeping->credit;
3018
3019
                            $result = $bookkeeping->create($user);
3020
                            if ($result < 0) {
3021
                                if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
3022
                                    $error++;
3023
                                    $errorforline++;
3024
                                    $errorforinvoice[$key] = 'alreadyjournalized';
3025
                                    //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
3026
                                } else {
3027
                                    $error++;
3028
                                    $errorforline++;
3029
                                    $errorforinvoice[$key] = 'other';
3030
                                    setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
3031
                                }
3032
                            }
3033
                        }
3034
                    }
3035
                }
3036
3037
                // VAT
3038
                if (!$errorforline) {
3039
                    $listoftax = array(0, 1, 2);
3040
                    foreach ($listoftax as $numtax) {
3041
                        $arrayofvat = $tabtva;
3042
                        if ($numtax == 1) {
3043
                            $arrayofvat = $tablocaltax1;
3044
                        }
3045
                        if ($numtax == 2) {
3046
                            $arrayofvat = $tablocaltax2;
3047
                        }
3048
3049
                        foreach ($arrayofvat[$key] as $k => $mt) {
3050
                            if ($mt) {
3051
                                $accountingaccount->fetch(null, $k, true);  // TODO Use a cache for label
3052
                                $label_account = $accountingaccount->label;
3053
3054
                                $bookkeeping = new BookKeeping($db);
3055
                                $bookkeeping->doc_date = $val["date"];
3056
                                $bookkeeping->date_lim_reglement = $val["datereg"];
3057
                                $bookkeeping->doc_ref = $val["ref"];
3058
                                $bookkeeping->date_creation = $now;
3059
                                $bookkeeping->doc_type = 'customer_invoice';
3060
                                $bookkeeping->fk_doc = $key;
3061
                                $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
3062
                                $bookkeeping->thirdparty_code = $companystatic->code_client;
3063
3064
                                $bookkeeping->subledger_account = '';
3065
                                $bookkeeping->subledger_label = '';
3066
3067
                                $bookkeeping->numero_compte = $k;
3068
                                $bookkeeping->label_compte = $label_account;
3069
3070
3071
                                $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref;
3072
                                $tmpvatrate = (empty($def_tva[$key][$k]) ? (empty($arrayofvat[$key][$k]) ? '' : $arrayofvat[$key][$k]) : implode(', ', $def_tva[$key][$k]));
3073
                                $bookkeeping->label_operation .= ' - ' . $langs->trans("Taxes") . ' ' . $tmpvatrate . ' %';
3074
                                $bookkeeping->label_operation .= ($numtax ? ' - Localtax ' . $numtax : '');
3075
3076
                                $bookkeeping->montant = $mt;
3077
                                $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
3078
                                $bookkeeping->debit = ($mt < 0) ? -$mt : 0;
3079
                                $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
3080
                                $bookkeeping->code_journal = $journal;
3081
                                $bookkeeping->journal_label = $langs->transnoentities($journal_label);
3082
                                $bookkeeping->fk_user_author = $user->id;
3083
                                $bookkeeping->entity = $conf->entity;
3084
3085
                                $totaldebit += $bookkeeping->debit;
3086
                                $totalcredit += $bookkeeping->credit;
3087
3088
                                $result = $bookkeeping->create($user);
3089
                                if ($result < 0) {
3090
                                    if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {  // Already exists
3091
                                        $error++;
3092
                                        $errorforline++;
3093
                                        $errorforinvoice[$key] = 'alreadyjournalized';
3094
                                        //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
3095
                                    } else {
3096
                                        $error++;
3097
                                        $errorforline++;
3098
                                        $errorforinvoice[$key] = 'other';
3099
                                        setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
3100
                                    }
3101
                                }
3102
                            }
3103
                        }
3104
                    }
3105
                }
3106
3107
                // Revenue stamp
3108
                if (!$errorforline) {
3109
                    if (is_array($tabrevenuestamp[$key])) {
3110
                        foreach ($tabrevenuestamp[$key] as $k => $mt) {
3111
                            if ($mt) {
3112
                                $accountingaccount->fetch(null, $k, true);    // TODO Use a cache for label
3113
                                $label_account = $accountingaccount->label;
3114
3115
                                $bookkeeping = new BookKeeping($db);
3116
                                $bookkeeping->doc_date = $val["date"];
3117
                                $bookkeeping->date_lim_reglement = $val["datereg"];
3118
                                $bookkeeping->doc_ref = $val["ref"];
3119
                                $bookkeeping->date_creation = $now;
3120
                                $bookkeeping->doc_type = 'customer_invoice';
3121
                                $bookkeeping->fk_doc = $key;
3122
                                $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
3123
                                $bookkeeping->thirdparty_code = $companystatic->code_client;
3124
3125
                                $bookkeeping->subledger_account = '';
3126
                                $bookkeeping->subledger_label = '';
3127
3128
                                $bookkeeping->numero_compte = $k;
3129
                                $bookkeeping->label_compte = $label_account;
3130
3131
                                $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("RevenueStamp");
3132
                                $bookkeeping->montant = $mt;
3133
                                $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
3134
                                $bookkeeping->debit = ($mt < 0) ? -$mt : 0;
3135
                                $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
3136
                                $bookkeeping->code_journal = $journal;
3137
                                $bookkeeping->journal_label = $langs->transnoentities($journal_label);
3138
                                $bookkeeping->fk_user_author = $user->id;
3139
                                $bookkeeping->entity = $conf->entity;
3140
3141
                                $totaldebit += $bookkeeping->debit;
3142
                                $totalcredit += $bookkeeping->credit;
3143
3144
                                $result = $bookkeeping->create($user);
3145
                                if ($result < 0) {
3146
                                    if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') {    // Already exists
3147
                                        $error++;
3148
                                        $errorforline++;
3149
                                        $errorforinvoice[$key] = 'alreadyjournalized';
3150
                                        //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
3151
                                    } else {
3152
                                        $error++;
3153
                                        $errorforline++;
3154
                                        $errorforinvoice[$key] = 'other';
3155
                                        setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
3156
                                    }
3157
                                }
3158
                            }
3159
                        }
3160
                    }
3161
                }
3162
3163
                // Protection against a bug on lines before
3164
                if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
3165
                    $error++;
3166
                    $errorforline++;
3167
                    $errorforinvoice[$key] = 'amountsnotbalanced';
3168
                    setEventMessages('We Tried to insert a non balanced transaction in book for ' . $invoicestatic->ref . '. Canceled. Surely a bug.', null, 'errors');
3169
                }
3170
3171
                if (!$errorforline) {
3172
                    $db->commit();
3173
                } else {
3174
                    $db->rollback();
3175
3176
                    if ($error >= 10) {
3177
                        setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
3178
                        break; // Break in the foreach
3179
                    }
3180
                }
3181
            }
3182
3183
            $tabpay = $tabfac;
3184
3185
            if (empty($error) && count($tabpay) > 0) {
3186
                setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
3187
            } elseif (count($tabpay) == $error) {
3188
                setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
3189
            } else {
3190
                setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
3191
            }
3192
3193
            $action = '';
3194
3195
            // Must reload data, so we make a redirect
3196
            if (count($tabpay) != $error) {
3197
                $param = 'id_journal=' . $id_journal;
3198
                $param .= '&date_startday=' . $date_startday;
3199
                $param .= '&date_startmonth=' . $date_startmonth;
3200
                $param .= '&date_startyear=' . $date_startyear;
3201
                $param .= '&date_endday=' . $date_endday;
3202
                $param .= '&date_endmonth=' . $date_endmonth;
3203
                $param .= '&date_endyear=' . $date_endyear;
3204
                $param .= '&in_bookkeeping=' . $in_bookkeeping;
3205
                header("Location: " . $_SERVER['PHP_SELF'] . ($param ? '?' . $param : ''));
3206
                exit;
3207
            }
3208
        }
3209
3210
        /*
3211
         * View
3212
         */
3213
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/journal_sellsjournal.php');
3214
3215
        $db->close();
3216
        return true;
3217
    }
3218
3219
    /**
3220
     * \file        htdocs/accountancy/journal/variousjournal.php
3221
     * \ingroup     Accountancy (Double entries)
3222
     * \brief       Page of a journal
3223
     */
3224
    public function variousjournal()
3225
    {
3226
        global $conf;
3227
        global $db;
3228
        global $user;
3229
        global $hookmanager;
3230
        global $user;
3231
        global $menumanager;
3232
        global $langs;
3233
        global $mysoc;
3234
3235
// Load translation files required by the page
3236
        $langs->loadLangs(array("banks", "accountancy", "compta", "other", "errors"));
3237
3238
        $id_journal = GETPOSTINT('id_journal');
3239
        $action = GETPOST('action', 'aZ09');
3240
3241
        $date_startmonth = GETPOST('date_startmonth');
3242
        $date_startday = GETPOST('date_startday');
3243
        $date_startyear = GETPOST('date_startyear');
3244
        $date_endmonth = GETPOST('date_endmonth');
3245
        $date_endday = GETPOST('date_endday');
3246
        $date_endyear = GETPOST('date_endyear');
3247
        $in_bookkeeping = GETPOST('in_bookkeeping');
3248
        if ($in_bookkeeping == '') {
3249
            $in_bookkeeping = 'notyet';
3250
        }
3251
3252
// Get information of journal
3253
        $object = new AccountingJournal($db);
3254
        $result = $object->fetch($id_journal);
3255
        if ($result > 0) {
3256
            $id_journal = $object->id;
3257
        } elseif ($result < 0) {
3258
            dol_print_error(null, $object->error, $object->errors);
3259
        } elseif ($result == 0) {
3260
            accessforbidden('ErrorRecordNotFound');
3261
        }
3262
3263
        $hookmanager->initHooks(array('globaljournal', $object->nature . 'journal'));
3264
        $parameters = array();
3265
3266
        $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
3267
        $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
3268
3269
        if (empty($date_startmonth)) {
3270
            // Period by default on transfer
3271
            $dates = getDefaultDatesForTransfer();
3272
            $date_start = $dates['date_start'];
3273
            $pastmonthyear = $dates['pastmonthyear'];
3274
            $pastmonth = $dates['pastmonth'];
3275
        }
3276
        if (empty($date_endmonth)) {
3277
            // Period by default on transfer
3278
            $dates = getDefaultDatesForTransfer();
3279
            $date_end = $dates['date_end'];
3280
            $pastmonthyear = $dates['pastmonthyear'];
3281
            $pastmonth = $dates['pastmonth'];
3282
        }
3283
3284
        if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
3285
            $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
3286
            $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
3287
        }
3288
3289
        $data_type = 'view';
3290
        if ($action == 'writebookkeeping') {
3291
            $data_type = 'bookkeeping';
3292
        }
3293
        if ($action == 'exportcsv') {
3294
            $data_type = 'csv';
3295
        }
3296
        $journal_data = $object->getData($user, $data_type, $date_start, $date_end, $in_bookkeeping);
3297
        if (!is_array($journal_data)) {
3298
            setEventMessages($object->error, $object->errors, 'errors');
3299
        }
3300
3301
// Security check
3302
        if (!isModEnabled('accounting')) {
3303
            accessforbidden();
3304
        }
3305
        if ($user->socid > 0) {
3306
            accessforbidden();
3307
        }
3308
        if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
3309
            accessforbidden();
3310
        }
3311
3312
3313
        /*
3314
         * Actions
3315
         */
3316
3317
        $reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks
3318
3319
        $reload = false;
3320
3321
// Bookkeeping Write
3322
        if ($action == 'writebookkeeping') {
3323
            $error = 0;
3324
3325
            $result = $object->writeIntoBookkeeping($user, $journal_data);
3326
            if ($result < 0) {
3327
                setEventMessages($object->error, $object->errors, 'errors');
3328
                $error = abs($result);
3329
            }
3330
3331
            $nb_elements = count($journal_data);
3332
            if (empty($error) && $nb_elements > 0) {
3333
                setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
3334
            } elseif ($nb_elements == $error) {
3335
                setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
3336
            } else {
3337
                setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
3338
            }
3339
3340
            $reload = true;
3341
        } elseif ($action == 'exportcsv') {
3342
            // Export CSV
3343
            $result = $object->exportCsv($journal_data, $date_end);
3344
            if ($result < 0) {
3345
                setEventMessages($object->error, $object->errors, 'errors');
3346
                $reload = true;
3347
            } else {
3348
                $filename = 'journal';
3349
                $type_export = 'journal';
3350
3351
                require_once BASE_PATH . '/../Dolibarr/Lib/Date.php';
3352
                include DOL_DOCUMENT_ROOT . '/accountancy/tpl/export_journal.tpl.php';
3353
3354
                print $result;
3355
3356
                $db->close();
3357
                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...
3358
            }
3359
        }
3360
3361
// Must reload data, so we make a redirect
3362
        if ($reload) {
3363
            $param = 'id_journal=' . $id_journal;
3364
            $param .= '&date_startday=' . $date_startday;
3365
            $param .= '&date_startmonth=' . $date_startmonth;
3366
            $param .= '&date_startyear=' . $date_startyear;
3367
            $param .= '&date_endday=' . $date_endday;
3368
            $param .= '&date_endmonth=' . $date_endmonth;
3369
            $param .= '&date_endyear=' . $date_endyear;
3370
            $param .= '&in_bookkeeping=' . $in_bookkeeping;
3371
            header("Location: " . $_SERVER['PHP_SELF'] . ($param ? '?' . $param : ''));
3372
            exit;
3373
        }
3374
3375
        /*
3376
         * View
3377
         */
3378
        require_once realpath(BASE_PATH . '/../Dolibarr/Modules/Accounting/Views/journal_variousjournal.php');
3379
3380
        $db->close();
3381
        return true;
3382
    }
3383
}
3384