dolibarr 22.0.5
bankjournal.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2010 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2007-2010 Jean Heimburger <jean@tiaris.info>
4 * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
5 * Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
7 * Copyright (C) 2013-2022 Open-DSI <support@open-dsi.fr>
8 * Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
9 * Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
10 * Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
11 * Copyright (C) 2017-2025 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
13 * Copyright (C) 2018-2024 Eric Seigne <eric.seigne@cap-rel.fr>
14 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
15 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
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
36require '../../main.inc.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
41require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
42require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
43require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
44require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
45require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
46require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php';
47require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
48require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
49require_once DOL_DOCUMENT_ROOT.'/don/class/paymentdonation.class.php';
50require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php';
51require_once DOL_DOCUMENT_ROOT.'/salaries/class/paymentsalary.class.php';
52require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
53require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
54require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
55require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
56require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
57require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
58require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
59require_once DOL_DOCUMENT_ROOT.'/expensereport/class/paymentexpensereport.class.php';
60require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/paymentvarious.class.php';
61require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
62require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php';
63require_once DOL_DOCUMENT_ROOT.'/loan/class/paymentloan.class.php';
64require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
65
74// Load translation files required by the page
75$langs->loadLangs(array("companies", "other", "compta", "banks", "bills", "donations", "loan", "accountancy", "trips", "salaries", "hrm", "members"));
76
77// Multi journal
78$id_journal = GETPOSTINT('id_journal');
79
80$date_startmonth = GETPOSTINT('date_startmonth');
81$date_startday = GETPOSTINT('date_startday');
82$date_startyear = GETPOSTINT('date_startyear');
83$date_endmonth = GETPOSTINT('date_endmonth');
84$date_endday = GETPOSTINT('date_endday');
85$date_endyear = GETPOSTINT('date_endyear');
86$in_bookkeeping = GETPOST('in_bookkeeping', 'aZ09');
87
88$only_rappro = GETPOSTINT('only_rappro');
89if ($only_rappro == 0) {
90 //GET page for the first time, use default settings
91 $only_rappro = getDolGlobalInt('ACCOUNTING_BANK_CONCILIATED');
92}
93
94$now = dol_now();
95
96$action = GETPOST('action', 'aZ09');
97
98if ($in_bookkeeping == '') {
99 $in_bookkeeping = 'notyet';
100}
101
102
103// Security check
104if (!isModEnabled('accounting')) {
106}
107if ($user->socid > 0) {
109}
110if (!$user->hasRight('accounting', 'bind', 'write')) {
112}
113
114
115/*
116 * Actions
117 */
118
119$error = 0;
120
121$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
122$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
123
124$pastmonth = null; // Initialise for static analysis (could be really unseg)
125$pastmonthyear = null;
126
127if (empty($date_startmonth)) {
128 // Period by default on transfer
130 $date_start = $dates['date_start'];
131 $pastmonthyear = $dates['pastmonthyear'];
132 $pastmonth = $dates['pastmonth'];
133}
134if (empty($date_endmonth)) {
135 // Period by default on transfer
137 $date_end = $dates['date_end'];
138 $pastmonthyear = $dates['pastmonthyear'];
139 $pastmonth = $dates['pastmonth'];
140}
141
142if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
143 $date_start = dol_get_first_day((int) $pastmonthyear, (int) $pastmonth, false);
144 $date_end = dol_get_last_day((int) $pastmonthyear, (int) $pastmonth, false);
145}
146
147// Get all bank lines
148//-------------------------------------
149$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,";
150$sql .= " ba.courant, ba.ref as baref, ba.account_number, ba.fk_accountancy_journal,";
151$sql .= " soc.rowid as socid, soc.nom as name, soc.email as email, bu1.type as typeop_company,";
152if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
153 $sql .= " spe.accountancy_code_customer_general,";
154 $sql .= " spe.accountancy_code_customer as code_compta_client,";
155 $sql .= " spe.accountancy_code_supplier_general,";
156 $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
157} else {
158 $sql .= " soc.accountancy_code_customer_general,";
159 $sql .= " soc.code_compta as code_compta_client,";
160 $sql .= " soc.accountancy_code_supplier_general,";
161 $sql .= " soc.code_compta_fournisseur,";
162}
163$sql .= " u.accountancy_code_user_general, u.accountancy_code, u.rowid as userid, u.lastname as lastname, u.firstname as firstname, u.email as useremail, u.statut as userstatus,";
164$sql .= " bu2.type as typeop_user,";
165$sql .= " bu3.type as typeop_payment, bu4.type as typeop_payment_supplier";
166$sql .= " FROM ".$db->prefix()."bank as b";
167$sql .= " JOIN ".$db->prefix()."bank_account as ba on b.fk_account = ba.rowid";
168$sql .= " LEFT JOIN ".$db->prefix()."bank_url as bu1 ON bu1.fk_bank = b.rowid AND bu1.type='company'";
169$sql .= " LEFT JOIN ".$db->prefix()."bank_url as bu2 ON bu2.fk_bank = b.rowid AND bu2.type='user'";
170$sql .= " LEFT JOIN ".$db->prefix()."bank_url as bu3 ON bu3.fk_bank = b.rowid AND bu3.type='payment'";
171$sql .= " LEFT JOIN ".$db->prefix()."bank_url as bu4 ON bu4.fk_bank = b.rowid AND bu4.type='payment_supplier'";
172$sql .= " LEFT JOIN ".$db->prefix()."societe as soc on bu1.url_id=soc.rowid";
173if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
174 $sql .= " LEFT JOIN " . $db->prefix() . "societe_perentity as spe ON spe.fk_soc = soc.rowid AND spe.entity = " . ((int) $conf->entity);
175}
176$sql .= " LEFT JOIN ".$db->prefix()."user as u on bu2.url_id=u.rowid";
177$sql .= " WHERE ba.fk_accountancy_journal=".((int) $id_journal);
178$sql .= " AND b.amount <> 0 AND ba.entity IN (".getEntity('bank_account', 0).")"; // We don't share object for accountancy
179if ($date_start && $date_end) {
180 $sql .= " AND b.dateo >= '".$db->idate($date_start)."' AND b.dateo <= '".$db->idate($date_end)."'";
181}
182// Define begin binding date
183if (getDolGlobalInt('ACCOUNTING_DATE_START_BINDING')) {
184 $sql .= " AND b.dateo >= '".$db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
185}
186// Already in bookkeeping or not
187if ($in_bookkeeping == 'already') {
188 $sql .= " AND (b.rowid IN (SELECT fk_doc FROM ".$db->prefix()."accounting_bookkeeping as ab WHERE ab.doc_type='bank') )";
189}
190if ($in_bookkeeping == 'notyet') {
191 $sql .= " AND (b.rowid NOT IN (SELECT fk_doc FROM ".$db->prefix()."accounting_bookkeeping as ab WHERE ab.doc_type='bank') )";
192}
193if ($only_rappro == 2) {
194 $sql .= " AND (b.rappro = '1')";
195}
196$sql .= " ORDER BY b.datev";
197//print $sql;
198
199$object = new Account($db);
200$paymentstatic = new Paiement($db);
201$paymentsupplierstatic = new PaiementFourn($db);
202$societestatic = new Societe($db);
203$userstatic = new User($db);
204$bankaccountstatic = new Account($db);
205$chargestatic = new ChargeSociales($db);
206$paymentdonstatic = new PaymentDonation($db);
207$paymentvatstatic = new Tva($db);
208$paymentsalstatic = new PaymentSalary($db);
209$paymentexpensereportstatic = new PaymentExpenseReport($db);
210$paymentvariousstatic = new PaymentVarious($db);
211$paymentloanstatic = new PaymentLoan($db);
212$accountLinestatic = new AccountLine($db);
213$paymentsubscriptionstatic = new Subscription($db);
214
215$tmppayment = new Paiement($db);
216$tmpinvoice = new Facture($db);
217
218$accountingaccount = new AccountingAccount($db);
219$account_transfer = 'NotDefined'; // For static analysis, NotDefined is a reserved word
220
221// Get code of finance journal
222$accountingjournalstatic = new AccountingJournal($db);
223$accountingjournalstatic->fetch($id_journal);
224$journal = $accountingjournalstatic->code;
225$journal_label = $accountingjournalstatic->label;
226
227$tabcompany = array();
228$tabuser = array();
229$tabpay = array();
230$tabbq = array();
231$tabtp = array();
232$tabtype = array();
233$tabmoreinfo = array();
234
235'
236@phan-var-force array<array{id:mixed,name:mixed,code_compta_client:string,email:string}> $tabcompany
237@phan-var-force array<array{id:int,name:string,lastname:string,firstname:string,email:string,accountancy_code:string,status:int> $tabuser
238@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
239@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
240';
241
242$account_customer = 'NotDefined';
243$account_supplier = 'NotDefined';
244$account_employee = 'NotDefined';
245
246//print $sql;
247dol_syslog("accountancy/journal/bankjournal.php", LOG_DEBUG);
248$result = $db->query($sql);
249if ($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_expensereport = getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT', 'NotDefined'); // NotDefined is a reserved word
258 $account_pay_vat = getDolGlobalString('ACCOUNTING_VAT_PAY_ACCOUNT', 'NotDefined'); // NotDefined is a reserved word
259 $account_pay_donation = getDolGlobalString('DONATION_ACCOUNTINGACCOUNT', 'NotDefined'); // NotDefined is a reserved word
260 $account_pay_subscription = getDolGlobalString('ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT', 'NotDefined'); // NotDefined is a reserved word
261 $account_transfer = getDolGlobalString('ACCOUNTING_ACCOUNT_TRANSFER_CASH', 'NotDefined'); // NotDefined is a reserved word
262
263 // Loop on each line into the llx_bank table. For each line, we should get:
264 // one line tabpay = line into bank
265 // one line for bank record = tabbq
266 // one line for thirdparty record = tabtp
267 // Note: tabcompany is used to store the subledger account
268 $i = 0;
269 while ($i < $num) {
270 $obj = $db->fetch_object($result);
271
272 $lineisapurchase = -1;
273 $lineisasale = -1;
274 // Old method to detect if it's a sale or purchase
275 if ($obj->label == '(SupplierInvoicePayment)' || $obj->label == '(SupplierInvoicePaymentBack)') {
276 $lineisapurchase = 1;
277 }
278 if ($obj->label == '(CustomerInvoicePayment)' || $obj->label == '(CustomerInvoicePaymentBack)') {
279 $lineisasale = 1;
280 }
281 // Try a more reliable method to detect if record is a supplier payment or a customer payment
282 if ($lineisapurchase < 0) {
283 if ($obj->typeop_payment_supplier == 'payment_supplier') {
284 $lineisapurchase = 1;
285 }
286 }
287 if ($lineisasale < 0) {
288 if ($obj->typeop_payment == 'payment') {
289 $lineisasale = 1;
290 }
291 }
292 //var_dump($obj->type_payment); //var_dump($obj->type_payment_supplier);
293 //var_dump($lineisapurchase); //var_dump($lineisasale);
294
295 // Set accountancy code for bank
296 $compta_bank = $obj->account_number;
297
298 // Set accountancy code for thirdparty (example: '411CU...' or '411' if no subledger account defined on customer)
299 $compta_soc = 'NotDefined';
300 $accountancy_code_general = 'NotDefined';
301 if ($lineisapurchase > 0) {
302 $accountancy_code_general = (!empty($obj->accountancy_code_supplier_general) && $obj->accountancy_code_supplier_general != '-1') ? $obj->accountancy_code_supplier_general : $account_supplier;
303 $compta_soc = (($obj->code_compta_fournisseur != "") ? $obj->code_compta_fournisseur : $account_supplier);
304 }
305 if ($lineisasale > 0) {
306 $accountancy_code_general = (!empty($obj->accountancy_code_customer_general) && $obj->accountancy_code_customer_general != '-1') ? $obj->accountancy_code_customer_general : $account_customer;
307 $compta_soc = (!empty($obj->code_compta_client) ? $obj->code_compta_client : $account_customer);
308 }
309
310 $tabcompany[$obj->rowid] = array(
311 'id' => $obj->socid,
312 'name' => $obj->name,
313 'code_compta' => $compta_soc,
314 'accountancy_code_general' => $accountancy_code_general,
315 'email' => $obj->email
316 );
317
318 // Set accountancy code for user
319 // $obj->accountancy_code is the accountancy_code of table u=user (but it is defined only if
320 // a link with type 'user' exists and user as a subledger account)
321 $accountancy_code_user_general = (!empty($obj->accountancy_code_user_general)) ? $obj->accountancy_code_user_general : $account_employee;
322 $compta_user = (!empty($obj->accountancy_code) ? $obj->accountancy_code : '');
323
324 $tabuser[$obj->rowid] = array(
325 'id' => $obj->userid,
326 'name' => dolGetFirstLastname($obj->firstname, $obj->lastname),
327 'lastname' => $obj->lastname,
328 'firstname' => $obj->firstname,
329 'email' => $obj->useremail,
330 'accountancy_code_general' => $accountancy_code_user_general,
331 'accountancy_code' => $compta_user,
332 'status' => $obj->userstatus
333 );
334
335 // Variable bookkeeping ($obj->rowid is Bank Id)
336 $tabpay[$obj->rowid]["date"] = $db->jdate($obj->do);
337 $tabpay[$obj->rowid]["type_payment"] = $obj->fk_type; // CHQ, VIR, LIQ, CB, ...
338 $tabpay[$obj->rowid]["ref"] = $obj->label; // By default. Not unique. May be changed later
339 $tabpay[$obj->rowid]["fk_bank"] = $obj->rowid;
340 $tabpay[$obj->rowid]["bank_account_ref"] = $obj->baref;
341 $tabpay[$obj->rowid]["fk_bank_account"] = $obj->fk_account;
342 $reg = array();
343 if (preg_match('/^\‍((.*)\‍)$/i', $obj->label, $reg)) {
344 $tabpay[$obj->rowid]["lib"] = $langs->trans($reg[1]);
345 } else {
346 $tabpay[$obj->rowid]["lib"] = dol_trunc($obj->label, 60);
347 }
348
349 // Load of url links to the line into llx_bank (so load llx_bank_url)
350 $links = $object->get_url($obj->rowid); // Get an array('url'=>, 'url_id'=>, 'label'=>, 'type'=> 'fk_bank'=> )
351 // print '<p>' . json_encode($object) . "</p>";//exit;
352 // print '<p>' . json_encode($links) . "</p>";//exit;
353
354 // By default
355 $tabpay[$obj->rowid]['type'] = 'unknown'; // Can be SOLD, miscellaneous entry, payment of patient, or any old record with no links in bank_url.
356 $tabtype[$obj->rowid] = 'unknown';
357 $tabmoreinfo[$obj->rowid] = array();
358
359 $amounttouse = $obj->amount;
360 if (!empty($obj->amount_main_currency)) {
361 // If $obj->amount_main_currency is set, it means that $obj->amount is not in same currency, we must use $obj->amount_main_currency
362 $amounttouse = $obj->amount_main_currency;
363 }
364
365 // get_url may return -1 which is not traversable
366 if (is_array($links) && count($links) > 0) {
367 // Test if entry is for a social contribution, salary or expense report.
368 // In such a case, we will ignore the bank url line for user
369 $is_sc = false;
370 $is_salary = false;
371 $is_expensereport = false;
372 foreach ($links as $v) {
373 if ($v['type'] == 'sc') {
374 $is_sc = true;
375 break;
376 }
377 if ($v['type'] == 'payment_salary') {
378 $is_salary = true;
379 break;
380 }
381 if ($v['type'] == 'payment_expensereport') {
382 $is_expensereport = true;
383 break;
384 }
385 }
386
387 // Now loop on each link of record in bank (code similar to bankentries_list.php)
388 foreach ($links as $key => $val) {
389 if ($links[$key]['type'] == 'user' && !$is_sc && !$is_salary && !$is_expensereport) {
390 // We must avoid as much as possible this "continue". If we want to jump to next loop, it means we don't want to process
391 // the case the link is user (often because managed by hard coded code into another link), and we must avoid this.
392 continue;
393 }
394 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'))) {
395 // So we excluded 'company' and 'user' here. We want only payment lines
396
397 // We save tabtype for a future use, to remember what kind of payment it is
398 $tabpay[$obj->rowid]['type'] = $links[$key]['type'];
399 $tabtype[$obj->rowid] = $links[$key]['type'];
400 /* phpcs:disable -- Code does nothing at this moment -> commented
401 } elseif (in_array($links[$key]['type'], array('company', 'user'))) {
402 if ($tabpay[$obj->rowid]['type'] == 'unknown') {
403 // We can guess here it is a bank record for a thirdparty company or a user.
404 // 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.
405 }
406 */ // phpcs::enable
407 }
408
409 // Special case to ask later to add more request to get information for old links without company link.
410 if ($links[$key]['type'] == 'withdraw') {
411 $tabmoreinfo[$obj->rowid]['withdraw'] = 1;
412 }
413
414 if ($links[$key]['type'] == 'payment') {
415 $paymentstatic->id = $links[$key]['url_id'];
416 $paymentstatic->ref = (string) $links[$key]['url_id'];
417 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentstatic->getNomUrl(2, '', ''); // TODO Do not include list of invoice in tooltip, the dol_string_nohtmltag is ko with this
418 $tabpay[$obj->rowid]["paymentid"] = $paymentstatic->id;
419 } elseif ($links[$key]['type'] == 'payment_supplier') {
420 $paymentsupplierstatic->id = $links[$key]['url_id'];
421 $paymentsupplierstatic->ref = (string) $links[$key]['url_id'];
422 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsupplierstatic->getNomUrl(2);
423 $tabpay[$obj->rowid]["paymentsupplierid"] = $paymentsupplierstatic->id;
424 } elseif ($links[$key]['type'] == 'company') {
425 $societestatic->id = $links[$key]['url_id'];
426 $societestatic->name = $links[$key]['label'];
427 $societestatic->email = $tabcompany[$obj->rowid]['email'];
428 $tabpay[$obj->rowid]["soclib"] = $societestatic->getNomUrl(1, '', 30);
429 if ($compta_soc) {
430 if (empty($tabtp[$obj->rowid][$compta_soc])) {
431 $tabtp[$obj->rowid][$compta_soc] = $amounttouse;
432 } else {
433 $tabtp[$obj->rowid][$compta_soc] += $amounttouse;
434 }
435 }
436 } elseif ($links[$key]['type'] == 'user') {
437 $userstatic->id = $links[$key]['url_id'];
438 $userstatic->name = $links[$key]['label'];
439 $userstatic->email = $tabuser[$obj->rowid]['email'];
440 $userstatic->firstname = $tabuser[$obj->rowid]['firstname'];
441 $userstatic->lastname = $tabuser[$obj->rowid]['lastname'];
442 $userstatic->status = $tabuser[$obj->rowid]['status'];
443 $userstatic->accountancy_code_user_general = $tabuser[$obj->rowid]['accountancy_code_general'];
444 $userstatic->accountancy_code = $tabuser[$obj->rowid]['accountancy_code'];
445
446 // For a payment of social contribution, we have a link sc + user.
447 // but we already fill the $tabpay[$obj->rowid]["soclib"] in the line 'sc'.
448 // If we fill it here to, we must concat.
449 if ($userstatic->id > 0) {
450 if ($is_sc) {
451 $tabpay[$obj->rowid]["soclib"] .= ' '.$userstatic->getNomUrl(-1, 'accountancy', 0);
452 } else {
453 $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(-1, 'accountancy', 0);
454 }
455 } else {
456 $tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen, but happens with old data when id of user was not saved on expense report payment.
457 }
458
459 if ($compta_user) {
460 if ($is_sc) {
461 //$tabcompany[$obj->rowid][$compta_user] += $amounttouse;
462 } else {
463 $tabtp[$obj->rowid][$compta_user] += $amounttouse;
464 }
465 }
466 } elseif ($links[$key]['type'] == 'sc') {
467 $chargestatic->id = $links[$key]['url_id'];
468 $chargestatic->ref = (string) $links[$key]['url_id'];
469
470 $tabpay[$obj->rowid]["lib"] .= ' '.$chargestatic->getNomUrl(2);
471 $reg = array();
472 if (preg_match('/^\‍((.*)\‍)$/i', $links[$key]['label'], $reg)) {
473 if ($reg[1] == 'socialcontribution') {
474 $reg[1] = 'SocialContribution';
475 }
476 $chargestatic->label = $langs->trans($reg[1]);
477 } else {
478 $chargestatic->label = $links[$key]['label'];
479 }
480 $chargestatic->ref = $chargestatic->label;
481
482 // Retrieve the accounting code of the social contribution of the payment from link of payment.
483 // Note: We have the social contribution id, it can be faster to get accounting code from social contribution id.
484 /*
485 $sqlmid = "SELECT cchgsoc.accountancy_code";
486 $sqlmid .= " FROM ".MAIN_DB_PREFIX."c_chargesociales cchgsoc";
487 $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."chargesociales as chgsoc ON chgsoc.fk_type = cchgsoc.id";
488 $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."paiementcharge as paycharg ON paycharg.fk_charge = chgsoc.rowid";
489 $sqlmid .= " INNER JOIN ".MAIN_DB_PREFIX."bank_url as bkurl ON bkurl.url_id=paycharg.rowid AND bkurl.type = 'payment_sc'";
490 $sqlmid .= " WHERE bkurl.fk_bank = ".((int) $obj->rowid);
491
492 dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=".$sqlmid, LOG_DEBUG);
493 $resultmid = $db->query($sqlmid);
494 if ($resultmid) {
495 $objmid = $db->fetch_object($resultmid);
496 $tabtp[$obj->rowid][$objmid->accountancy_code] = isset($tabtp[$obj->rowid][$objmid->accountancy_code]) ? $tabtp[$obj->rowid][$objmid->accountancy_code] + $amounttouse : $amounttouse;
497 }*/
498 $tmpcharge = new ChargeSociales($db);
499 $resultmid = $tmpcharge->fetch($chargestatic->id);
500 if ($resultmid) {
501 $chargestatic->type_label = $tmpcharge->type_label;
502 $chargestatic->type_code = $tmpcharge->type_code;
503 $chargestatic->type_accountancy_code = $tmpcharge->type_accountancy_code;
504
505 $tabtp[$obj->rowid][$tmpcharge->type_accountancy_code] = isset($tabtp[$obj->rowid][$tmpcharge->type_accountancy_code]) ? $tabtp[$obj->rowid][$tmpcharge->type_accountancy_code] + $amounttouse : $amounttouse;
506 }
507
508 $tabpay[$obj->rowid]["soclib"] = $chargestatic->getNomUrl(1, '30');
509 $tabpay[$obj->rowid]["paymentscid"] = $chargestatic->id;
510 } elseif ($links[$key]['type'] == 'payment_donation') {
511 $paymentdonstatic->id = $links[$key]['url_id'];
512 $paymentdonstatic->ref = (string) $links[$key]['url_id'];
513 $paymentdonstatic->fk_donation = $links[$key]['url_id'];
514 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentdonstatic->getNomUrl(2);
515 $tabpay[$obj->rowid]["paymentdonationid"] = $paymentdonstatic->id;
516 $tabtp[$obj->rowid][$account_pay_donation] = isset($tabtp[$obj->rowid][$account_pay_donation]) ? $tabtp[$obj->rowid][$account_pay_donation] + $amounttouse : $amounttouse;
517 } elseif ($links[$key]['type'] == 'member') {
518 $paymentsubscriptionstatic->id = $links[$key]['url_id'];
519 $paymentsubscriptionstatic->ref = (string) $links[$key]['url_id'];
520 $paymentsubscriptionstatic->label = $links[$key]['label'];
521 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsubscriptionstatic->getNomUrl(2);
522 $tabpay[$obj->rowid]["paymentsubscriptionid"] = $paymentsubscriptionstatic->id;
523 $paymentsubscriptionstatic->fetch($paymentsubscriptionstatic->id);
524 $tabtp[$obj->rowid][$account_pay_subscription] = isset($tabtp[$obj->rowid][$account_pay_subscription]) ? $tabtp[$obj->rowid][$account_pay_subscription] + $amounttouse : $amounttouse;
525 } elseif ($links[$key]['type'] == 'payment_vat') { // Payment VAT
526 $paymentvatstatic->id = $links[$key]['url_id'];
527 $paymentvatstatic->ref = (string) $links[$key]['url_id'];
528 $paymentvatstatic->label = $links[$key]['label'];
529 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentvatstatic->getNomUrl(2);
530 $tabpay[$obj->rowid]["paymentvatid"] = $paymentvatstatic->id;
531 $tabtp[$obj->rowid][$account_pay_vat] = isset($tabtp[$obj->rowid][$account_pay_vat]) ? $tabtp[$obj->rowid][$account_pay_vat] + $amounttouse : $amounttouse;
532 } elseif ($links[$key]['type'] == 'payment_salary') {
533 $paymentsalstatic->id = $links[$key]['url_id'];
534 $paymentsalstatic->ref = (string) $links[$key]['url_id'];
535 $paymentsalstatic->label = $links[$key]['label'];
536 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsalstatic->getNomUrl(2);
537 $tabpay[$obj->rowid]["paymentsalid"] = $paymentsalstatic->id;
538
539 // 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.
540 // Note: A better way to fix this is to delete payment of salary and recreate it, or to fix the bookkeeping table manually after.
541 if (getDolGlobalString('ACCOUNTANCY_AUTOFIX_MISSING_LINK_TO_USER_ON_SALARY_BANK_PAYMENT')) {
542 $tmpsalary = new Salary($db);
543 $tmpsalary->fetch($paymentsalstatic->id);
544 $tmpsalary->fetch_user($tmpsalary->fk_user);
545
546 $userstatic->id = $tmpsalary->user->id;
547 $userstatic->name = $tmpsalary->user->name;
548 $userstatic->email = $tmpsalary->user->email;
549 $userstatic->firstname = $tmpsalary->user->firstname;
550 $userstatic->lastname = $tmpsalary->user->lastname;
551 $userstatic->status = $tmpsalary->user->status;
552 $userstatic->accountancy_code = $tmpsalary->user->accountancy_code;
553
554 if ($userstatic->id > 0) {
555 $tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0);
556 } else {
557 $tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen
558 }
559
560 if (empty($obj->typeop_user)) { // Add test to avoid adding amount twice if a link already exists also on user.
561 $accountancy_code_user_general = (!empty($obj->accountancy_code_user_general)) ? $obj->accountancy_code_user_general : $account_employee;
562 $compta_user = $userstatic->accountancy_code;
563 if ($compta_user) {
564 $tabtp[$obj->rowid][$compta_user] += $amounttouse;
565 $tabuser[$obj->rowid] = array(
566 'id' => $userstatic->id,
567 'name' => dolGetFirstLastname($userstatic->firstname, $userstatic->lastname),
568 'lastname' => $userstatic->lastname,
569 'firstname' => $userstatic->firstname,
570 'email' => $userstatic->email,
571 'accountancy_code_general' => $accountancy_code_user_general,
572 'accountancy_code' => $compta_user,
573 'status' => $userstatic->status
574 );
575 }
576 }
577 }
578 } elseif ($links[$key]['type'] == 'payment_expensereport') {
579 $paymentexpensereportstatic->id = $links[$key]['url_id'];
580 $tabpay[$obj->rowid]["lib"] .= $paymentexpensereportstatic->getNomUrl(2);
581 $tabpay[$obj->rowid]["paymentexpensereport"] = $paymentexpensereportstatic->id;
582 } elseif ($links[$key]['type'] == 'payment_various') {
583 $paymentvariousstatic->id = $links[$key]['url_id'];
584 $paymentvariousstatic->ref = (string) $links[$key]['url_id'];
585 $paymentvariousstatic->label = $links[$key]['label'];
586 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentvariousstatic->getNomUrl(2);
587 $tabpay[$obj->rowid]["paymentvariousid"] = $paymentvariousstatic->id;
588 $paymentvariousstatic->fetch($paymentvariousstatic->id);
589 $account_various = (!empty($paymentvariousstatic->accountancy_code) ? $paymentvariousstatic->accountancy_code : 'NotDefined'); // NotDefined is a reserved word
590 $account_subledger = (!empty($paymentvariousstatic->subledger_account) ? $paymentvariousstatic->subledger_account : ''); // NotDefined is a reserved word
591 $tabpay[$obj->rowid]["account_various"] = $account_various;
592 $tabtp[$obj->rowid][$account_subledger] = isset($tabtp[$obj->rowid][$account_subledger]) ? $tabtp[$obj->rowid][$account_subledger] + $amounttouse : $amounttouse;
593 } elseif ($links[$key]['type'] == 'payment_loan') {
594 $paymentloanstatic->id = $links[$key]['url_id'];
595 $paymentloanstatic->ref = (string) $links[$key]['url_id'];
596 $paymentloanstatic->fk_loan = $links[$key]['url_id'];
597 $tabpay[$obj->rowid]["lib"] .= ' '.$paymentloanstatic->getNomUrl(2);
598 $tabpay[$obj->rowid]["paymentloanid"] = $paymentloanstatic->id;
599 //$tabtp[$obj->rowid][$account_pay_loan] += $amounttouse;
600 $sqlmid = 'SELECT pl.amount_capital, pl.amount_insurance, pl.amount_interest, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest';
601 $sqlmid .= ' FROM '.MAIN_DB_PREFIX.'payment_loan as pl, '.MAIN_DB_PREFIX.'loan as l';
602 $sqlmid .= ' WHERE l.rowid = pl.fk_loan AND pl.fk_bank = '.((int) $obj->rowid);
603
604 dol_syslog("accountancy/journal/bankjournal.php:: sqlmid=".$sqlmid, LOG_DEBUG);
605 $resultmid = $db->query($sqlmid);
606 if ($resultmid) {
607 $objmid = $db->fetch_object($resultmid);
608 $tabtp[$obj->rowid][$objmid->accountancy_account_capital] = isset($objmid->amount_capital) ? ($tabtp[$obj->rowid][$objmid->accountancy_account_capital] ?? 0) - $objmid->amount_capital : 0;
609 $tabtp[$obj->rowid][$objmid->accountancy_account_insurance] = isset($objmid->amount_insurance) ? ($tabtp[$obj->rowid][$objmid->accountancy_account_insurance] ?? 0) - $objmid->amount_insurance : 0;
610 $tabtp[$obj->rowid][$objmid->accountancy_account_interest] = isset($objmid->amount_interest) ? ($tabtp[$obj->rowid][$objmid->accountancy_account_interest] ?? 0) - $objmid->amount_interest : 0;
611 }
612 } elseif ($links[$key]['type'] == 'banktransfert') {
613 $accountLinestatic->fetch($links[$key]['url_id']);
614 $tabpay[$obj->rowid]["lib"] .= ' '.$langs->trans("BankTransfer").' '.$accountLinestatic ->getNomUrl(1);
615 $tabtp[$obj->rowid][$account_transfer] = isset($tabtp[$obj->rowid][$account_transfer]) ? $tabtp[$obj->rowid][$account_transfer] + $amounttouse : $amounttouse;
616 $bankaccountstatic->fetch($tabpay[$obj->rowid]['fk_bank_account']);
617 $tabpay[$obj->rowid]["soclib"] = $bankaccountstatic->getNomUrl(2);
618 }
619 }
620 }
621
622 if (empty($tabbq[$obj->rowid][$compta_bank])) {
623 $tabbq[$obj->rowid][$compta_bank] = $amounttouse;
624 } else {
625 $tabbq[$obj->rowid][$compta_bank] += $amounttouse;
626 }
627
628 // If no links were found to know the amount on thirdparty, we try to guess it.
629 // This may happens on bank entries without the links lines to 'company'.
630 if (empty($tabtp[$obj->rowid]) && !empty($tabmoreinfo[$obj->rowid]['withdraw'])) { // If we don't find 'company' link because it is an old 'withdraw' record
631 foreach ($links as $key => $val) {
632 if ($links[$key]['type'] == 'payment') {
633 // Get thirdparty
634 $tmppayment->fetch($links[$key]['url_id']);
635 $arrayofamounts = $tmppayment->getAmountsArray();
636 if (is_array($arrayofamounts)) {
637 foreach ($arrayofamounts as $invoiceid => $amount) {
638 $tmpinvoice->fetch($invoiceid);
639 $tmpinvoice->fetch_thirdparty();
640 if ($tmpinvoice->thirdparty->code_compta_client) {
641 $tabtp[$obj->rowid][$tmpinvoice->thirdparty->code_compta_client] += $amount;
642 }
643 }
644 }
645 }
646 }
647 }
648
649 // If no links were found to know the amount on thirdparty/user, we init it to account 'NotDefined'.
650 if (empty($tabtp[$obj->rowid])) {
651 $tabtp[$obj->rowid]['NotDefined'] = $tabbq[$obj->rowid][$compta_bank];
652 }
653
654 // if($obj->socid)$tabtp[$obj->rowid][$compta_soc] += $amounttouse;
655
656 $i++;
657 }
658} else {
659 dol_print_error($db);
660}
661
662// Write bookkeeping
663if (!$error && $action == 'writebookkeeping' && $user->hasRight('accounting', 'bind', 'write')) {
664 $now = dol_now();
665
666 $accountingaccountcustomer = new AccountingAccount($db);
667 $accountingaccountcustomer->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER'), true);
668
669 $accountingaccountsupplier = new AccountingAccount($db);
670 $accountingaccountsupplier->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), true);
671
672 $accountingaccountpayment = new AccountingAccount($db);
673 $accountingaccountpayment->fetch(0, getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT'), true);
674
675 $accountingaccountexpensereport = new AccountingAccount($db);
676 $accountingaccountexpensereport->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT'), true);
677
678 $accountingaccountsuspense = new AccountingAccount($db);
679 $accountingaccountsuspense->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE'), true);
680
681 $error = 0;
682 foreach ($tabpay as $key => $val) { // $key is rowid into llx_bank
683 $date = dol_print_date($val["date"], 'day');
684
685 $ref = getSourceDocRef($val, $tabtype[$key]);
686
687 $errorforline = 0;
688
689 $totalcredit = 0;
690 $totaldebit = 0;
691
692 $db->begin();
693
694 // Introduce a protection. Total of tabtp must be total of tabbq
695
696 // Bank
697 if (is_array($tabbq[$key])) {
698 // Line into bank account
699 foreach ($tabbq[$key] as $k => $mt) {
700 if ($mt) {
701 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
702 $accountingaccount = new AccountingAccount($db);
703 $accountingaccount->fetch(0, $k, true); // $k is accounting account of the bank.
704 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
705 } else {
706 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
707 }
708
709 $account_label = $accountingaccount->label;
710
711 $reflabel = '';
712 if (!empty($val['lib'])) {
713 $reflabel .= dol_string_nohtmltag($val['lib'])." / ";
714 }
715 $reflabel .= $langs->trans("Bank").' '.dol_string_nohtmltag($val['bank_account_ref']);
716 if (!empty($val['soclib'])) {
717 $reflabel .= " / ".dol_string_nohtmltag($val['soclib']);
718 }
719
720 $bookkeeping = new BookKeeping($db);
721 $bookkeeping->doc_date = $val["date"];
722 $bookkeeping->doc_ref = $ref;
723 $bookkeeping->doc_type = 'bank';
724 $bookkeeping->fk_doc = $key;
725 $bookkeeping->fk_docdet = $val["fk_bank"];
726
727 $bookkeeping->numero_compte = $k;
728 $bookkeeping->label_compte = $account_label;
729
730 $bookkeeping->label_operation = $reflabel;
731 $bookkeeping->montant = $mt;
732 $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
733 $bookkeeping->debit = ($mt >= 0 ? $mt : 0);
734 $bookkeeping->credit = ($mt < 0 ? -$mt : 0);
735 $bookkeeping->code_journal = $journal;
736 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
737 $bookkeeping->fk_user_author = $user->id;
738 $bookkeeping->date_creation = $now;
739
740 // No subledger_account value for the bank line but add a specific label_operation
741 $bookkeeping->subledger_account = '';
742 $bookkeeping->label_operation = $reflabel;
743 $bookkeeping->entity = $conf->entity;
744
745 $totaldebit += $bookkeeping->debit;
746 $totalcredit += $bookkeeping->credit;
747
748 $result = $bookkeeping->create($user);
749 if ($result < 0) {
750 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
751 $error++;
752 $errorforline++;
753 setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
754 } else {
755 $error++;
756 $errorforline++;
757 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
758 }
759 }
760 }
761 }
762 }
763
764 // Third party
765 if (!$errorforline) {
766 if (is_array($tabtp[$key])) {
767 // Line into thirdparty account
768 foreach ($tabtp[$key] as $k => $mt) {
769 if ($mt) {
770 $lettering = false;
771
772 $reflabel = '';
773 if (!empty($val['lib'])) {
774 $reflabel .= dol_string_nohtmltag($val['lib']).(!empty($val['soclib']) ? " / " : "");
775 }
776 if ($tabtype[$key] == 'banktransfert') {
777 $reflabel .= dol_string_nohtmltag($langs->transnoentitiesnoconv('TransitionalAccount').' '.$account_transfer);
778 } else {
779 $reflabel .= dol_string_nohtmltag($val['soclib'] ?? '');
780 }
781
782 $bookkeeping = new BookKeeping($db);
783 $bookkeeping->doc_date = $val["date"];
784 $bookkeeping->doc_ref = $ref;
785 $bookkeeping->doc_type = 'bank';
786 $bookkeeping->fk_doc = $key;
787 $bookkeeping->fk_docdet = $val["fk_bank"];
788
789 $bookkeeping->label_operation = $reflabel;
790 $bookkeeping->montant = $mt;
791 $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
792 $bookkeeping->debit = ($mt < 0 ? -$mt : 0);
793 $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
794 $bookkeeping->code_journal = $journal;
795 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
796 $bookkeeping->fk_user_author = $user->id;
797 $bookkeeping->date_creation = $now;
798
799 if ($tabtype[$key] == 'payment') { // If payment is payment of customer invoice, we get ref of invoice
800 $lettering = true;
801 $bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
802 $bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
803 $bookkeeping->numero_compte = $tabcompany[$key]['accountancy_code_general'];
804 $bookkeeping->label_compte = $accountingaccountcustomer->label;
805 } elseif ($tabtype[$key] == 'payment_supplier') { // If payment is payment of supplier invoice, we get ref of invoice
806 $lettering = true;
807 $bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
808 $bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
809 $bookkeeping->numero_compte = $tabcompany[$key]['accountancy_code_general'];
810 $bookkeeping->label_compte = $accountingaccountsupplier->label;
811 } elseif ($tabtype[$key] == 'payment_expensereport') {
812 $bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
813 $bookkeeping->subledger_label = $tabuser[$key]['name'];
814 $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT');
815 $bookkeeping->label_compte = $accountingaccountexpensereport->label;
816 } elseif ($tabtype[$key] == 'payment_salary') {
817 $bookkeeping->subledger_account = $tabuser[$key]['accountancy_code'];
818 $bookkeeping->subledger_label = $tabuser[$key]['name'];
819 $bookkeeping->numero_compte = $tabuser[$key]['accountancy_code_general'];
820 $bookkeeping->label_compte = $accountingaccountpayment->label;
821 } elseif (in_array($tabtype[$key], array('sc', 'payment_sc'))) { // If payment is payment of social contribution
822 $bookkeeping->subledger_account = '';
823 $bookkeeping->subledger_label = '';
824 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
825 $accountingaccount = new AccountingAccount($db);
826 $accountingaccount->fetch(0, $k, true);
827 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
828 } else {
829 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
830 }
831 $bookkeeping->numero_compte = $k;
832 $bookkeeping->label_compte = $accountingaccount->label;
833 } elseif ($tabtype[$key] == 'payment_vat') {
834 $bookkeeping->subledger_account = '';
835 $bookkeeping->subledger_label = '';
836 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
837 $accountingaccount = new AccountingAccount($db);
838 $accountingaccount->fetch(0, $k, true);
839 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
840 } else {
841 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
842 }
843 $bookkeeping->numero_compte = $k;
844 $bookkeeping->label_compte = $accountingaccount->label;
845 } elseif ($tabtype[$key] == 'payment_donation') {
846 $bookkeeping->subledger_account = '';
847 $bookkeeping->subledger_label = '';
848 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
849 $accountingaccount = new AccountingAccount($db);
850 $accountingaccount->fetch(0, $k, true);
851 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
852 } else {
853 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
854 }
855 $bookkeeping->numero_compte = $k;
856 $bookkeeping->label_compte = $accountingaccount->label;
857 } elseif ($tabtype[$key] == 'member') {
858 $bookkeeping->subledger_account = '';
859 $bookkeeping->subledger_label = '';
860 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
861 $accountingaccount = new AccountingAccount($db);
862 $accountingaccount->fetch(0, $k, true);
863 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
864 } else {
865 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
866 }
867 $bookkeeping->numero_compte = $k;
868 $bookkeeping->label_compte = $accountingaccount->label;
869 } elseif ($tabtype[$key] == 'payment_loan') {
870 $bookkeeping->subledger_account = '';
871 $bookkeeping->subledger_label = '';
872 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
873 $accountingaccount = new AccountingAccount($db);
874 $accountingaccount->fetch(0, $k, true);
875 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
876 } else {
877 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
878 }
879 $bookkeeping->numero_compte = $k;
880 $bookkeeping->label_compte = $accountingaccount->label;
881 } elseif ($tabtype[$key] == 'payment_various') {
882 $bookkeeping->subledger_account = $k;
883 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
884 if (empty($conf->cache['accountingaccountincurrententity'][$tabpay[$key]["account_various"]])) {
885 $accountingaccount = new AccountingAccount($db);
886 $accountingaccount->fetch(0, $tabpay[$key]["account_various"], true);
887 $conf->cache['accountingaccountincurrententity'][$tabpay[$key]["account_various"]] = $accountingaccount;
888 } else {
889 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$tabpay[$key]["account_various"]];
890 }
891 $bookkeeping->numero_compte = $tabpay[$key]["account_various"];
892 $bookkeeping->label_compte = $accountingaccount->label;
893 } elseif ($tabtype[$key] == 'banktransfert') {
894 $bookkeeping->subledger_account = '';
895 $bookkeeping->subledger_label = '';
896 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
897 $accountingaccount = new AccountingAccount($db);
898 $accountingaccount->fetch(0, $k, true);
899 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
900 } else {
901 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
902 }
903 $bookkeeping->numero_compte = $k;
904 $bookkeeping->label_compte = $accountingaccount->label;
905 } else {
906 if ($tabtype[$key] == 'unknown') { // Unknown transaction, we will use a waiting account for thirdparty.
907 // Temporary account
908 $bookkeeping->subledger_account = '';
909 $bookkeeping->subledger_label = '';
910 $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE');
911 $bookkeeping->label_compte = $accountingaccountsuspense->label;
912 }
913 }
914 $bookkeeping->label_operation = $reflabel;
915 $bookkeeping->entity = $conf->entity;
916
917 $totaldebit += $bookkeeping->debit;
918 $totalcredit += $bookkeeping->credit;
919
920 $result = $bookkeeping->create($user);
921 if ($result < 0) {
922 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
923 $error++;
924 $errorforline++;
925 setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
926 } else {
927 $error++;
928 $errorforline++;
929 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
930 }
931 } else {
932 if ($lettering && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
933 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
934 $lettering_static = new Lettering($db);
935 $nb_lettering = $lettering_static->bookkeepingLetteringAll(array($bookkeeping->id));
936 }
937 }
938 }
939 }
940 } else { // If thirdparty unknown, output the waiting account
941 foreach ($tabbq[$key] as $k => $mt) {
942 if ($mt) {
943 $reflabel = '';
944 if (!empty($val['lib'])) {
945 $reflabel .= dol_string_nohtmltag($val['lib'])." / ";
946 }
947 $reflabel .= dol_string_nohtmltag('WaitingAccount');
948
949 $bookkeeping = new BookKeeping($db);
950 $bookkeeping->doc_date = $val["date"];
951 $bookkeeping->doc_ref = $ref;
952 $bookkeeping->doc_type = 'bank';
953 $bookkeeping->fk_doc = $key;
954 $bookkeeping->fk_docdet = $val["fk_bank"];
955 $bookkeeping->montant = $mt;
956 $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
957 $bookkeeping->debit = ($mt < 0 ? -$mt : 0);
958 $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
959 $bookkeeping->code_journal = $journal;
960 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
961 $bookkeeping->fk_user_author = $user->id;
962 $bookkeeping->date_creation = $now;
963 $bookkeeping->label_compte = '';
964 $bookkeeping->label_operation = $reflabel;
965 $bookkeeping->entity = $conf->entity;
966
967 $totaldebit += $bookkeeping->debit;
968 $totalcredit += $bookkeeping->credit;
969
970 $result = $bookkeeping->create($user);
971
972 if ($result < 0) {
973 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
974 $error++;
975 $errorforline++;
976 setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
977 } else {
978 $error++;
979 $errorforline++;
980 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
981 }
982 }
983 }
984 }
985 }
986 }
987
988 if (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT')) {
989 $error++;
990 $errorforline++;
991 setEventMessages('We tried to insert a non balanced transaction in book for '.$ref.'. Canceled. Surely a bug.', null, 'errors');
992 }
993
994 if (!$errorforline) {
995 $db->commit();
996 } else {
997 //print 'KO for line '.$key.' '.$error.'<br>';
998 $db->rollback();
999
1000 $MAXNBERRORS = 5;
1001 if ($error >= $MAXNBERRORS) {
1002 setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped").' (>'.$MAXNBERRORS.')', null, 'errors');
1003 break; // Break in the foreach
1004 }
1005 }
1006 }
1007
1008 if (empty($error) && count($tabpay) > 0) {
1009 setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
1010 } elseif (count($tabpay) == $error) {
1011 setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
1012 } else {
1013 setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
1014 }
1015
1016 $action = '';
1017
1018 // Must reload data, so we make a redirect
1019 if (count($tabpay) != $error) {
1020 $param = 'id_journal='.$id_journal;
1021 $param .= '&date_startday='.$date_startday;
1022 $param .= '&date_startmonth='.$date_startmonth;
1023 $param .= '&date_startyear='.$date_startyear;
1024 $param .= '&date_endday='.$date_endday;
1025 $param .= '&date_endmonth='.$date_endmonth;
1026 $param .= '&date_endyear='.$date_endyear;
1027 $param .= '&in_bookkeeping='.$in_bookkeeping;
1028 header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
1029 exit;
1030 }
1031}
1032
1033
1034
1035// Export
1036if ($action == 'exportcsv' && $user->hasRight('accounting', 'bind', 'write')) { // ISO and not UTF8 !
1037 $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
1038
1039 $filename = 'journal';
1040 $type_export = 'journal';
1041 include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
1042
1043 // CSV header line
1044 print '"'.$langs->transnoentitiesnoconv("BankId").'"'.$sep;
1045 print '"'.$langs->transnoentitiesnoconv("Date").'"'.$sep;
1046 print '"'.$langs->transnoentitiesnoconv("PaymentMode").'"'.$sep;
1047 print '"'.$langs->transnoentitiesnoconv("AccountAccounting").'"'.$sep;
1048 print '"'.$langs->transnoentitiesnoconv("SubledgerAccount").'"'.$sep;
1049 print '"'.$langs->transnoentitiesnoconv("Label").'"'.$sep;
1050 print '"'.$langs->transnoentitiesnoconv("AccountingDebit").'"'.$sep;
1051 print '"'.$langs->transnoentitiesnoconv("AccountingCredit").'"'.$sep;
1052 print '"'.$langs->transnoentitiesnoconv("Journal").'"'.$sep;
1053 print '"'.$langs->transnoentitiesnoconv("Note").'"'.$sep;
1054 print "\n";
1055
1056 foreach ($tabpay as $key => $val) {
1057 $date = dol_print_date($val["date"], 'day');
1058
1059 $ref = getSourceDocRef($val, $tabtype[$key]);
1060
1061 // Bank
1062 foreach ($tabbq[$key] as $k => $mt) {
1063 if ($mt) {
1064 $reflabel = '';
1065 if (!empty($val['lib'])) {
1066 $reflabel .= dol_string_nohtmltag($val['lib'])." / ";
1067 }
1068 $reflabel .= $langs->trans("Bank").' '.dol_string_nohtmltag($val['bank_account_ref']);
1069 if (!empty($val['soclib'])) {
1070 $reflabel .= " / ".dol_string_nohtmltag($val['soclib']);
1071 }
1072
1073 print '"'.$key.'"'.$sep;
1074 print '"'.$date.'"'.$sep;
1075 print '"'.$val["type_payment"].'"'.$sep;
1076 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1077 print " ".$sep;
1078 print '"'.$reflabel.'"'.$sep;
1079 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1080 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1081 print '"'.$journal.'"'.$sep;
1082 print '"'.dol_string_nohtmltag($ref).'"'.$sep;
1083 print "\n";
1084 }
1085 }
1086
1087 // Third party
1088 if (is_array($tabtp[$key])) {
1089 foreach ($tabtp[$key] as $k => $mt) {
1090 if ($mt) {
1091 $reflabel = '';
1092 if (!empty($val['lib'])) {
1093 $reflabel .= dol_string_nohtmltag($val['lib']).(!empty($val['soclib']) ? " / " : "");
1094 }
1095 if ($tabtype[$key] == 'banktransfert') {
1096 $reflabel .= dol_string_nohtmltag($langs->transnoentitiesnoconv('TransitionalAccount').' '.$account_transfer);
1097 } else {
1098 $reflabel .= dol_string_nohtmltag($val['soclib'] ?? '');
1099 }
1100
1101 print '"'.$key.'"'.$sep;
1102 print '"'.$date.'"'.$sep;
1103 print '"'.$val["type_payment"].'"'.$sep;
1104 if ($tabtype[$key] == 'payment_supplier') {
1105 $account_ledger = (!empty($obj->accountancy_code_supplier_general)) ? $obj->accountancy_code_supplier_general : $account_supplier;
1106 print '"'.length_accountg($account_ledger).'"'.$sep;
1107 } elseif ($tabtype[$key] == 'payment') {
1108 $account_ledger = (!empty($obj->accountancy_code_customer_general)) ? $obj->accountancy_code_customer_general : $account_customer;
1109 print '"'.length_accountg($account_ledger).'"'.$sep;
1110 } elseif ($tabtype[$key] == 'payment_expensereport') {
1111 print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT')).'"'.$sep;
1112 } elseif ($tabtype[$key] == 'payment_salary') {
1113 $account_ledger = (!empty($obj->accountancy_code_user_general)) ? $obj->accountancy_code_user_general : $account_employee;
1114 print '"'.length_accountg($account_ledger).'"'.$sep;
1115 } else {
1116 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1117 }
1118 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
1119 print '"'.$reflabel.'"'.$sep;
1120 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1121 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1122 print '"'.$journal.'"'.$sep;
1123 print '"'.dol_string_nohtmltag($ref).'"'.$sep;
1124 print "\n";
1125 }
1126 }
1127 } else { // If thirdparty unknown, output the waiting account
1128 foreach ($tabbq[$key] as $k => $mt) {
1129 if ($mt) {
1130 $reflabel = '';
1131 if (!empty($val['lib'])) {
1132 $reflabel .= dol_string_nohtmltag($val['lib'])." / ";
1133 }
1134 $reflabel .= dol_string_nohtmltag('WaitingAccount');
1135
1136 print '"'.$key.'"'.$sep;
1137 print '"'.$date.'"'.$sep;
1138 print '"'.$val["type_payment"].'"'.$sep;
1139 print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE')).'"'.$sep;
1140 print $sep;
1141 print '"'.$reflabel.'"'.$sep;
1142 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1143 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1144 print '"'.$journal.'"'.$sep;
1145 print '"'.dol_string_nohtmltag($ref).'"'.$sep;
1146 print "\n";
1147 }
1148 }
1149 }
1150 }
1151}
1152
1153
1154/*
1155 * View
1156 */
1157
1158$form = new Form($db);
1159
1160if (empty($action) || $action == 'view') {
1161 $invoicestatic = new Facture($db);
1162 $invoicesupplierstatic = new FactureFournisseur($db);
1163 $expensereportstatic = new ExpenseReport($db);
1164 $vatstatic = new Tva($db);
1165 $donationstatic = new Don($db);
1166 $loanstatic = new Loan($db);
1167 $salarystatic = new Salary($db);
1168 $variousstatic = new PaymentVarious($db);
1169
1170 $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
1171 $help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#G&eacute;n&eacute;ration_des_&eacute;critures_en_comptabilit&eacute;';
1172 llxHeader('', dol_string_nohtmltag($title), $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-generation page-bankjournal');
1173
1174 $nom = $title;
1175 $builddate = dol_now();
1176 //$description = $langs->trans("DescFinanceJournal") . '<br>';
1177 $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
1178
1179 $listofchoices = array(
1180 'notyet' => $langs->trans("NotYetInGeneralLedger"),
1181 'already' => $langs->trans("AlreadyInGeneralLedger")
1182 );
1183 $period = $form->selectDate($date_start ? $date_start : -1, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end ? $date_end : -1, 'date_end', 0, 0, 0, '', 1, 0);
1184 $period .= '<span class="valignmiddle"> - '.$langs->trans("JournalizationInLedgerStatus").' </span>'.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1, 0, 0, '', 0, 0, 0, '', 'minwidth75 valignmiddle');
1185
1186 $varlink = 'id_journal='.$id_journal;
1187 $periodlink = '';
1188 $exportlink = '';
1189
1190 $listofchoices = array(
1191 1 => $langs->trans("TransfertAllBankLines"),
1192 2 => $langs->trans("TransfertOnlyConciliatedBankLine")
1193 );
1194 $moreoptions = [ "BankLineConciliated" => $form->selectarray('only_rappro', $listofchoices, $only_rappro, 0, 0, 0, '', 0, 0, 0, '', 'minwidth75 valignmiddle')];
1195
1196 journalHead($nom, '', $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink, $moreoptions);
1197
1198 $desc = '';
1199
1200 if (getDolGlobalString('ACCOUNTANCY_FISCAL_PERIOD_MODE') != 'blockedonclosed') {
1201 // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed)
1202 // Fiscal period test
1203 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_fiscalyear WHERE entity = ".((int) $conf->entity);
1204 $resql = $db->query($sql);
1205 if ($resql) {
1206 $obj = $db->fetch_object($resql);
1207 if ($obj->nb == 0) {
1208 print '<br><div class="warning">'.img_warning().' '.$langs->trans("TheFiscalPeriodIsNotDefined");
1209 $desc = ' : '.$langs->trans("AccountancyAreaDescFiscalPeriod", 4, '{link}');
1210 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("FiscalPeriod").'</strong>', $desc);
1211 print $desc;
1212 print '</div>';
1213 }
1214 } else {
1215 dol_print_error($db);
1216 }
1217 }
1218
1219 // Bank test
1220 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."bank_account WHERE entity = ".((int) $conf->entity)." AND fk_accountancy_journal IS NULL AND clos=0";
1221 $resql = $db->query($sql);
1222 if ($resql) {
1223 $obj = $db->fetch_object($resql);
1224 if ($obj->nb > 0) {
1225 print '<br><div class="warning">'.img_warning().' '.$langs->trans("TheJournalCodeIsNotDefinedOnSomeBankAccount");
1226 $desc = ' : '.$langs->trans("AccountancyAreaDescBank", 6, '{link}');
1227 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("BankAccounts").'</strong>', $desc);
1228 print $desc;
1229 print '</div>';
1230 }
1231 } else {
1232 dol_print_error($db);
1233 }
1234
1235
1236 // Button to write into Ledger
1237 if (getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER') == '-1'
1238 || getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER') == '-1'
1239 || (isModEnabled("salaries") && (getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == "" || getDolGlobalString('SALARIES_ACCOUNTING_ACCOUNT_PAYMENT') == '-1'))
1240 || (isModEnabled("expensereport") && (getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT') == '-1'))) {
1241
1242
1243 print($desc ? '' : '<br>').'<div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
1244 $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
1245 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
1246 print $desc;
1247 print '</div>';
1248 }
1249
1250
1251 print '<br><div class="tabsAction tabsActionNoBottom centerimp">';
1252
1253 if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL') && $in_bookkeeping == 'notyet') {
1254 print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
1255 }
1256
1257 if (getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER') == '-1'
1258 || getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER') == "" || getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER') == '-1') {
1259 print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
1260 } else {
1261 if ($in_bookkeeping == 'notyet') {
1262 print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
1263 } else {
1264 print '<a class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
1265 }
1266 }
1267
1268 print '</div>';
1269
1270 // TODO Avoid using js. We can use a direct link with $param
1271 print '
1272 <script type="text/javascript">
1273 function launch_export() {
1274 console.log("Set value into form and submit");
1275 $("div.fiche form input[name=\"action\"]").val("exportcsv");
1276 $("div.fiche form input[type=\"submit\"]").click();
1277 $("div.fiche form input[name=\"action\"]").val("");
1278 }
1279 function writebookkeeping() {
1280 console.log("Set value into form and submit");
1281 $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
1282 $("div.fiche form input[type=\"submit\"]").click();
1283 $("div.fiche form input[name=\"action\"]").val("");
1284 }
1285 </script>';
1286
1287 /*
1288 * Show result array
1289 */
1290 print '<br>';
1291
1292 $i = 0;
1293 print '<div class="div-table-responsive">';
1294 print '<table class="noborder centpercent">';
1295 print '<tr class="liste_titre">';
1296 print "<td>".$langs->trans("Date")."</td>";
1297 print "<td>".$langs->trans("Piece").' ('.$langs->trans("ObjectsRef").")</td>";
1298 print "<td>".$langs->trans("AccountAccounting")."</td>";
1299 print "<td>".$langs->trans("SubledgerAccount")."</td>";
1300 print "<td>".$langs->trans("LabelOperation")."</td>";
1301 print '<td class="center">'.$langs->trans("PaymentMode")."</td>";
1302 print '<td class="right">'.$langs->trans("AccountingDebit")."</td>";
1303 print '<td class="right">'.$langs->trans("AccountingCredit")."</td>";
1304 print "</tr>\n";
1305
1306 foreach ($tabpay as $key => $val) { // $key is rowid in llx_bank
1307 $date = dol_print_date($val["date"], 'day');
1308
1309 $ref = getSourceDocRef($val, $tabtype[$key]);
1310
1311 // Bank
1312 foreach ($tabbq[$key] as $k => $mt) {
1313 if ($mt) {
1314 $reflabel = '';
1315 if (!empty($val['lib'])) {
1316 $reflabel .= $val['lib']." / ";
1317 }
1318 $reflabel .= $langs->trans("Bank").' '.$val['bank_account_ref'];
1319 if (!empty($val['soclib'])) {
1320 $reflabel .= " / ".$val['soclib'];
1321 }
1322
1323 //var_dump($tabpay[$key]);
1324 print '<!-- Bank bank.rowid='.$key.'=accounting_bookkeeping.fk_doc (accounting_bookkeeping.doc_type=\'bank\') type='.$tabpay[$key]['type'].' ref='.$tabpay[$key]['ref'].' -->';
1325 print '<tr class="oddeven">';
1326
1327 // Date
1328 print "<td>".$date."</td>";
1329
1330 // Ref
1331 print '<td class="maxwidth300 nopaddingtopimp nopaddingbottomimp">'.dol_escape_htmltag($ref)."</td>";
1332
1333 // Ledger account
1334 $accounttoshow = length_accountg($k);
1335 if (empty($accounttoshow) || $accounttoshow == 'NotDefined') {
1336 $accounttoshow = '<span class="error">'.$langs->trans("BankAccountNotDefined").'</span>';
1337 }
1338 print '<td class="maxwidth300" title="'.dol_escape_htmltag(dol_string_nohtmltag($accounttoshow)).'">';
1339 print $accounttoshow;
1340 print "</td>";
1341
1342 // Subledger account
1343 print '<td class="maxwidth300">';
1344 /*$accounttoshow = length_accountg($k);
1345 if (empty($accounttoshow) || $accounttoshow == 'NotDefined')
1346 {
1347 print '<span class="error">'.$langs->trans("BankAccountNotDefined").'</span>';
1348 }
1349 else print $accounttoshow;*/
1350 print "</td>";
1351
1352 // Label operation
1353 print '<td class="maxwidth300 nopaddingtopimp nopaddingbottomimp">';
1354 print $reflabel; // This is already html escaped content
1355 print "</td>";
1356
1357 print '<td class="center">'.$val["type_payment"]."</td>";
1358 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1359 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1360 print "</tr>";
1361
1362 $i++;
1363 }
1364 }
1365
1366 // Third party
1367 if (is_array($tabtp[$key])) {
1368 foreach ($tabtp[$key] as $k => $mt) {
1369 if ($mt) {
1370 $reflabel = '';
1371 if (!empty($val['lib'])) {
1372 $reflabel .= $val['lib'].(!empty($val['soclib']) ? " / " : "");
1373 }
1374 if ($tabtype[$key] == 'banktransfert') {
1375 $reflabel .= $langs->trans('TransitionalAccount').' '.$account_transfer;
1376 } else {
1377 $reflabel .= isset($val['soclib']) ? $val['soclib'] : "";
1378 }
1379
1380 print '<!-- Thirdparty bank.rowid='.$key.'=accounting_bookkeeping.fk_doc (accounting_bookkeeping.doc_type=\'bank\') type='.$tabpay[$key]['type'].' ref='.$tabpay[$key]['ref'].' -->';
1381 print '<tr class="oddeven">';
1382
1383 // Date
1384 print "<td>".$date."</td>";
1385
1386 // Ref / Piece
1387 print '<td class="nopaddingtopimp nopaddingbottomimp">'.dol_escape_htmltag($ref)."</td>";
1388
1389
1390 // Ledger account
1391 $account_ledger = $k;
1392 // Try to force general ledger account depending on type
1393 if ($tabtype[$key] == 'payment') {
1394 $account_ledger = (!empty($obj->accountancy_code_customer_general)) ? $obj->accountancy_code_customer_general : $account_customer;
1395 }
1396 if ($tabtype[$key] == 'payment_supplier') {
1397 $account_ledger = (!empty($obj->accountancy_code_supplier_general)) ? $obj->accountancy_code_supplier_general : $account_supplier;
1398 }
1399 if ($tabtype[$key] == 'payment_expensereport') {
1400 $account_ledger = getDolGlobalString('ACCOUNTING_ACCOUNT_EXPENSEREPORT');
1401 }
1402 if ($tabtype[$key] == 'payment_salary') {
1403 $account_ledger = (!empty($obj->accountancy_code_user_general)) ? $obj->accountancy_code_user_general : $account_employee;
1404 }
1405 if ($tabtype[$key] == 'payment_vat') {
1406 $account_ledger = getDolGlobalString('ACCOUNTING_VAT_PAY_ACCOUNT');
1407 }
1408 if ($tabtype[$key] == 'member') {
1409 $account_ledger = getDolGlobalString('ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT');
1410 }
1411 if ($tabtype[$key] == 'payment_various') {
1412 $account_ledger = $tabpay[$key]["account_various"];
1413 }
1414 $accounttoshow = length_accountg($account_ledger);
1415 if (empty($accounttoshow) || $accounttoshow == 'NotDefined') {
1416 if ($tabtype[$key] == 'unknown') {
1417 // We will accept writing, but into a waiting account
1418 if (!getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE') || getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE') == '-1') {
1419 $accounttoshow = '<span class="error small">'.$langs->trans('UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking').'</span>';
1420 } else {
1421 $accounttoshow = '<span class="warning small">'.$langs->trans('UnknownAccountForThirdparty', length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE'))).'</span>'; // We will use a waiting account
1422 }
1423 } else {
1424 // We will refuse writing
1425 $errorstring = 'UnknownAccountForThirdpartyBlocking';
1426 if ($tabtype[$key] == 'payment') {
1427 $errorstring = 'MainAccountForCustomersNotDefined';
1428 }
1429 if ($tabtype[$key] == 'payment_supplier') {
1430 $errorstring = 'MainAccountForSuppliersNotDefined';
1431 }
1432 if ($tabtype[$key] == 'payment_expensereport') {
1433 $errorstring = 'MainAccountForUsersNotDefined';
1434 }
1435 if ($tabtype[$key] == 'payment_salary') {
1436 $errorstring = 'MainAccountForUsersNotDefined';
1437 }
1438 if ($tabtype[$key] == 'payment_vat') {
1439 $errorstring = 'MainAccountForVatPaymentNotDefined';
1440 }
1441 if ($tabtype[$key] == 'member') {
1442 $errorstring = 'MainAccountForSubscriptionPaymentNotDefined';
1443 }
1444 $accounttoshow = '<span class="error small">'.$langs->trans($errorstring).'</span>';
1445 }
1446 }
1447 print '<td class="maxwidth300" title="'.dol_escape_htmltag(dol_string_nohtmltag($accounttoshow)).'">';
1448 print $accounttoshow; // This is a HTML string
1449 print "</td>";
1450
1451 // Subledger account
1452 $accounttoshowsubledger = '';
1453 if (in_array($tabtype[$key], array('payment', 'payment_supplier', 'payment_expensereport', 'payment_salary', 'payment_various'))) { // Type of payments that uses a subledger
1454 $accounttoshowsubledger = length_accounta($k);
1455 if ($accounttoshow != $accounttoshowsubledger) {
1456 if (empty($accounttoshowsubledger) || $accounttoshowsubledger == 'NotDefined') {
1457 //print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
1458 if (!empty($tabcompany[$key]['code_compta'])) {
1459 if (in_array($tabtype[$key], array('payment_various'))) {
1460 // For such case, if subledger is not defined, we won't use subledger accounts.
1461 $accounttoshowsubledger = '<span class="warning small twolinesmax">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored").'</span>';
1462 } elseif (in_array($tabtype[$key], array('payment_salary'))) {
1463 $accounttoshowsubledger = '<span class="warning small twolinesmax">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored2").'</span>';
1464 } else {
1465 $accounttoshowsubledger = '<span class="warning small twolinesmax">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).'</span>';
1466 }
1467 } else {
1468 $accounttoshowsubledger = '<span class="error small twolinesmax">'.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking").'</span>';
1469 }
1470 }
1471 } else {
1472 $accounttoshowsubledger = '';
1473 }
1474 }
1475 print '<td class="maxwidth300 nopaddingtopimp nopaddingbottomimp" title="'.dolPrintHTMLForAttribute(dol_string_nohtmltag($accounttoshowsubledger)).'">';
1476 print $accounttoshowsubledger; // This is a html string
1477 print "</td>";
1478
1479 // Label operation
1480 print '<td class="nopaddingtopimpo paddingbottomimp">';
1481 print $reflabel; // This is a html string
1482 print "</td>";
1483
1484 print '<td class="center">'.$val["type_payment"]."</td>";
1485
1486 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1487
1488 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1489
1490 print "</tr>";
1491
1492 $i++;
1493 }
1494 }
1495 } else { // Waiting account
1496 foreach ($tabbq[$key] as $k => $mt) {
1497 if ($mt) {
1498 $reflabel = '';
1499 if (!empty($val['lib'])) {
1500 $reflabel .= $val['lib']." / ";
1501 }
1502 $reflabel .= 'WaitingAccount';
1503
1504 print '<!-- Wait bank.rowid='.$key.' -->';
1505 print '<tr class="oddeven">';
1506 print "<td>".$date."</td>";
1507 print "<td>".$ref."</td>";
1508 // Ledger account
1509 print "<td>";
1510 /*if (empty($accounttoshow) || $accounttoshow == 'NotDefined')
1511 {
1512 print '<span class="error">'.$langs->trans("WaitAccountNotDefined").'</span>';
1513 }
1514 else */
1515 print length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUSPENSE'));
1516 print "</td>";
1517 // Subledger account
1518 print "<td>";
1519 print "</td>";
1520 print "<td>".dol_escape_htmltag($reflabel)."</td>";
1521 print '<td class="center">'.$val["type_payment"]."</td>";
1522 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1523 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1524 print "</tr>";
1525
1526 $i++;
1527 }
1528 }
1529 }
1530 }
1531
1532 if (!$i) {
1533 $colspan = 8;
1534 print '<tr class="oddeven"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1535 }
1536
1537 print "</table>";
1538 print '</div>';
1539
1540 llxFooter();
1541}
1542
1543$db->close();
1544
1545
1546
1554function getSourceDocRef($val, $typerecord)
1555{
1556 global $db, $langs;
1557
1558 // Defined the docref into $ref (We start with $val['ref'] by default and we complete according to other data)
1559 // WE MUST HAVE SAME REF FOR ALL LINES WE WILL RECORD INTO THE BOOKKEEPING
1560 $ref = $val['ref'];
1561 if ($ref == '(SupplierInvoicePayment)' || $ref == '(SupplierInvoicePaymentBack)') {
1562 $ref = $langs->transnoentitiesnoconv('Supplier');
1563 }
1564 if ($ref == '(CustomerInvoicePayment)' || $ref == '(CustomerInvoicePaymentBack)') {
1565 $ref = $langs->transnoentitiesnoconv('Customer');
1566 }
1567 if ($ref == '(SocialContributionPayment)') {
1568 $ref = $langs->transnoentitiesnoconv('SocialContribution');
1569 }
1570 if ($ref == '(DonationPayment)') {
1571 $ref = $langs->transnoentitiesnoconv('Donation');
1572 }
1573 if ($ref == '(SubscriptionPayment)') {
1574 $ref = $langs->transnoentitiesnoconv('Subscription');
1575 }
1576 if ($ref == '(ExpenseReportPayment)') {
1577 $ref = $langs->transnoentitiesnoconv('Employee');
1578 }
1579 if ($ref == '(LoanPayment)') {
1580 $ref = $langs->transnoentitiesnoconv('Loan');
1581 }
1582 if ($ref == '(payment_salary)') {
1583 $ref = $langs->transnoentitiesnoconv('Employee');
1584 }
1585
1586 $sqlmid = '';
1587 if ($typerecord == 'payment') {
1588 if (getDolGlobalInt('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
1589 $sqlmid = "SELECT payfac.fk_facture as id, ".$db->ifsql('f1.rowid IS NULL', 'f.ref', 'f1.ref')." as ref";
1590 $sqlmid .= " FROM ".$db->prefix()."paiement_facture as payfac";
1591 $sqlmid .= " LEFT JOIN ".$db->prefix()."facture as f ON f.rowid = payfac.fk_facture";
1592 $sqlmid .= " LEFT JOIN ".$db->prefix()."societe_remise_except as sre ON sre.fk_facture_source = payfac.fk_facture";
1593 $sqlmid .= " LEFT JOIN ".$db->prefix()."facture as f1 ON f1.rowid = sre.fk_facture";
1594 $sqlmid .= " WHERE payfac.fk_paiement=".((int) $val['paymentid']);
1595 } else {
1596 $sqlmid = "SELECT payfac.fk_facture as id, f.ref as ref";
1597 $sqlmid .= " FROM ".$db->prefix()."paiement_facture as payfac";
1598 $sqlmid .= " INNER JOIN ".$db->prefix()."facture as f ON f.rowid = payfac.fk_facture";
1599 $sqlmid .= " WHERE payfac.fk_paiement=".((int) $val['paymentid']);
1600 }
1601 $ref = $langs->transnoentitiesnoconv("Invoice");
1602 } elseif ($typerecord == 'payment_supplier') {
1603 $sqlmid = 'SELECT payfac.fk_facturefourn as id, f.ref';
1604 $sqlmid .= " FROM ".MAIN_DB_PREFIX."paiementfourn_facturefourn as payfac, ".MAIN_DB_PREFIX."facture_fourn as f";
1605 $sqlmid .= " WHERE payfac.fk_facturefourn = f.rowid AND payfac.fk_paiementfourn=".((int) $val["paymentsupplierid"]);
1606 $ref = $langs->transnoentitiesnoconv("SupplierInvoice");
1607 } elseif ($typerecord == 'payment_expensereport') {
1608 $sqlmid = 'SELECT e.rowid as id, e.ref';
1609 $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_expensereport as pe, ".MAIN_DB_PREFIX."expensereport as e";
1610 $sqlmid .= " WHERE pe.rowid=".((int) $val["paymentexpensereport"])." AND pe.fk_expensereport = e.rowid";
1611 $ref = $langs->transnoentitiesnoconv("ExpenseReport");
1612 } elseif ($typerecord == 'payment_salary') {
1613 $sqlmid = 'SELECT s.rowid as ref';
1614 $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_salary as s";
1615 $sqlmid .= " WHERE s.rowid=".((int) $val["paymentsalid"]);
1616 $ref = $langs->transnoentitiesnoconv("SalaryPayment");
1617 } elseif ($typerecord == 'sc') {
1618 $sqlmid = 'SELECT sc.rowid as ref';
1619 $sqlmid .= " FROM ".MAIN_DB_PREFIX."paiementcharge as sc";
1620 $sqlmid .= " WHERE sc.rowid=".((int) $val["paymentscid"]);
1621 $ref = $langs->transnoentitiesnoconv("SocialContribution");
1622 } elseif ($typerecord == 'payment_vat') {
1623 $sqlmid = 'SELECT v.rowid as ref';
1624 $sqlmid .= " FROM ".MAIN_DB_PREFIX."tva as v";
1625 $sqlmid .= " WHERE v.rowid=".((int) $val["paymentvatid"]);
1626 $ref = $langs->transnoentitiesnoconv("PaymentVat");
1627 } elseif ($typerecord == 'payment_donation') {
1628 $sqlmid = 'SELECT payd.fk_donation as ref';
1629 $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_donation as payd";
1630 $sqlmid .= " WHERE payd.fk_donation=".((int) $val["paymentdonationid"]);
1631 $ref = $langs->transnoentitiesnoconv("Donation");
1632 } elseif ($typerecord == 'payment_loan') {
1633 $sqlmid = 'SELECT l.rowid as ref';
1634 $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_loan as l";
1635 $sqlmid .= " WHERE l.rowid=".((int) $val["paymentloanid"]);
1636 $ref = $langs->transnoentitiesnoconv("LoanPayment");
1637 } elseif ($typerecord == 'payment_various') {
1638 $sqlmid = 'SELECT v.rowid as ref';
1639 $sqlmid .= " FROM ".MAIN_DB_PREFIX."payment_various as v";
1640 $sqlmid .= " WHERE v.rowid=".((int) $val["paymentvariousid"]);
1641 $ref = $langs->transnoentitiesnoconv("VariousPayment");
1642 }
1643 // Add warning
1644 if (empty($sqlmid)) {
1645 dol_syslog("Found a typerecord=".$typerecord." not supported", LOG_WARNING);
1646 }
1647
1648 if ($sqlmid) {
1649 dol_syslog("accountancy/journal/bankjournal.php::sqlmid=".$sqlmid, LOG_DEBUG);
1650 $resultmid = $db->query($sqlmid);
1651 if ($resultmid) {
1652 while ($objmid = $db->fetch_object($resultmid)) {
1653 $ref .= ' '.$objmid->ref;
1654 }
1655 } else {
1656 dol_print_error($db);
1657 }
1658 }
1659
1660 $ref = dol_trunc($langs->transnoentitiesnoconv("BankId").' '.$val['fk_bank'].' - '.$ref, 295); // 295 + 3 dots (...) is < than max size of 300
1661 return $ref;
1662}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
journalHead($nom, $variant, $period, $periodlink, $description, $builddate, $exportlink='', $moreparam=array(), $calcmode='', $varlink='', $moreoptions=array())
Show header of a page used to transfer/dispatch data in accounting.
getDefaultDatesForTransfer()
Return Default dates for transfer based on periodicity option in accountancy setup.
length_accounta($accounta)
Return Auxiliary accounting account of thirdparties with defined length.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
getSourceDocRef($val, $typerecord)
Return source for doc_ref of a bank transaction.
Class to manage bank accounts.
Class to manage bank transaction lines.
Class to manage accounting accounts.
Class to manage accounting journals.
Class to manage Ledger (General Ledger and Subledger)
Class for managing the social charges.
Class to manage donations.
Definition don.class.php:41
Class to manage Trips and Expenses.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage generation of HTML components Only common components must be here.
Class Lettering.
Loan.
Class to manage payments for supplier invoices.
Class to manage payments of customer invoices.
Class to manage payments of donations.
Class to manage payments of expense report.
Class to manage payments of loans.
Class to manage payments of salaries.
Class to manage various payments.
Class to manage salary payments.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage subscriptions of foundation members.
Class to manage VAT - Value-added tax (also known in French as TVA - Taxe sur la valeur ajoutée)
Definition tva.class.php:38
Class to manage Dolibarr users.
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:600
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:619
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.