dolibarr 19.0.3
bonprelevement.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2010-2015 Juanjo Menent <jmenent@2byte.es>
5 * Copyright (C) 2010-2014 Laurent Destailleur <eldy@users.sourceforge.net>
6 * Copyright (C) 2014-2016 Ferran Marcet <fmarcet@2byte.es>
7 * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
8 * Copyright (C) 2019 JC Prieto <jcprieto@virtual20.com><prietojc@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
31require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
32require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
33require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
34require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
35require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
36require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php';
37require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php';
38require_once DOL_DOCUMENT_ROOT.'/salaries/class/paymentsalary.class.php';
39require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
40require_once DOL_DOCUMENT_ROOT.'/user/class/userbankaccount.class.php';
41
42
47{
51 public $element = 'widthdraw';
52
56 public $table_element = 'prelevement_bons';
57
61 public $picto = 'payment';
62
63 public $date_echeance;
64 public $raison_sociale;
65 public $reference_remise;
66 public $emetteur_code_guichet;
67 public $emetteur_numero_compte;
68 public $emetteur_code_banque;
69 public $emetteur_number_key;
70 public $sepa_xml_pti_in_ctti;
71
72 public $emetteur_iban;
73 public $emetteur_bic;
74 public $emetteur_ics;
75
76 public $user_trans;
77 public $user_credit;
78
79 public $total;
80 public $fetched;
81 public $labelStatus = array();
82
83 public $factures = array();
84
85 public $methodes_trans = array();
86
87 public $invoice_in_error = array();
88 public $thirdparty_in_error = array();
89
93 public $file;
94
95 /*
96 * @var string filename
97 */
98 public $filename;
99
100 const STATUS_DRAFT = 0;
101 const STATUS_TRANSFERED = 1;
102 const STATUS_CREDITED = 2; // STATUS_CREDITED and STATUS_DEBITED is same. Difference is in ->type
103 const STATUS_DEBITED = 2; // STATUS_CREDITED and STATUS_DEBITED is same. Difference is in ->type
104
105
145 // BEGIN MODULEBUILDER PROPERTIES
149 public $fields=array(
150 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>0,),
151 'ref' => array('type'=>'varchar(12)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>15, 'notnull'=>0, 'visible'=>-1, 'csslist'=>'tdoverflowmax150', 'showoncombobox'=>'1',),
152 'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>25, 'notnull'=>0, 'visible'=>-1,),
153 'amount' => array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>-1,),
154 'statut' => array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>'1', 'position'=>500, 'notnull'=>0, 'visible'=>-1, 'arrayofkeyval'=>array(0=>'Wait', 1=>'Transfered', 2=>'Credited')),
155 'credite' => array('type'=>'smallint(6)', 'label'=>'Credite', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>-1,),
156 'note' => array('type'=>'text', 'label'=>'Note', 'enabled'=>'1', 'position'=>45, 'notnull'=>0, 'visible'=>-1,),
157 'date_trans' => array('type'=>'datetime', 'label'=>'Datetrans', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>-1,),
158 'method_trans' => array('type'=>'smallint(6)', 'label'=>'Methodtrans', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1,),
159 'fk_user_trans' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fkusertrans', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>-1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150',),
160 'date_credit' => array('type'=>'datetime', 'label'=>'Datecredit', 'enabled'=>'1', 'position'=>65, 'notnull'=>0, 'visible'=>-1,),
161 'fk_user_credit' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fkusercredit', 'enabled'=>'1', 'position'=>70, 'notnull'=>0, 'visible'=>-1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150',),
162 'type' => array('type'=>'varchar(16)', 'label'=>'Type', 'enabled'=>'1', 'position'=>75, 'notnull'=>0, 'visible'=>-1,),
163 'fk_bank_account' => array('type'=>'integer', 'label'=>'Fkbankaccount', 'enabled'=>'1', 'position'=>80, 'notnull'=>0, 'visible'=>-1, 'css'=>'maxwidth500 widthcentpercentminusxx',),
164 );
165 public $rowid;
166 public $ref;
167 public $datec;
168 public $amount;
169 public $statut;
170 public $credite;
171 public $note;
172 public $date_trans;
173 public $method_trans;
174 public $fk_user_trans;
175 public $date_credit;
176 public $fk_user_credit;
177 public $type;
178 public $fk_bank_account;
179 // END MODULEBUILDER PROPERTIES
180
181
182
188 public function __construct($db)
189 {
190 $this->db = $db;
191
192 $this->filename = '';
193
194 $this->date_echeance = dol_now();
195 $this->raison_sociale = "";
196 $this->reference_remise = "";
197
198 $this->emetteur_code_guichet = "";
199 $this->emetteur_numero_compte = "";
200 $this->emetteur_code_banque = "";
201 $this->emetteur_number_key = "";
202 $this->sepa_xml_pti_in_ctti = false;
203
204 $this->emetteur_iban = "";
205 $this->emetteur_bic = "";
206 $this->emetteur_ics = "";
207
208 $this->factures = array();
209
210 $this->methodes_trans = array(0 => 'Internet', 2 => 'Email', 3 => 'Api');
211
212 $this->fetched = 0;
213 }
214
215 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
231 public function AddFacture($invoice_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $type = 'debit-order', $sourcetype = '')
232 {
233 // phpcs:enable
234 $result = 0;
235 $line_id = 0;
236
237 // Add lines into prelevement_lignes
238 $result = $this->addline($line_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $sourcetype);
239
240
241 if ($result == 0) {
242 if ($line_id > 0) {
243 $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement (";
244 if ($type != 'bank-transfer') {
245 $sql .= "fk_facture";
246 } else {
247 if ($sourcetype == 'salary') {
248 $sql .= "fk_salary";
249 } else {
250 $sql .= "fk_facture_fourn";
251 }
252 }
253 $sql .= ",fk_prelevement_lignes";
254 $sql .= ") VALUES (";
255 $sql .= ((int) $invoice_id);
256 $sql .= ", ".((int) $line_id);
257 $sql .= ")";
258
259 if ($this->db->query($sql)) {
260 $result = 0;
261 } else {
262 $result = -1;
263 $this->errors[] = get_class($this)."::AddFacture ".$this->db->lasterror;
264 dol_syslog(get_class($this)."::AddFacture Error $result");
265 }
266 } else {
267 $result = -2;
268 $this->errors[] = get_class($this)."::AddFacture linedid Empty";
269 dol_syslog(get_class($this)."::AddFacture Error $result");
270 }
271 } else {
272 $result = -3;
273 dol_syslog(get_class($this)."::AddFacture Error $result");
274 }
275
276 return $result;
277 }
278
293 public function addline(&$line_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $sourcetype = '')
294 {
295 $result = -1;
296 $concat = 0; // ??? what is this for. Seems not used.
297
298 if ($concat == 1) {
299 /*
300 * We aggregate the lines
301 */
302 $sql = "SELECT rowid";
303 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_lignes";
304 $sql .= " WHERE fk_prelevement_bons = ".((int) $this->id);
305 if ($sourcetype == 'salary') {
306 $sql .= " AND fk_soc = ".((int) $client_id);
307 } else {
308 $sql .= " AND fk_user = ".((int) $client_id);
309 }
310 $sql .= " AND code_banque = '".$this->db->escape($code_banque)."'";
311 $sql .= " AND code_guichet = '".$this->db->escape($code_guichet)."'";
312 $sql .= " AND number = '".$this->db->escape($number)."'";
313
314 $resql = $this->db->query($sql);
315 if ($resql) {
316 $num = $this->db->num_rows($resql);
317 } else {
318 $result = -1;
319 }
320 } else {
321 /*
322 * No aggregate
323 */
324 $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_lignes (";
325 $sql .= "fk_prelevement_bons";
326 $sql .= ", fk_soc";
327 $sql .= ", client_nom";
328 $sql .= ", amount";
329 $sql .= ", code_banque";
330 $sql .= ", code_guichet";
331 $sql .= ", number";
332 $sql .= ", cle_rib";
333 $sql .= ($sourcetype == 'salary' ? ", fk_user" : "");
334 $sql .= ") VALUES (";
335 $sql .= $this->id;
336 $sql .= ", ".(($sourcetype != 'salary') ? ((int) $client_id) : "0"); // fk_soc can't be null
337 $sql .= ", '".$this->db->escape($client_nom)."'";
338 $sql .= ", ".((float) price2num($amount));
339 $sql .= ", '".$this->db->escape($code_banque)."'";
340 $sql .= ", '".$this->db->escape($code_guichet)."'";
341 $sql .= ", '".$this->db->escape($number)."'";
342 $sql .= ", '".$this->db->escape($number_key)."'";
343 $sql .= (($sourcetype == 'salary') ? ", ". ((int) $client_id) : '');
344 $sql .= ")";
345 if ($this->db->query($sql)) {
346 $line_id = $this->db->last_insert_id(MAIN_DB_PREFIX."prelevement_lignes");
347 $result = 0;
348 } else {
349 $this->errors[] = get_class($this)."::addline Error -2 ".$this->db->lasterror;
350 dol_syslog(get_class($this)."::addline Error -2");
351 $result = -2;
352 }
353 }
354
355 return $result;
356 }
357
364 public function getErrorString($error)
365 {
366 global $langs;
367
368 $errors = array();
369
370 $errors[1027] = $langs->trans("DateInvalid");
371
372 return $errors[abs($error)];
373 }
374
382 public function fetch($rowid, $ref = '')
383 {
384 $sql = "SELECT p.rowid, p.ref, p.amount, p.note";
385 $sql .= ", p.datec as dc";
386 $sql .= ", p.date_trans as date_trans";
387 $sql .= ", p.method_trans, p.fk_user_trans";
388 $sql .= ", p.date_credit as date_credit";
389 $sql .= ", p.fk_user_credit";
390 $sql .= ", p.type";
391 $sql .= ", p.fk_bank_account";
392 $sql .= ", p.statut as status";
393 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p";
394 $sql .= " WHERE p.entity IN (".getEntity('invoice').")";
395 if ($rowid > 0) {
396 $sql .= " AND p.rowid = ".((int) $rowid);
397 } else {
398 $sql .= " AND p.ref = '".$this->db->escape($ref)."'";
399 }
400
401 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
402 $result = $this->db->query($sql);
403 if ($result) {
404 if ($this->db->num_rows($result)) {
405 $obj = $this->db->fetch_object($result);
406
407 $this->id = $obj->rowid;
408 $this->ref = $obj->ref;
409 $this->amount = $obj->amount;
410 $this->note = $obj->note;
411 $this->datec = $this->db->jdate($obj->dc);
412
413 $this->date_trans = $this->db->jdate($obj->date_trans);
414 $this->method_trans = $obj->method_trans;
415 $this->user_trans = $obj->fk_user_trans;
416
417 $this->date_credit = $this->db->jdate($obj->date_credit);
418 $this->user_credit = $obj->fk_user_credit;
419
420 $this->type = $obj->type;
421 $this->fk_bank_account = $obj->fk_bank_account;
422
423 $this->status = $obj->status;
424 $this->statut = $obj->status; // For backward compatibility
425
426 $this->fetched = 1;
427
428 return 1;
429 } else {
430 dol_syslog(get_class($this)."::Fetch Erreur aucune ligne retournee");
431 return -1;
432 }
433 } else {
434 return -2;
435 }
436 }
437
445 public function update(User $user, $notrigger = false)
446 {
447 return $this->updateCommon($user, $notrigger);
448 }
449
450 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
460 public function set_infocredit($user, $date, $type = '')
461 {
462 // phpcs:enable
463 global $conf, $langs;
464
465 $error = 0;
466
467 if ($this->fetched == 1) {
468 if ($date < $this->date_trans) {
469 $langs->load("errors");
470 $this->error = $langs->trans('ErrorDateOfMovementLowerThanDateOfFileTransmission');
471 dol_syslog("bon-prelevment::set_infocredit 1027 ".$this->error);
472 return -1027;
473 }
474
475 $this->db->begin();
476
477 $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_bons";
478 $sql .= " SET fk_user_credit = ".((int) $user->id);
479 $sql .= ", statut = ".self::STATUS_CREDITED;
480 $sql .= ", date_credit = '".$this->db->idate($date)."'";
481 $sql .= " WHERE rowid = ".((int) $this->id);
482 $sql .= " AND entity = ".((int) $conf->entity);
483 $sql .= " AND statut = ".self::STATUS_TRANSFERED;
484
485 $resql = $this->db->query($sql);
486 if ($resql) {
487 $langs->load('withdrawals');
488 $subject = $langs->trans("InfoCreditSubject", $this->ref);
489 $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour'));
490
491 // Add payment of withdrawal into bank
492 $fk_bank_account = $this->fk_bank_account;
493 if (empty($fk_bank_account)) {
494 $fk_bank_account = ($this->type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
495 }
496
497 $facs = array();
498 $amounts = array();
499 $amountsperthirdparty = array();
500
501 $facs = $this->getListInvoices(1, $type);
502 if ($this->error) {
503 $error++;
504 }
505
506 // Loop on each invoice or salary.
507 // $facs should be array(0=>id, 1=>amount requested)
508 $num = count($facs);
509 for ($i = 0; $i < $num; $i++) {
510 if ($this->type == 'bank-transfer') {
511 if ($type == 'salary') {
512 $fac = new Salary($this->db);
513 } else {
514 $fac = new FactureFournisseur($this->db);
515 }
516 } else {
517 $fac = new Facture($this->db);
518 }
519
520 $result = $fac->fetch($facs[$i][0]);
521
522 $amounts[$fac->id] = $facs[$i][1];
523 if ($this->type == 'bank-transfer') {
524 if ($type == 'salary') {
525 $amountsperthirdparty[$fac->fk_user][$fac->id] = $facs[$i][1];
526 } else {
527 $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1];
528 }
529 } else {
530 $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1];
531 }
532
533 $totalpaid = $fac->getSommePaiement();
534 $totalcreditnotes = 0;
535 if (method_exists($fac, 'getSumCreditNotesUsed')) {
536 $totalcreditnotes = $fac->getSumCreditNotesUsed();
537 }
538 $totaldeposits = 0;
539 if (method_exists($fac, 'getSumDepositsUsed')) {
540 $totaldeposits = $fac->getSumDepositsUsed();
541 }
542 $alreadypayed = $totalpaid + $totalcreditnotes + $totaldeposits;
543
544 // Set the main document to pay with status Paid.
545 // @TODO Move this after creation of payments done after
546 $amountofdocument = $fac->total_ttc;
547 if ($type == 'salary') {
548 $amountofdocument = $fac->amount;
549 }
550 if (price2num($alreadypayed + $facs[$i][1], 'MT') == price2num($amountofdocument, 'MT')) {
551 $result = $fac->setPaid($user);
552 if ($result < 0) {
553 $this->error = $fac->error;
554 $this->errors = $fac->errors;
555 }
556 }
557 }
558
559 // Make one payment per customer or employee
560 foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) {
561 if ($this->type == 'bank-transfer') {
562 if ($type == 'salary') {
563 $paiement = new PaymentSalary($this->db);
564 } else {
565 $paiement = new PaiementFourn($this->db);
566 }
567 } else {
568 $paiement = new Paiement($this->db);
569 }
570 $paiement->datepaye = $date;
571 $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice
572
573 if ($this->type == 'bank-transfer') {
574 if ($type == 'salary') {
575 $paiement->datep = $date;
576
577 $paiement->paiementid = 2;
578 $paiement->fk_typepayment = 2;
579 $paiement->paiementcode = 'VIR';
580 } else {
581 $paiement->paiementid = 2;
582 $paiement->paiementcode = 'VIR';
583 }
584 } else {
585 $paiement->paiementid = 3;
586 $paiement->paiementcode = 'PRE';
587 }
588
589 $paiement->num_payment = $this->ref; // Set ref of direct debit note
590 $paiement->id_prelevement = $this->id;
591
592 $result = $paiement->create($user); // This use ->paiementid, that is ID of payment mode
593
594 if ($result < 0) {
595 $error++;
596 $this->error = $paiement->error;
597 $this->errors = $paiement->errors;
598 dol_syslog(get_class($this)."::set_infocredit AddPayment Error ".$this->error);
599 } else {
600 if ($this->type == 'bank-transfer') {
601 if ($type == 'salary') {
602 $modeforaddpayment = 'payment_salary';
603 $labelforaddpayment = '(SalaryPayment)';
604 $addbankurl = 'credit-transfer';
605 } else {
606 $modeforaddpayment = 'payment_supplier';
607 $labelforaddpayment = '(SupplierInvoicePayment)';
608 $addbankurl = 'credit-transfer';
609 }
610 } else {
611 $modeforaddpayment = 'payment';
612 $labelforaddpayment = '(CustomerInvoicePayment)';
613 $addbankurl = 'direct-debit'; // = 'directdebit'
614 }
615
616 $result = $paiement->addPaymentToBank($user, $modeforaddpayment, $labelforaddpayment, $fk_bank_account, '', '', 0, '', $addbankurl);
617
618 if ($result < 0) {
619 $error++;
620 $this->error = $paiement->error;
621 $this->errors = $paiement->errors;
622 dol_syslog(get_class($this)."::set_infocredit AddPaymentToBank Error ".$this->error);
623 }
624 }
625 }
626
627 // Update withdrawal line
628 // TODO: Translate to ligneprelevement.class.php
629 if (!$error) {
630 $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_lignes";
631 $sql .= " SET statut = 2";
632 $sql .= " WHERE fk_prelevement_bons = ".((int) $this->id);
633
634 if (!$this->db->query($sql)) {
635 dol_syslog(get_class($this)."::set_infocredit Update lines Error");
636 $error++;
637 }
638 }
639 } else {
640 $this->error = $this->db->lasterror();
641 dol_syslog(get_class($this)."::set_infocredit Update Bons Error");
642 $error++;
643 }
644
645 // End of procedure
646 if ($error == 0) {
647 $this->date_credit = $date; // date credit or debit
648 $this->statut = self::STATUS_CREDITED;
649 $this->status = self::STATUS_CREDITED;
650
651 $this->db->commit();
652 return 0;
653 } else {
654 $this->db->rollback();
655 return -1;
656 }
657 } else {
658 return -1026;
659 }
660 }
661
662 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
671 public function set_infotrans($user, $date, $method)
672 {
673 // phpcs:enable
674 global $conf, $langs;
675
676 $error = 0;
677
678 dol_syslog(get_class($this)."::set_infotrans Start", LOG_INFO);
679
680 if ($this->db->begin()) {
681 $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons ";
682 $sql .= " SET fk_user_trans = ".$user->id;
683 $sql .= " , date_trans = '".$this->db->idate($date)."'";
684 $sql .= " , method_trans = ".((int) $method);
685 $sql .= " , statut = ".self::STATUS_TRANSFERED;
686 $sql .= " WHERE rowid = ".((int) $this->id);
687 $sql .= " AND entity = ".((int) $conf->entity);
688 $sql .= " AND statut = ".self::STATUS_DRAFT;
689
690 if ($this->db->query($sql)) {
691 $this->method_trans = $method;
692 $langs->load('withdrawals');
693 $subject = $langs->trans("InfoTransSubject", $this->ref);
694 $message = $langs->trans("InfoTransMessage", $this->ref, dolGetFirstLastname($user->firstname, $user->lastname));
695 $message .= $langs->trans("InfoTransData", price($this->amount), $this->methodes_trans[$this->method_trans], dol_print_date($date, 'day'));
696
697 // TODO Call trigger to create a notification using notification module
698 } else {
699 $error++;
700 }
701
702 if ($error == 0) {
703 $this->date_trans = $date;
704 $this->statut = self::STATUS_TRANSFERED;
705 $this->status = self::STATUS_TRANSFERED;
706 $this->user_trans = $user->id;
707
708 $this->db->commit();
709
710 return 0;
711 } else {
712 $this->db->rollback();
713 dol_syslog(get_class($this)."::set_infotrans ROLLBACK", LOG_ERR);
714
715 return -1;
716 }
717 } else {
718 dol_syslog(get_class($this)."::set_infotrans Ouverture transaction SQL impossible", LOG_CRIT);
719 return -2;
720 }
721 }
722
730 private function getListInvoices($amounts = 0, $type = '')
731 {
732 global $conf;
733
734 $arr = array();
735
736 dol_syslog(get_class($this)."::getListInvoices");
737
738 // Returns all invoices presented within same order
739 $sql = "SELECT ";
740 if ($this->type == 'bank-transfer') {
741 if ($type == 'salary') {
742 $sql .= " p.fk_salary";
743 } else {
744 $sql .= " p.fk_facture_fourn";
745 }
746 } else {
747 $sql .= " p.fk_facture";
748 }
749 if ($amounts) {
750 $sql .= ", SUM(pl.amount)";
751 }
752 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as pb,";
753 $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,";
754 $sql .= " ".MAIN_DB_PREFIX."prelevement as p";
755 $sql .= " WHERE p.fk_prelevement_lignes = pl.rowid";
756 $sql .= " AND pl.fk_prelevement_bons = pb.rowid";
757 $sql .= " AND pb.rowid = ".((int) $this->id);
758 $sql .= " AND pb.entity = ".((int) $conf->entity);
759 if ($amounts) {
760 if ($this->type == 'bank-transfer') {
761 if ($type == 'salary') {
762 $sql .= " GROUP BY p.fk_salary";
763 } else {
764 $sql .= " GROUP BY p.fk_facture_fourn";
765 }
766 } else {
767 $sql .= " GROUP BY p.fk_facture";
768 }
769 }
770
771 $resql = $this->db->query($sql);
772 if ($resql) {
773 $num = $this->db->num_rows($resql);
774
775 if ($num) {
776 $i = 0;
777 while ($i < $num) {
778 $row = $this->db->fetch_row($resql);
779 if (!$amounts) {
780 $arr[$i] = $row[0];
781 } else {
782 $arr[$i] = array(
783 $row[0],
784 $row[1]
785 );
786 }
787 $i++;
788 }
789 }
790 $this->db->free($resql);
791 } else {
792 $this->error = $this->db->lasterror();
793 }
794
795 return $arr;
796 }
797
798 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
806 public function SommeAPrelever($mode = 'direct-debit', $type = '')
807 {
808 // phpcs:enable
809 $sql = "SELECT sum(pd.amount) as nb";
810 if ($type !== 'salary') {
811 if ($mode != 'bank-transfer') {
812 $sql .= " FROM ".MAIN_DB_PREFIX."facture as f,";
813 } else {
814 $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f,";
815 }
816 } else {
817 $sql .= " FROM ".MAIN_DB_PREFIX."salary as s,";
818 }
819 $sql .= " ".MAIN_DB_PREFIX."prelevement_demande as pd";
820 $sql .= ($type !== 'salary' ? " WHERE f.entity IN (".getEntity('invoice').")" : " WHERE s.entity IN (".getEntity('salary').")");
821 if (!getDolGlobalString('WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS')) {
822 $sql .= ($type !== 'salary' ? " AND f.fk_statut = ".Facture::STATUS_VALIDATED : " AND s.paye = ".Salary::STATUS_UNPAID);
823 }
824 if ($type !== 'salary') {
825 if ($mode != 'bank-transfer') {
826 $sql .= " AND f.rowid = pd.fk_facture";
827 } else {
828 $sql .= " AND f.rowid = pd.fk_facture_fourn";
829 }
830 } else {
831 $sql .= " AND s.rowid = pd.fk_salary";
832 }
833 $sql .= ($type !== 'salary' ? " AND f.paye = 0" : "");
834 $sql .= " AND pd.traite = 0";
835 $sql .= " AND pd.ext_payment_id IS NULL";
836 $sql .= ($type !== 'salary' ? " AND f.total_ttc > 0" : "");
837
838 $resql = $this->db->query($sql);
839 if ($resql) {
840 $obj = $this->db->fetch_object($resql);
841
842 $this->db->free($resql);
843
844 return $obj->nb;
845 } else {
846 $error = 1;
847 dol_syslog(get_class($this)."::SommeAPrelever Erreur -1");
848 dol_syslog($this->db->error());
849
850 return -1;
851 }
852 }
853
861 public function nbOfInvoiceToPay($mode = 'direct-debit', $type = '')
862 {
863 if ($type === 'salary') {
864 return $this->NbFactureAPrelever($mode, 1);
865 } else {
866 return $this->NbFactureAPrelever($mode);
867 }
868 }
869
870 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
878 public function NbFactureAPrelever($type = 'direct-debit', $forsalary = 0)
879 {
880 // phpcs:enable
881 if ($forsalary == 1) {
882 $sql = "SELECT count(s.rowid) as nb";
883 $sql .= " FROM ".MAIN_DB_PREFIX."salary as s";
884 } else {
885 $sql = "SELECT count(f.rowid) as nb";
886
887 if ($type == 'bank-transfer') {
888 $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
889 } else {
890 $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
891 }
892 }
893 $sql .= ", ".MAIN_DB_PREFIX."prelevement_demande as pd";
894 if ($forsalary == 1) {
895 $sql .= " WHERE s.entity IN (".getEntity('invoice').")";
896 if (!getDolGlobalString('WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS')) {
897 $sql .= " AND s.paye = 0";
898 }
899 } else {
900 $sql .= " WHERE f.entity IN (".getEntity('invoice').")";
901 if (!getDolGlobalString('WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS')) {
902 $sql .= " AND f.fk_statut = ".Facture::STATUS_VALIDATED;
903 }
904 }
905 if ($forsalary == 1) {
906 $sql .= " AND s.rowid = pd.fk_salary";
907 } else {
908 if ($type == 'bank-transfer') {
909 $sql .= " AND f.rowid = pd.fk_facture_fourn";
910 } else {
911 $sql .= " AND f.rowid = pd.fk_facture";
912 }
913 }
914 $sql .= " AND pd.traite = 0";
915 $sql .= " AND pd.ext_payment_id IS NULL";
916 if (!$forsalary == 1) {
917 $sql .= " AND f.total_ttc > 0";
918 } else {
919 $sql .= " AND s.paye = 0";
920 }
921
922 dol_syslog(get_class($this)."::NbFactureAPrelever");
923 $resql = $this->db->query($sql);
924
925 if ($resql) {
926 $obj = $this->db->fetch_object($resql);
927 $this->db->free($resql);
928
929 return $obj->nb;
930 } else {
931 $this->error = get_class($this)."::NbFactureAPrelever Erreur -1 sql=".$this->db->error();
932 return -1;
933 }
934 }
935
936
937 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
958 public function create($banque = 0, $agence = 0, $mode = 'real', $format = 'ALL', $executiondate = '', $notrigger = 0, $type = 'direct-debit', $did = 0, $fk_bank_account = 0, $sourcetype = 'invoice')
959 {
960 // phpcs:enable
961 global $conf, $langs, $user;
962
963 dol_syslog(__METHOD__." Bank=".$banque." Office=".$agence." mode=".$mode." format=".$format, LOG_DEBUG);
964
965 require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
966 require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
967
968 // Check params
969 if ($type != 'bank-transfer') {
970 if (empty($format)) {
971 $this->error = 'ErrorBadParametersForDirectDebitFileCreate';
972 return -1;
973 }
974 }
975
976 // Clean params
977 if (empty($fk_bank_account)) {
978 $fk_bank_account = ($type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
979 }
980
981 $error = 0;
982
983 $datetimeprev = dol_now('gmt');
984 // Choice the date of the execution direct debit
985 if (!empty($executiondate)) {
986 $datetimeprev = $executiondate;
987 }
988
989 $month = dol_print_date($datetimeprev, "%m", 'gmt');
990 $year = dol_print_date($datetimeprev, "%Y", 'gmt');
991
992 $this->invoice_in_error = array();
993 $this->thirdparty_in_error = array();
994
995 // Read invoices
996 $factures = array();
997 $factures_prev = array();
998 $factures_result = array();
999 $factures_prev_id = array();
1000 $factures_errors = array();
1001 if (!$error) {
1002 dol_syslog(__METHOD__." Read invoices for did=".((int) $did), LOG_DEBUG);
1003
1004 $sql = "SELECT f.rowid, pd.rowid as pfdrowid";
1005 if ($sourcetype != 'salary') {
1006 $sql .= ", f.fk_soc";
1007 } else {
1008 $sql .= ", f.fk_user";
1009 }
1010 $sql .= ", pd.code_banque, pd.code_guichet, pd.number, pd.cle_rib";
1011 $sql .= ", pd.amount";
1012 if ($sourcetype != 'salary') {
1013 $sql .= ", s.nom as name";
1014 $sql .= ", f.ref, sr.bic, sr.iban_prefix, sr.frstrecur";
1015 } else {
1016 $sql .= ", CONCAT(s.firstname,' ',s.lastname) as name";
1017 $sql .= ", f.ref, sr.bic, sr.iban_prefix, 'FRST' as frstrecur";
1018 }
1019 if ($sourcetype != 'salary') {
1020 if ($type != 'bank-transfer') {
1021 $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
1022 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_demande as pd ON f.rowid = pd.fk_facture";
1023 } else {
1024 $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
1025 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_demande as pd ON f.rowid = pd.fk_facture_fourn";
1026 }
1027 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
1028 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_rib as sr ON s.rowid = sr.fk_soc AND sr.default_rib = 1";
1029 } else {
1030 $sql .= " FROM ".MAIN_DB_PREFIX."salary as f";
1031 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."prelevement_demande as pd ON f.rowid = pd.fk_salary";
1032 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as s ON s.rowid = f.fk_user";
1033 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user_rib as sr ON s.rowid = sr.fk_user"; // TODO Add AND sr.default_rib = 1 here
1034 }
1035 if ($sourcetype != 'salary') {
1036 if ($type != 'bank-transfer') {
1037 $sql .= " WHERE f.entity IN (".getEntity('invoice').')';
1038 } else {
1039 $sql .= " WHERE f.entity IN (".getEntity('supplier_invoice').')';
1040 }
1041 } else {
1042 $sql .= " WHERE f.entity IN (".getEntity('salary').')';
1043 }
1044 if ($sourcetype != 'salary') {
1045 $sql .= " AND f.fk_statut = 1"; // Invoice validated
1046 $sql .= " AND f.paye = 0";
1047 $sql .= " AND f.total_ttc > 0";
1048 } else {
1049 //$sql .= " AND f.fk_statut = 1"; // Invoice validated
1050 $sql .= " AND f.paye = 0";
1051 $sql .= " AND f.amount > 0";
1052 }
1053 $sql .= " AND pd.traite = 0";
1054 $sql .= " AND pd.ext_payment_id IS NULL";
1055 if ($sourcetype != 'salary') {
1056 $sql .= " AND sr.type = 'ban'"; // TODO Add AND sr.type = 'ban' for users too
1057 }
1058 if ($did > 0) {
1059 $sql .= " AND pd.rowid = ".((int) $did);
1060 }
1061
1062 $resql = $this->db->query($sql);
1063 if ($resql) {
1064 $num = $this->db->num_rows($resql);
1065 $i = 0;
1066
1067 while ($i < $num) {
1068 $row = $this->db->fetch_row($resql); // TODO Replace with fetch_object()
1069 $factures[$i] = $row; // All fields
1070
1071 if ($row[7] == 0) {
1072 $error++;
1073 dol_syslog(__METHOD__." Read invoices/salary error Found a null amount", LOG_ERR);
1074 $this->invoice_in_error[$row[0]] = "Error for invoice or salary id ".$row[0].", found a null amount";
1075 break;
1076 }
1077 $i++;
1078 }
1079
1080 $this->db->free($resql);
1081 dol_syslog(__METHOD__." Read invoices/salary, ".$i." invoices/salary to withdraw", LOG_DEBUG);
1082 } else {
1083 $error++;
1084 $this->error = $this->db->lasterror();
1085 dol_syslog(__METHOD__." Read invoices/salary error ".$this->db->lasterror(), LOG_ERR);
1086 return -1;
1087 }
1088 }
1089
1090 if (!$error) {
1091 // Make some checks
1092 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1093 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
1094 require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
1095 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1096
1097 $tmpsoc = new Societe($this->db);
1098 $tmpuser = new User($this->db);
1099
1100 // Check BAN
1101 $i = 0;
1102 dol_syslog(__METHOD__." Check BAN", LOG_DEBUG);
1103
1104 if (count($factures) > 0) {
1105 foreach ($factures as $key => $fac) {
1106 /*
1107 if ($type != 'bank-transfer') {
1108 $tmpinvoice = new Facture($this->db);
1109 } else {
1110 $tmpinvoice = new FactureFournisseur($this->db);
1111 }
1112 $resfetch = $tmpinvoice->fetch($fac[0]);
1113 if ($resfetch >= 0) { // Field 0 of $fac is rowid of invoice
1114 */
1115
1116 // Check if $fac[8] s.nom is null
1117 if ($fac[8] != null) {
1118 //$bac = new CompanyBankAccount($this->db);
1119 //$bac->fetch(0, $soc->id);
1120
1121 if ($type != 'bank-transfer') {
1122 if ($format == 'FRST' && $fac[12] != 'FRST') {
1123 continue;
1124 }
1125 if ($format == 'RCUR' && $fac[12] != 'RCUR') {
1126 continue;
1127 }
1128 }
1129
1130 $verif = checkSwiftForAccount(null, $fac[10]);
1131 if ($verif) {
1132 $verif = checkIbanForAccount(null, $fac[11]);
1133 }
1134
1135 if ($verif) {
1136 $factures_prev[$i] = $fac;
1137 /* second array necessary for BonPrelevement */
1138 $factures_prev_id[$i] = $fac[0];
1139 $i++;
1140 //dol_syslog(__METHOD__."::RIB is ok", LOG_DEBUG);
1141 } else {
1142 if ($type != 'bank-transfer') {
1143 $tmpsoc->id = $fac[2];
1144 $tmpsoc->name = $fac[8];
1145 $invoice_url = "<a href='".DOL_URL_ROOT.'/compta/facture/card.php?facid='.$fac[0]."'>".$fac[9]."</a>";
1146 $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1147 $this->thirdparty_in_error[$tmpsoc->id] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1148 $error++;
1149 }
1150 if ($type == 'bank-transfer' && $sourcetype != 'salary') {
1151 $tmpsoc->id = $fac[2];
1152 $tmpsoc->name = $fac[8];
1153 $invoice_url = "<a href='".DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$fac[0]."'>".$fac[9]."</a>";
1154 $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1155 $this->thirdparty_in_error[$tmpsoc->id] = "Error on default bank number IBAN/BIC for invoice " . $invoice_url . " for thirdparty " . $tmpsoc->getNomUrl(0);
1156 $error++;
1157 }
1158 if ($type == 'bank-transfer' && $sourcetype == 'salary') {
1159 $tmpuser->id = $fac[2];
1160 $tmpuser->firstname = $fac[8];
1161 $salary_url = "<a href='".DOL_URL_ROOT.'/salaries/card.php?id='.$fac[0]."'>".$fac[0]."</a>";
1162 $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for salary " . $salary_url . " for employee " . $tmpuser->getNomUrl(0);
1163 $this->thirdparty_in_error[$tmpuser->id] = "Error on default bank number IBAN/BIC for salary " . $salary_url . " for employee " . $tmpuser->getNomUrl(0);
1164 $error++;
1165 }
1166 dol_syslog(__METHOD__ . " Check BAN Error on default bank number IBAN/BIC reported by verif(): " . join(', ', $fac), LOG_WARNING);
1167 }
1168 } else {
1169 dol_syslog(__METHOD__ . " Check BAN Failed to read company", LOG_WARNING);
1170 }
1171 /*
1172 } else {
1173 dol_syslog(__METHOD__." Check BAN Failed to read invoice", LOG_WARNING);
1174 }
1175 */
1176 }
1177 } else {
1178 dol_syslog(__METHOD__." Check BAN No invoice to process", LOG_WARNING);
1179 }
1180 }
1181
1182 $ok = 0;
1183
1184 // Withdraw invoices in factures_prev array
1185 $out = count($factures_prev)." invoices will be included.";
1186 //print $out."\n";
1187 dol_syslog($out);
1188
1189 // Return warning
1190 /*$i=0;
1191 foreach ($this->thirdparty_in_error as $key => $val)
1192 {
1193 if ($i < 10) setEventMessages($val, null, 'warnings');
1194 else setEventMessages('More error were discarded...', null, 'warnings');
1195 $i++;
1196 }*/
1197
1198 if (count($factures_prev) > 0) {
1199 if ($mode == 'real') {
1200 $ok = 1;
1201 } else {
1202 print $langs->trans("ModeWarning"); // "Option for real mode was not set, we stop after this simulation\n";
1203 }
1204 }
1205 if ($ok) {
1206 /*
1207 * We are in real mode.
1208 * We create order and build file into disk
1209 */
1210 $this->db->begin();
1211
1212 $now = dol_now();
1213 $ref = '';
1214
1215 /*
1216 * Process order generation
1217 */
1218 if (!$error) {
1219 $ref = substr($year, -2).$month;
1220
1221 // Get next free nunber for the ref of bon prelevement
1222 $sql = "SELECT substring(ref from char_length(ref) - 1)"; // To extract "YYMMXX" from "TYYMMXX"
1223 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons";
1224 $sql .= " WHERE ref LIKE '_".$this->db->escape($ref)."%'";
1225 $sql .= " AND entity = ".((int) $conf->entity);
1226 $sql .= " ORDER BY ref DESC LIMIT 1";
1227
1228 dol_syslog(get_class($this)." get next free number", LOG_DEBUG);
1229 $resql = $this->db->query($sql);
1230
1231 if ($resql) {
1232 $row = $this->db->fetch_row($resql);
1233
1234 // Build the new ref
1235 $ref = "T".$ref.sprintf("%02d", (intval($row[0]) + 1));
1236
1237 // $conf->abc->dir_output may be:
1238 // /home/ldestailleur/git/dolibarr_15.0/documents/abc/
1239 // or
1240 // /home/ldestailleur/git/dolibarr_15.0/documents/X/abc with X >= 2 with multicompany.
1241 if ($type != 'bank-transfer') {
1242 $dir = $conf->prelevement->dir_output.'/receipts';
1243 } else {
1244 $dir = $conf->paymentbybanktransfer->dir_output.'/receipts';
1245 }
1246 if (!is_dir($dir)) {
1247 dol_mkdir($dir);
1248 }
1249
1250 if (isModEnabled('multicompany')) {
1251 $labelentity = $conf->entity;
1252 $this->filename = $dir.'/'.$ref.'-'.$labelentity.'.xml';
1253 } else {
1254 $this->filename = $dir.'/'.$ref.'.xml';
1255 }
1256
1257 // Create withdraw order in database
1258 $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons (";
1259 $sql .= "ref, entity, datec, type, fk_bank_account";
1260 $sql .= ") VALUES (";
1261 $sql .= "'".$this->db->escape($ref)."'";
1262 $sql .= ", ".((int) $conf->entity);
1263 $sql .= ", '".$this->db->idate($now)."'";
1264 $sql .= ", '".($type == 'bank-transfer' ? 'bank-transfer' : 'debit-order')."'";
1265 $sql .= ", ".((int) $fk_bank_account);
1266 $sql .= ")";
1267
1268 $resql = $this->db->query($sql);
1269
1270
1271 if ($resql) {
1272 $prev_id = $this->db->last_insert_id(MAIN_DB_PREFIX."prelevement_bons");
1273 $this->id = $prev_id;
1274 $this->ref = $ref;
1275 } else {
1276 $error++;
1277 dol_syslog(__METHOD__." Create withdraw receipt ".$this->db->lasterror(), LOG_ERR);
1278 }
1279 } else {
1280 $error++;
1281 dol_syslog(__METHOD__." Get last withdraw receipt ".$this->db->lasterror(), LOG_ERR);
1282 }
1283 }
1284
1285 if (!$error) {
1286 dol_syslog(__METHOD__." Now loop on each document to insert them in llx_prelevement_demande");
1287
1288 // Add lines for the bon
1289 if (count($factures_prev) > 0) {
1290 foreach ($factures_prev as $fac) { // Add a link in database for each invoice ro salary
1291 /*
1292 * Add standing order. This add record into llx_prelevement_lignes and llx_prelevement
1293 *
1294 * $fac[0] : invoice_id
1295 * $fac[1] : ???
1296 * $fac[2] : third party id
1297 * $fac[3] : banque
1298 * $fac[4] : guichet
1299 * $fac[5] : number
1300 * $fac[6] : cle rib
1301 * $fac[7] : amount
1302 * $fac[8] : client nom
1303 * $fac[9] : Invoice ref
1304 * $fac[10] : BIC
1305 * $fac[11] : IBAN
1306 * $fac[12] : frstrcur
1307 */
1308 $ri = $this->AddFacture($fac[0], $fac[2], $fac[8], $fac[7], $fac[3], $fac[4], $fac[5], $fac[6], $type, $sourcetype);
1309
1310 if ($ri != 0) {
1311 $error++;
1312 }
1313
1314 // Update invoice requests as done
1315 $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_demande";
1316 $sql .= " SET traite = 1";
1317 $sql .= ", date_traite = '".$this->db->idate($now)."'";
1318 $sql .= ", fk_prelevement_bons = ".((int) $this->id);
1319 $sql .= " WHERE rowid = ".((int) $fac[1]);
1320
1321 $resql = $this->db->query($sql);
1322 if (!$resql) {
1323 $error++;
1324 $this->errors[] = $this->db->lasterror();
1325 dol_syslog(__METHOD__." Update Error=".$this->db->lasterror(), LOG_ERR);
1326 }
1327 }
1328 }
1329 }
1330
1331 if (!$error) {
1332 /*
1333 * Create file of type='direct-debit' for direct debit order or type='bank-transfer' for credit transfer into a XML file
1334 */
1335
1336 dol_syslog(__METHOD__." Init direct debit or credit transfer file for ".count($factures_prev)." invoices", LOG_DEBUG);
1337
1338 if (count($factures_prev) > 0) {
1339 $this->date_echeance = $datetimeprev;
1340 $this->reference_remise = $ref;
1341
1342 $account = new Account($this->db);
1343 if ($account->fetch($fk_bank_account) > 0) {
1344 $this->emetteur_code_banque = $account->code_banque;
1345 $this->emetteur_code_guichet = $account->code_guichet;
1346 $this->emetteur_numero_compte = $account->number;
1347 $this->emetteur_number_key = $account->cle_rib;
1348 $this->sepa_xml_pti_in_ctti = (bool) $account->pti_in_ctti;
1349 $this->emetteur_iban = $account->iban;
1350 $this->emetteur_bic = $account->bic;
1351
1352 $this->emetteur_ics = (($type == 'bank-transfer' && getDolGlobalString("SEPA_USE_IDS")) ? $account->ics_transfer : $account->ics); // Example "FR78ZZZ123456"
1353
1354 $this->raison_sociale = $account->proprio;
1355 }
1356 $this->factures = $factures_prev_id;
1357 $this->context['factures_prev'] = $factures_prev;
1358 // Generation of direct debit or credit transfer file $this->filename (May be a SEPA file for european countries)
1359 // This also set the property $this->total with amount that is included into file
1360 if ($sourcetype == 'salary') {
1361 $userid = $this->context['factures_prev'][0][2];
1362 }
1363 $result = $this->generate($format, $executiondate, $type, $fk_bank_account, $userid);
1364 if ($result < 0) {
1365 //var_dump($this->error);
1366 //var_dump($this->invoice_in_error);
1367 $error++;
1368 }
1369 }
1370 dol_syslog(__METHOD__." Bank order file has been generated under filename ".$this->filename, LOG_DEBUG);
1371 }
1372
1373
1374 /*
1375 * Update total defined after generation of file
1376 */
1377 if (!$error) {
1378 $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons";
1379 $sql .= " SET amount = ".price2num($this->total);
1380 $sql .= " WHERE rowid = ".((int) $this->id);
1381 $sql .= " AND entity = ".((int) $conf->entity);
1382 $resql = $this->db->query($sql);
1383
1384 if (!$resql) {
1385 $error++;
1386 dol_syslog(__METHOD__." Error update total: ".$this->db->error(), LOG_ERR);
1387 }
1388 }
1389
1390 if (!$error && !$notrigger) {
1391 $triggername = 'DIRECT_DEBIT_ORDER_CREATE';
1392 if ($type != 'bank-transfer') {
1393 $triggername = 'CREDIT_TRANSFER_ORDER_CREATE';
1394 }
1395
1396 // Call trigger
1397 $result = $this->call_trigger($triggername, $user);
1398 if ($result < 0) {
1399 $error++;
1400 }
1401 // End call triggers
1402 }
1403
1404 if (!$error) {
1405 $this->db->commit();
1406 return count($factures_prev); // The error of failed lines are into $this->invoice_in_error and $this->thirdparty_in_error
1407 } else {
1408 $this->db->rollback();
1409 return -1;
1410 }
1411 } else {
1412 return 0;
1413 }
1414 }
1415
1416
1424 public function delete($user = null, $notrigger = 0)
1425 {
1426 $this->db->begin();
1427
1428 $error = 0;
1429 $resql1 = $resql2 = $resql3 = $resql4 = 0;
1430
1431 if (!$notrigger) {
1432 $triggername = 'DIRECT_DEBIT_ORDER_DELETE';
1433 if ($this->type == 'bank-transfer') {
1434 $triggername = 'PAYMENTBYBANKTRANFER_DELETE';
1435 }
1436 // Call trigger
1437 $result = $this->call_trigger($triggername, $user);
1438 if ($result < 0) {
1439 $error++;
1440 }
1441 // End call triggers
1442 }
1443
1444 if (!$error) {
1445 $sql = "DELETE FROM ".MAIN_DB_PREFIX."prelevement WHERE fk_prelevement_lignes IN (SELECT rowid FROM ".MAIN_DB_PREFIX."prelevement_lignes WHERE fk_prelevement_bons = ".((int) $this->id).")";
1446 $resql1 = $this->db->query($sql);
1447 if (!$resql1) {
1448 dol_print_error($this->db);
1449 }
1450 }
1451
1452 if (!$error) {
1453 $sql = "DELETE FROM ".MAIN_DB_PREFIX."prelevement_lignes WHERE fk_prelevement_bons = ".((int) $this->id);
1454 $resql2 = $this->db->query($sql);
1455 if (!$resql2) {
1456 dol_print_error($this->db);
1457 }
1458 }
1459
1460 if (!$error) {
1461 $sql = "DELETE FROM ".MAIN_DB_PREFIX."prelevement_bons WHERE rowid = ".((int) $this->id);
1462 $resql3 = $this->db->query($sql);
1463 if (!$resql3) {
1464 dol_print_error($this->db);
1465 }
1466 }
1467
1468 if (!$error) {
1469 $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_demande SET fk_prelevement_bons = NULL, traite = 0 WHERE fk_prelevement_bons = ".((int) $this->id);
1470 $resql4 = $this->db->query($sql);
1471 if (!$resql4) {
1472 dol_print_error($this->db);
1473 }
1474 }
1475
1476 if ($resql1 && $resql2 && $resql3 && $resql4 && !$error) {
1477 $this->db->commit();
1478 return 1;
1479 } else {
1480 $this->db->rollback();
1481 return -1;
1482 }
1483 }
1484
1485
1496 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
1497 {
1498 global $conf, $langs, $hookmanager;
1499
1500 if (!empty($conf->dol_no_mouse_hover)) {
1501 $notooltip = 1; // Force disable tooltips
1502 }
1503
1504 $result = '';
1505
1506 $labeltoshow = 'PaymentByDirectDebit';
1507 if (!empty($this->type) && $this->type == 'bank-transfer') {
1508 $labeltoshow = 'PaymentByBankTransfer';
1509 }
1510
1511 $label = img_picto('', $this->picto).' <u>'.$langs->trans($labeltoshow).'</u> '.$this->getLibStatut(5);
1512 $label .= '<br>';
1513 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
1514 if (isset($this->amount)) {
1515 $label .= '<br><b>'.$langs->trans("Amount").":</b> ".price($this->amount);
1516 }
1517 if (isset($this->date_trans)) {
1518 $label .= '<br><b>'.$langs->trans("TransData").":</b> ".dol_print_date($this->date_trans, 'dayhour', 'tzuserrel');
1519 }
1520 /*if (isset($this->date_credit)) {
1521 $label .= '<br><b>'.$langs->trans("TransData").":</b> ".dol_print_date($this->date_credit, 'dayhour', 'tzuserrel');
1522 }*/
1523
1524 $url = DOL_URL_ROOT.'/compta/prelevement/card.php?id='.$this->id;
1525 if (!empty($this->type) && $this->type == 'bank-transfer') {
1526 $url = DOL_URL_ROOT.'/compta/prelevement/card.php?id='.$this->id;
1527 }
1528
1529 if ($option != 'nolink') {
1530 // Add param to save lastsearch_values or not
1531 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1532 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1533 $add_save_lastsearch_values = 1;
1534 }
1535 if ($add_save_lastsearch_values) {
1536 $url .= '&save_lastsearch_values=1';
1537 }
1538 }
1539
1540 $linkclose = '';
1541 if (empty($notooltip)) {
1542 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1543 $label = $langs->trans("ShowMyObject");
1544 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1545 }
1546 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
1547 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
1548 } else {
1549 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1550 }
1551
1552 $linkstart = '<a href="'.$url.'"';
1553 $linkstart .= $linkclose.'>';
1554 $linkend = '</a>';
1555
1556 $result .= $linkstart;
1557 if ($withpicto) {
1558 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1559 }
1560 if ($withpicto != 2) {
1561 $result .= $this->ref;
1562 }
1563 $result .= $linkend;
1564
1565 global $action, $hookmanager;
1566 $hookmanager->initHooks(array('banktransferdao'));
1567 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1568 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1569 if ($reshook > 0) {
1570 $result = $hookmanager->resPrint;
1571 } else {
1572 $result .= $hookmanager->resPrint;
1573 }
1574
1575 return $result;
1576 }
1577
1578
1585 public function deleteNotificationById($rowid)
1586 {
1587 $sql = "DELETE FROM ".MAIN_DB_PREFIX."notify_def";
1588 $sql .= " WHERE rowid = ".((int) $rowid);
1589
1590 if ($this->db->query($sql)) {
1591 return 0;
1592 } else {
1593 return -1;
1594 }
1595 }
1596
1604 public function deleteNotification($user, $action)
1605 {
1606 if (is_object($user)) {
1607 $userid = $user->id;
1608 } else { // If user is an id
1609 $userid = $user;
1610 }
1611
1612 $sql = "DELETE FROM ".MAIN_DB_PREFIX."notify_def";
1613 $sql .= " WHERE fk_user=".((int) $userid)." AND fk_action='".$this->db->escape($action)."'";
1614
1615 if ($this->db->query($sql)) {
1616 return 0;
1617 } else {
1618 return -1;
1619 }
1620 }
1621
1622 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1631 public function addNotification($db, $user, $action)
1632 {
1633 // phpcs:enable
1634 $result = 0;
1635
1636 if (is_object($user)) {
1637 $userid = $user->id;
1638 } else { // If user is an id
1639 $userid = $user;
1640 }
1641
1642 if ($this->deleteNotification($user, $action) == 0) {
1643 $now = dol_now();
1644
1645 $sql = "INSERT INTO ".MAIN_DB_PREFIX."notify_def (datec,fk_user, fk_soc, fk_contact, fk_action)";
1646 $sql .= " VALUES ('".$this->db->idate($now)."', ".((int) $userid).", 'NULL', 'NULL', '".$this->db->escape($action)."')";
1647
1648 dol_syslog("adnotiff: ".$sql);
1649 if ($this->db->query($sql)) {
1650 $result = 0;
1651 } else {
1652 $result = -1;
1653 dol_syslog(get_class($this)."::addNotification Error $result");
1654 }
1655 }
1656
1657 return $result;
1658 }
1659
1660
1675 public function generate($format = 'ALL', $executiondate = 0, $type = 'direct-debit', $fk_bank_account = 0, $user_dest = 0)
1676 {
1677 global $conf, $langs, $mysoc;
1678
1679 //TODO: Optimize code to read lines in a single function
1680
1681 // Clean params
1682 if (empty($fk_bank_account)) {
1683 $fk_bank_account = ($type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
1684 }
1685
1686 $result = 0;
1687
1688 dol_syslog(get_class($this)."::generate build file=".$this->filename." type=".$type);
1689
1690 $this->file = fopen($this->filename, "w");
1691 if (empty($this->file)) {
1692 $this->error = $langs->trans('ErrorFailedToOpenFile', $this->filename);
1693 return -1;
1694 }
1695
1696 $found = 0;
1697 $this->total = 0;
1698
1699 // Build file for European countries
1700 if ($mysoc->isInEEC()) {
1701 $found++;
1702
1703 if ($type != 'bank-transfer') {
1707 // SEPA Initialisation
1708 $CrLf = "\n";
1709
1710 $now = dol_now();
1711
1712 $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S');
1713
1714 $date_actu = $now;
1715 if (!empty($executiondate)) {
1716 $date_actu = $executiondate;
1717 }
1718
1719 $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d');
1720 $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S');
1721 $fileDebiteurSection = '';
1722 $fileEmetteurSection = '';
1723 $i = 0;
1724
1725 /*
1726 * Section Debitor (sepa Debiteurs bloc lines)
1727 */
1728
1729 $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,";
1730 $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,";
1731 $sql .= " f.ref as reffac, p.fk_facture as idfac,";
1732 $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum";
1733 $sql .= " FROM";
1734 $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,";
1735 $sql .= " ".MAIN_DB_PREFIX."facture as f,";
1736 $sql .= " ".MAIN_DB_PREFIX."prelevement as p,";
1737 $sql .= " ".MAIN_DB_PREFIX."societe as soc,";
1738 $sql .= " ".MAIN_DB_PREFIX."c_country as c,";
1739 $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib";
1740 $sql .= " WHERE pl.fk_prelevement_bons = ".((int) $this->id);
1741 $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1742 $sql .= " AND p.fk_facture = f.rowid";
1743 $sql .= " AND f.fk_soc = soc.rowid";
1744 $sql .= " AND soc.fk_pays = c.rowid";
1745 $sql .= " AND rib.fk_soc = f.fk_soc";
1746 $sql .= " AND rib.default_rib = 1";
1747 $sql .= " AND rib.type = 'ban'";
1748
1749 // Define $fileDebiteurSection. One section DrctDbtTxInf per invoice.
1750 $resql = $this->db->query($sql);
1751 if ($resql) {
1752 $cachearraytotestduplicate = array();
1753
1754 $num = $this->db->num_rows($resql);
1755 while ($i < $num) {
1756 $obj = $this->db->fetch_object($resql);
1757
1758 if (!empty($cachearraytotestduplicate[$obj->idfac])) {
1759 $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid);
1760 $this->invoice_in_error[$obj->idfac] = $this->error;
1761 $result = -2;
1762 break;
1763 }
1764 $cachearraytotestduplicate[$obj->idfac] = $obj->rowid;
1765
1766 $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec);
1767
1768 $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->reffac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type);
1769
1770 $this->total = $this->total + $obj->somme;
1771 $i++;
1772 }
1773 $nbtotalDrctDbtTxInf = $i;
1774 } else {
1775 $this->error = $this->db->lasterror();
1776 fputs($this->file, 'ERROR DEBITOR '.$sql.$CrLf); // DEBITOR = Customers
1777 $result = -2;
1778 }
1779
1780 // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf
1781 if ($result != -2) {
1782 $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type, $fk_bank_account);
1783 }
1784
1788 // SEPA File Header
1789 fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf);
1790 fputs($this->file, '<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'.$CrLf);
1791 fputs($this->file, ' <CstmrDrctDbtInitn>'.$CrLf);
1792 // SEPA Group header
1793 fputs($this->file, ' <GrpHdr>'.$CrLf);
1794 fputs($this->file, ' <MsgId>'.('DD/'.$dateTime_YMD.'/REF'.$this->id).'</MsgId>'.$CrLf);
1795 fputs($this->file, ' <CreDtTm>'.$dateTime_ECMA.'</CreDtTm>'.$CrLf);
1796 fputs($this->file, ' <NbOfTxs>'.$i.'</NbOfTxs>'.$CrLf);
1797 fputs($this->file, ' <CtrlSum>'.$this->total.'</CtrlSum>'.$CrLf);
1798 fputs($this->file, ' <InitgPty>'.$CrLf);
1799 fputs($this->file, ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf);
1800 fputs($this->file, ' <Id>'.$CrLf);
1801 fputs($this->file, ' <PrvtId>'.$CrLf);
1802 fputs($this->file, ' <Othr>'.$CrLf);
1803 fputs($this->file, ' <Id>'.$this->emetteur_ics.'</Id>'.$CrLf);
1804 fputs($this->file, ' </Othr>'.$CrLf);
1805 fputs($this->file, ' </PrvtId>'.$CrLf);
1806 fputs($this->file, ' </Id>'.$CrLf);
1807 fputs($this->file, ' </InitgPty>'.$CrLf);
1808 fputs($this->file, ' </GrpHdr>'.$CrLf);
1809 // SEPA File Emetteur
1810 if ($result != -2) {
1811 fputs($this-> file, $fileEmetteurSection);
1812 }
1813 // SEPA File Debiteurs
1814 if ($result != -2) {
1815 fputs($this-> file, $fileDebiteurSection);
1816 }
1817 // SEPA FILE FOOTER
1818 fputs($this->file, ' </PmtInf>'.$CrLf);
1819 fputs($this->file, ' </CstmrDrctDbtInitn>'.$CrLf);
1820 fputs($this->file, '</Document>'.$CrLf);
1821 } else {
1825 // SEPA Initialisation
1826 $CrLf = "\n";
1827
1828 $now = dol_now();
1829
1830 $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S');
1831
1832 $date_actu = $now;
1833 if (!empty($executiondate)) {
1834 $date_actu = $executiondate;
1835 }
1836
1837 $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d');
1838 $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S');
1839 $fileCrediteurSection = '';
1840 $fileEmetteurSection = '';
1841 $i = 0;
1842
1843 /*
1844 * Section Creditor (sepa Crediteurs bloc lines)
1845 */
1846 if (!empty($user_dest)) {
1847 $sql = "SELECT u.rowid as userId, u.address, u.zip, u.town, c.code as country_code, CONCAT(u.firstname,' ',u.lastname) as nom,";
1848 $sql .= " pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,";
1849 $sql .= " s.ref as reffac, p.fk_salary as idfac,";
1850 $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, '' as rum, '' as date_rum";
1851 $sql .= " FROM";
1852 $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,";
1853 $sql .= " ".MAIN_DB_PREFIX."salary as s,";
1854 $sql .= " ".MAIN_DB_PREFIX."prelevement as p,";
1855 $sql .= " ".MAIN_DB_PREFIX."user as u";
1856 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON u.fk_country = c.rowid,";
1857 $sql .= " ".MAIN_DB_PREFIX."user_rib as rib";
1858 $sql .= " WHERE pl.fk_prelevement_bons=".((int) $this->id);
1859 $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1860 $sql .= " AND p.fk_salary = s.rowid";
1861 $sql .= " AND s.fk_user = u.rowid";
1862 $sql .= " AND rib.fk_user = s.fk_user";
1863 } else {
1864 $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,";
1865 $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,";
1866 $sql .= " f.ref as reffac, f.ref_supplier as fac_ref_supplier, p.fk_facture_fourn as idfac,";
1867 $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum";
1868 $sql .= " FROM";
1869 $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,";
1870 $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,";
1871 $sql .= " ".MAIN_DB_PREFIX."prelevement as p,";
1872 $sql .= " ".MAIN_DB_PREFIX."societe as soc";
1873 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON soc.fk_pays = c.rowid,";
1874 $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib";
1875 $sql .= " WHERE pl.fk_prelevement_bons = ".((int) $this->id);
1876 $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1877 $sql .= " AND p.fk_facture_fourn = f.rowid";
1878 $sql .= " AND f.fk_soc = soc.rowid";
1879 $sql .= " AND rib.fk_soc = f.fk_soc";
1880 $sql .= " AND rib.default_rib = 1";
1881 $sql .= " AND rib.type = 'ban'";
1882 }
1883 // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice.
1884 $resql = $this->db->query($sql);
1885 if ($resql) {
1886 $cachearraytotestduplicate = array();
1887
1888 $num = $this->db->num_rows($resql);
1889 while ($i < $num) {
1890 $obj = $this->db->fetch_object($resql);
1891 if (!empty($cachearraytotestduplicate[$obj->idfac])) {
1892 $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid);
1893 $this->invoice_in_error[$obj->idfac] = $this->error;
1894 $result = -2;
1895 break;
1896 }
1897 $cachearraytotestduplicate[$obj->idfac] = $obj->rowid;
1898
1899 $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec);
1900 $refobj = $obj->reffac;
1901 if (empty($refobj) && !empty($user_dest)) { // If ref of salary not defined, we force a value
1902 $refobj = "SAL".$obj->idfac;
1903 }
1904
1905 $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $refobj, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type, $obj->fac_ref_supplier);
1906
1907 $this->total = $this->total + $obj->somme;
1908 $i++;
1909 }
1910 $nbtotalDrctDbtTxInf = $i;
1911 } else {
1912 $this->error = $this->db->lasterror();
1913 fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers
1914 $result = -2;
1915 }
1916 // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf
1917 if ($result != -2) {
1918 $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type);
1919 }
1920
1924 // SEPA File Header
1925 fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf);
1926 fputs($this->file, '<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'.$CrLf);
1927 fputs($this->file, ' <CstmrCdtTrfInitn>'.$CrLf);
1928 // SEPA Group header
1929 fputs($this->file, ' <GrpHdr>'.$CrLf);
1930 fputs($this->file, ' <MsgId>'.('TRF/'.$dateTime_YMD.'/REF'.$this->id).'</MsgId>'.$CrLf);
1931 fputs($this->file, ' <CreDtTm>'.$dateTime_ECMA.'</CreDtTm>'.$CrLf);
1932 fputs($this->file, ' <NbOfTxs>'.$i.'</NbOfTxs>'.$CrLf);
1933 fputs($this->file, ' <CtrlSum>'.$this->total.'</CtrlSum>'.$CrLf);
1934 fputs($this->file, ' <InitgPty>'.$CrLf);
1935 fputs($this->file, ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf);
1936 fputs($this->file, ' <Id>'.$CrLf);
1937 fputs($this->file, ' <PrvtId>'.$CrLf);
1938 fputs($this->file, ' <Othr>'.$CrLf);
1939 fputs($this->file, ' <Id>'.$this->emetteur_ics.'</Id>'.$CrLf);
1940 fputs($this->file, ' </Othr>'.$CrLf);
1941 fputs($this->file, ' </PrvtId>'.$CrLf);
1942 fputs($this->file, ' </Id>'.$CrLf);
1943 fputs($this->file, ' </InitgPty>'.$CrLf);
1944 fputs($this->file, ' </GrpHdr>'.$CrLf);
1945 // SEPA File Emetteur (mycompany)
1946 if ($result != -2) {
1947 fputs($this-> file, $fileEmetteurSection);
1948 }
1949 // SEPA File Creditors
1950 if ($result != -2) {
1951 fputs($this-> file, $fileCrediteurSection);
1952 }
1953 // SEPA FILE FOOTER
1954 fputs($this->file, ' </PmtInf>'.$CrLf);
1955 fputs($this->file, ' </CstmrCdtTrfInitn>'.$CrLf);
1956 fputs($this->file, '</Document>'.$CrLf);
1957 }
1958 }
1959
1960 // Build file for Other Countries with unknow format
1961 if (!$found) {
1962 if ($type != 'bank-transfer') {
1963 $sql = "SELECT pl.amount";
1964 $sql .= " FROM";
1965 $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,";
1966 $sql .= " ".MAIN_DB_PREFIX."facture as f,";
1967 $sql .= " ".MAIN_DB_PREFIX."prelevement as p";
1968 $sql .= " WHERE pl.fk_prelevement_bons = ".((int) $this->id);
1969 $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1970 $sql .= " AND p.fk_facture = f.rowid";
1971
1972 // Lines
1973 $i = 0;
1974 $resql = $this->db->query($sql);
1975 if ($resql) {
1976 $num = $this->db->num_rows($resql);
1977
1978 while ($i < $num) {
1979 $obj = $this->db->fetch_object($resql);
1980 $this->total = $this->total + $obj->amount;
1981
1982 // TODO Write record into file
1983 $i++;
1984 }
1985 } else {
1986 $result = -2;
1987 }
1988 } else {
1989 $sql = "SELECT pl.amount";
1990 $sql .= " FROM";
1991 $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,";
1992 $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,";
1993 $sql .= " ".MAIN_DB_PREFIX."prelevement as p";
1994 $sql .= " WHERE pl.fk_prelevement_bons = ".((int) $this->id);
1995 $sql .= " AND pl.rowid = p.fk_prelevement_lignes";
1996 $sql .= " AND p.fk_facture_fourn = f.rowid";
1997 // Lines
1998 $i = 0;
1999 $resql = $this->db->query($sql);
2000 if ($resql) {
2001 $num = $this->db->num_rows($resql);
2002
2003 while ($i < $num) {
2004 $obj = $this->db->fetch_object($resql);
2005 $this->total = $this->total + $obj->amount;
2006
2007 // TODO Write record into file
2008 $i++;
2009 }
2010 } else {
2011 $result = -2;
2012 }
2013 }
2014
2015 $langs->load('withdrawals');
2016
2017 // TODO Add here code to generate a generic file
2018 fputs($this->file, $langs->transnoentitiesnoconv('WithdrawalFileNotCapable', $mysoc->country_code));
2019 }
2020
2021 fclose($this->file);
2022 dolChmod($this->filename);
2023
2024 return $result;
2025 }
2026
2027
2036 public static function buildRumNumber($row_code_client, $row_datec, $row_drum)
2037 {
2038 global $langs;
2039
2040 $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation)
2041
2042 // 3 char + '-' + 12 + '-' + id + '-' + code Must be lower than 32.
2043 return $pre.'-'.dol_print_date($row_datec, 'dayhourlogsmall').'-'.dol_trunc($row_drum.($row_code_client ? '-'.$row_code_client : ''), 13, 'right', 'UTF-8', 1);
2044 }
2045
2046
2047 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2064 public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '', $type = 'direct-debit')
2065 {
2066 // phpcs:enable
2067 fputs($this->file, "06");
2068 fputs($this->file, "08"); // Prelevement ordinaire
2069
2070 fputs($this->file, " "); // Zone Reservee B2
2071
2072 fputs($this->file, $this->emetteur_ics); // ICS
2073
2074 // Date d'echeance C1
2075
2076 fputs($this->file, " ");
2077 fputs($this->file, dol_print_date($this->date_echeance, "%d%m", 'gmt'));
2078 fputs($this->file, substr(dol_print_date($this->date_echeance, "%y", 'gmt'), 1));
2079
2080 // Raison Sociale Destinataire C2
2081
2082 fputs($this->file, substr(strtoupper($client_nom)." ", 0, 24));
2083
2084 // Domiciliation facultative D1
2085 $domiciliation = strtr($rib_dom, array(" " => "-", CHR(13) => " ", CHR(10) => ""));
2086 fputs($this->file, substr($domiciliation." ", 0, 24));
2087
2088 // Zone Reservee D2
2089
2090 fputs($this->file, substr(" ", 0, 8));
2091
2092 // Code Guichet D3
2093
2094 fputs($this->file, $rib_guichet);
2095
2096 // Numero de compte D4
2097
2098 fputs($this->file, substr("000000000000000".$rib_number, -11));
2099
2100 // Zone E Montant
2101
2102 $montant = (round($amount, 2) * 100);
2103
2104 fputs($this->file, substr("000000000000000".$montant, -16));
2105
2106 // Label F
2107
2108 fputs($this->file, substr("*_".$ref."_RDVnet".$rowid." ", 0, 31));
2109
2110 // Code etablissement G1
2111
2112 fputs($this->file, $rib_banque);
2113
2114 // Zone Reservee G2
2115
2116 fputs($this->file, substr(" ", 0, 5));
2117
2118 fputs($this->file, "\n");
2119 }
2120
2121
2122 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2148 public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum, $type = 'direct-debit', $row_comment = '')
2149 {
2150 // phpcs:enable
2151 global $conf;
2152
2153 include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
2154
2155 $CrLf = "\n";
2156 $Rowing = sprintf("%010d", $row_idfac);
2157
2158 // Define value for RUM
2159 // Example: RUM-CustomerCode-CustomerBankAccountId-01424448606 (note: Date is the timestamp of the date of creation of CustomerBankAccountId)
2160 $Rum = (empty($row_rum) ? $this->buildRumNumber($row_code_client, $row_datec, $row_drum) : $row_rum);
2161
2162 // Define date of RUM signature
2163 $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d');
2164
2165 if ($type != 'bank-transfer') {
2166 // SEPA Paiement Information of buyer for Direct Debit
2167 $XML_DEBITOR = '';
2168 $XML_DEBITOR .= ' <DrctDbtTxInf>'.$CrLf;
2169 $XML_DEBITOR .= ' <PmtId>'.$CrLf;
2170 // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum)
2171 $XML_DEBITOR .= ' <EndToEndId>'.((getDolGlobalString('PRELEVEMENT_END_TO_END') != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('DD-'.dol_trunc($row_idfac.'-'.$row_ref, 20, 'right', 'UTF-8', 1)).'-'.$Rowing).'</EndToEndId>'.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters
2172 $XML_DEBITOR .= ' </PmtId>'.$CrLf;
2173 $XML_DEBITOR .= ' <InstdAmt Ccy="EUR">'.round($row_somme, 2).'</InstdAmt>'.$CrLf;
2174 $XML_DEBITOR .= ' <DrctDbtTx>'.$CrLf;
2175 $XML_DEBITOR .= ' <MndtRltdInf>'.$CrLf;
2176 $XML_DEBITOR .= ' <MndtId>'.$Rum.'</MndtId>'.$CrLf;
2177 $XML_DEBITOR .= ' <DtOfSgntr>'.$DtOfSgntr.'</DtOfSgntr>'.$CrLf;
2178 $XML_DEBITOR .= ' <AmdmntInd>false</AmdmntInd>'.$CrLf;
2179 $XML_DEBITOR .= ' </MndtRltdInf>'.$CrLf;
2180 $XML_DEBITOR .= ' </DrctDbtTx>'.$CrLf;
2181 $XML_DEBITOR .= ' <DbtrAgt>'.$CrLf;
2182 $XML_DEBITOR .= ' <FinInstnId>'.$CrLf;
2183 $XML_DEBITOR .= ' <BIC>'.$row_bic.'</BIC>'.$CrLf;
2184 $XML_DEBITOR .= ' </FinInstnId>'.$CrLf;
2185 $XML_DEBITOR .= ' </DbtrAgt>'.$CrLf;
2186 $XML_DEBITOR .= ' <Dbtr>'.$CrLf;
2187 $XML_DEBITOR .= ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ' '))).'</Nm>'.$CrLf;
2188 $XML_DEBITOR .= ' <PstlAdr>'.$CrLf;
2189 $XML_DEBITOR .= ' <Ctry>'.$row_country_code.'</Ctry>'.$CrLf;
2190 $addressline1 = strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""));
2191 $addressline2 = strtr($row_zip.(($row_zip && $row_town) ? ' ' : (string) $row_town), array(CHR(13) => ", ", CHR(10) => ""));
2192 if (trim($addressline1)) {
2193 $XML_DEBITOR .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2194 }
2195 if (trim($addressline2)) {
2196 $XML_DEBITOR .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2197 }
2198 $XML_DEBITOR .= ' </PstlAdr>'.$CrLf;
2199 $XML_DEBITOR .= ' </Dbtr>'.$CrLf;
2200 $XML_DEBITOR .= ' <DbtrAcct>'.$CrLf;
2201 $XML_DEBITOR .= ' <Id>'.$CrLf;
2202 $XML_DEBITOR .= ' <IBAN>'.preg_replace('/\s/', '', $row_iban).'</IBAN>'.$CrLf;
2203 $XML_DEBITOR .= ' </Id>'.$CrLf;
2204 $XML_DEBITOR .= ' </DbtrAcct>'.$CrLf;
2205 $XML_DEBITOR .= ' <RmtInf>'.$CrLf;
2206 // A string with some information on payment - 140 max
2207 $XML_DEBITOR .= ' <Ustrd>'.getDolGlobalString('PRELEVEMENT_USTRD', dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($row_ref.($row_comment ? ' - '.$row_comment : '')), '', '', '', 1), 135, 'right', 'UTF-8', 1))).'</Ustrd>'.$CrLf; // Free unstuctured data - 140 max
2208 $XML_DEBITOR .= ' </RmtInf>'.$CrLf;
2209 $XML_DEBITOR .= ' </DrctDbtTxInf>'.$CrLf;
2210 return $XML_DEBITOR;
2211 } else {
2212 // SEPA Payment Information of seller for Credit Transfer
2213 $XML_CREDITOR = '';
2214 $XML_CREDITOR .= ' <CdtTrfTxInf>'.$CrLf;
2215 $XML_CREDITOR .= ' <PmtId>'.$CrLf;
2216 // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum)
2217 $XML_CREDITOR .= ' <EndToEndId>'.((getDolGlobalString('PRELEVEMENT_END_TO_END') != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('CT-'.dol_trunc($row_idfac.'-'.$row_ref, 20, 'right', 'UTF-8', 1)).'-'.$Rowing).'</EndToEndId>'.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters
2218 $XML_CREDITOR .= ' </PmtId>'.$CrLf;
2219 if (!empty($this->sepa_xml_pti_in_ctti)) {
2220 $XML_CREDITOR .= ' <PmtTpInf>' . $CrLf;
2221
2222 // Can be 'NORM' for normal or 'HIGH' for high priority level
2223 if (getDolGlobalString('PAYMENTBYBANKTRANSFER_FORCE_HIGH_PRIORITY')) {
2224 $instrprty = 'HIGH';
2225 } else {
2226 $instrprty = 'NORM';
2227 }
2228 $XML_CREDITOR .= ' <InstrPrty>'.$instrprty.'</InstrPrty>' . $CrLf;
2229 $XML_CREDITOR .= ' <SvcLvl>' . $CrLf;
2230 $XML_CREDITOR .= ' <Cd>SEPA</Cd>' . $CrLf;
2231 $XML_CREDITOR .= ' </SvcLvl>' . $CrLf;
2232 $XML_CREDITOR .= ' <CtgyPurp>' . $CrLf;
2233 $XML_CREDITOR .= ' <Cd>CORE</Cd>' . $CrLf;
2234 $XML_CREDITOR .= ' </CtgyPurp>' . $CrLf;
2235 $XML_CREDITOR .= ' </PmtTpInf>' . $CrLf;
2236 }
2237 $XML_CREDITOR .= ' <Amt>'.$CrLf;
2238 $XML_CREDITOR .= ' <InstdAmt Ccy="EUR">'.round($row_somme, 2).'</InstdAmt>'.$CrLf;
2239 $XML_CREDITOR .= ' </Amt>'.$CrLf;
2240 /*
2241 $XML_CREDITOR .= ' <DrctDbtTx>'.$CrLf;
2242 $XML_CREDITOR .= ' <MndtRltdInf>'.$CrLf;
2243 $XML_CREDITOR .= ' <MndtId>'.$Rum.'</MndtId>'.$CrLf;
2244 $XML_CREDITOR .= ' <DtOfSgntr>'.$DtOfSgntr.'</DtOfSgntr>'.$CrLf;
2245 $XML_CREDITOR .= ' <AmdmntInd>false</AmdmntInd>'.$CrLf;
2246 $XML_CREDITOR .= ' </MndtRltdInf>'.$CrLf;
2247 $XML_CREDITOR .= ' </DrctDbtTx>'.$CrLf;
2248 */
2249 //$XML_CREDITOR .= ' <ChrgBr>SLEV</ChrgBr>'.$CrLf;
2250 $XML_CREDITOR .= ' <CdtrAgt>'.$CrLf;
2251 $XML_CREDITOR .= ' <FinInstnId>'.$CrLf;
2252 $XML_CREDITOR .= ' <BIC>'.$row_bic.'</BIC>'.$CrLf;
2253 $XML_CREDITOR .= ' </FinInstnId>'.$CrLf;
2254 $XML_CREDITOR .= ' </CdtrAgt>'.$CrLf;
2255 $XML_CREDITOR .= ' <Cdtr>'.$CrLf;
2256 $XML_CREDITOR .= ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ' '))).'</Nm>'.$CrLf;
2257 $XML_CREDITOR .= ' <PstlAdr>'.$CrLf;
2258 $XML_CREDITOR .= ' <Ctry>'.$row_country_code.'</Ctry>'.$CrLf;
2259 $addressline1 = strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""));
2260 $addressline2 = strtr($row_zip.(($row_zip && $row_town) ? ' ' : (string) $row_town), array(CHR(13) => ", ", CHR(10) => ""));
2261 if (trim($addressline1)) {
2262 $XML_CREDITOR .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2263 }
2264 if (trim($addressline2)) {
2265 $XML_CREDITOR .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2266 }
2267 $XML_CREDITOR .= ' </PstlAdr>'.$CrLf;
2268 $XML_CREDITOR .= ' </Cdtr>'.$CrLf;
2269 $XML_CREDITOR .= ' <CdtrAcct>'.$CrLf;
2270 $XML_CREDITOR .= ' <Id>'.$CrLf;
2271 $XML_CREDITOR .= ' <IBAN>'.preg_replace('/\s/', '', $row_iban).'</IBAN>'.$CrLf;
2272 $XML_CREDITOR .= ' </Id>'.$CrLf;
2273 $XML_CREDITOR .= ' </CdtrAcct>'.$CrLf;
2274 $XML_CREDITOR .= ' <RmtInf>'.$CrLf;
2275 // A string with some information on payment - 140 max
2276 $XML_CREDITOR .= ' <Ustrd>'.getDolGlobalString('CREDITTRANSFER_USTRD', dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($row_ref.($row_comment ? ' - '.$row_comment : '')), '', '', '', 1), 135, 'right', 'UTF-8', 1))).'</Ustrd>'.$CrLf; // Free unstructured data - 140 max
2277 $XML_CREDITOR .= ' </RmtInf>'.$CrLf;
2278 $XML_CREDITOR .= ' </CdtTrfTxInf>'.$CrLf;
2279 return $XML_CREDITOR;
2280 }
2281 }
2282
2283
2284 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2292 public function EnregEmetteur($type = 'direct-debit')
2293 {
2294 // phpcs:enable
2295 fputs($this->file, "03");
2296 fputs($this->file, "08"); // Prelevement ordinaire
2297
2298 fputs($this->file, " "); // Zone Reservee B2
2299
2300 fputs($this->file, $this->emetteur_ics); // ICS
2301
2302 // Date d'echeance C1
2303
2304 fputs($this->file, " ");
2305 fputs($this->file, dol_print_date($this->date_echeance, "%d%m", 'gmt'));
2306 fputs($this->file, substr(dol_print_date($this->date_echeance, "%y", 'gmt'), 1));
2307
2308 // Raison Sociale C2
2309
2310 fputs($this->file, substr($this->raison_sociale." ", 0, 24));
2311
2312 // Reference de la remise creancier D1 sur 7 caracteres
2313
2314 fputs($this->file, substr($this->reference_remise." ", 0, 7));
2315
2316 // Zone Reservee D1-2
2317
2318 fputs($this->file, substr(" ", 0, 17));
2319
2320 // Zone Reservee D2
2321
2322 fputs($this->file, substr(" ", 0, 2));
2323 fputs($this->file, "E");
2324 fputs($this->file, substr(" ", 0, 5));
2325
2326 // Code Guichet D3
2327
2328 fputs($this->file, $this->emetteur_code_guichet);
2329
2330 // Numero de compte D4
2331
2332 fputs($this->file, substr("000000000000000".$this->emetteur_numero_compte, -11));
2333
2334 // Zone Reservee E
2335
2336 fputs($this->file, substr(" ", 0, 16));
2337
2338 // Zone Reservee F
2339
2340 fputs($this->file, substr(" ", 0, 31));
2341
2342 // Code etablissement
2343
2344 fputs($this->file, $this->emetteur_code_banque);
2345
2346 // Zone Reservee G
2347
2348 fputs($this->file, substr(" ", 0, 5));
2349
2350 fputs($this->file, "\n");
2351 }
2352
2353
2354 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2370 public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST', $type = 'direct-debit', $fk_bank_account = 0)
2371 {
2372 // phpcs:enable
2373
2374 // Clean parameters
2375 $dateTime_YMD = dol_print_date($ladate, '%Y%m%d');
2376 $dateTime_ETAD = dol_print_date($ladate, '%Y-%m-%d');
2377 $dateTime_YMDHMS = dol_print_date($ladate, '%Y-%m-%dT%H:%M:%S');
2378
2379 // Clean params
2380 if (empty($fk_bank_account)) {
2381 $fk_bank_account = ($type == 'bank-transfer' ? getDolGlobalInt('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalInt('PRELEVEMENT_ID_BANKACCOUNT'));
2382 }
2383
2384 // Get data of bank account
2385 $account = new Account($this->db);
2386 if ($account->fetch($fk_bank_account) > 0) {
2387 $this->emetteur_code_banque = $account->code_banque;
2388 $this->emetteur_code_guichet = $account->code_guichet;
2389 $this->emetteur_numero_compte = $account->number;
2390 $this->emetteur_number_key = $account->cle_rib;
2391 $this->sepa_xml_pti_in_ctti = (bool) $account->pti_in_ctti;
2392 $this->emetteur_iban = $account->iban;
2393 $this->emetteur_bic = $account->bic;
2394
2395 $this->emetteur_ics = (($type == 'bank-transfer' && getDolGlobalString("SEPA_USE_IDS")) ? $account->ics_transfer : $account->ics); // Ex: PRELEVEMENT_ICS = "FR78ZZZ123456";
2396
2397 $this->raison_sociale = $account->proprio;
2398 }
2399
2400 // Get pending payments
2401 $sql = "SELECT rowid, ref";
2402 $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as pb";
2403 $sql .= " WHERE pb.rowid = ".((int) $this->id);
2404
2405 $resql = $this->db->query($sql);
2406 if ($resql) {
2407 $obj = $this->db->fetch_object($resql);
2408
2409 $country = explode(':', $configuration->global->MAIN_INFO_SOCIETE_COUNTRY);
2410 $IdBon = sprintf("%05d", $obj->rowid);
2411 $RefBon = $obj->ref;
2412
2413 if ($type != 'bank-transfer') {
2414 // SEPA Paiement Information of my company for Direct Debit
2415 $XML_SEPA_INFO = '';
2416 $XML_SEPA_INFO .= ' <PmtInf>'.$CrLf;
2417 $XML_SEPA_INFO .= ' <PmtInfId>'.('DD/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).'</PmtInfId>'.$CrLf;
2418 $XML_SEPA_INFO .= ' <PmtMtd>DD</PmtMtd>'.$CrLf;
2419 $XML_SEPA_INFO .= ' <NbOfTxs>'.$nombre.'</NbOfTxs>'.$CrLf;
2420 $XML_SEPA_INFO .= ' <CtrlSum>'.$total.'</CtrlSum>'.$CrLf;
2421 $XML_SEPA_INFO .= ' <PmtTpInf>'.$CrLf;
2422 $XML_SEPA_INFO .= ' <SvcLvl>'.$CrLf;
2423 $XML_SEPA_INFO .= ' <Cd>SEPA</Cd>'.$CrLf;
2424 $XML_SEPA_INFO .= ' </SvcLvl>'.$CrLf;
2425 $XML_SEPA_INFO .= ' <LclInstrm>'.$CrLf;
2426 $XML_SEPA_INFO .= ' <Cd>CORE</Cd>'.$CrLf;
2427 $XML_SEPA_INFO .= ' </LclInstrm>'.$CrLf;
2428 $XML_SEPA_INFO .= ' <SeqTp>'.$format.'</SeqTp>'.$CrLf;
2429 $XML_SEPA_INFO .= ' </PmtTpInf>'.$CrLf;
2430 $XML_SEPA_INFO .= ' <ReqdColltnDt>'.$dateTime_ETAD.'</ReqdColltnDt>'.$CrLf;
2431 $XML_SEPA_INFO .= ' <Cdtr>'.$CrLf;
2432 $XML_SEPA_INFO .= ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf;
2433 $XML_SEPA_INFO .= ' <PstlAdr>'.$CrLf;
2434 $XML_SEPA_INFO .= ' <Ctry>'.$country[1].'</Ctry>'.$CrLf;
2435 $addressline1 = strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""));
2436 $addressline2 = strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""));
2437 if ($addressline1) {
2438 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2439 }
2440 if ($addressline2) {
2441 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2442 }
2443 $XML_SEPA_INFO .= ' </PstlAdr>'.$CrLf;
2444 $XML_SEPA_INFO .= ' </Cdtr>'.$CrLf;
2445 $XML_SEPA_INFO .= ' <CdtrAcct>'.$CrLf;
2446 $XML_SEPA_INFO .= ' <Id>'.$CrLf;
2447 $XML_SEPA_INFO .= ' <IBAN>'.preg_replace('/\s/', '', $this->emetteur_iban).'</IBAN>'.$CrLf;
2448 $XML_SEPA_INFO .= ' </Id>'.$CrLf;
2449 $XML_SEPA_INFO .= ' </CdtrAcct>'.$CrLf;
2450 $XML_SEPA_INFO .= ' <CdtrAgt>'.$CrLf;
2451 $XML_SEPA_INFO .= ' <FinInstnId>'.$CrLf;
2452 $XML_SEPA_INFO .= ' <BIC>'.$this->emetteur_bic.'</BIC>'.$CrLf;
2453 $XML_SEPA_INFO .= ' </FinInstnId>'.$CrLf;
2454 $XML_SEPA_INFO .= ' </CdtrAgt>'.$CrLf;
2455 /* $XML_SEPA_INFO .= ' <UltmtCdtr>'.$CrLf;
2456 $XML_SEPA_INFO .= ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf;
2457 $XML_SEPA_INFO .= ' <PstlAdr>'.$CrLf;
2458 $XML_SEPA_INFO .= ' <Ctry>'.$country[1].'</Ctry>'.$CrLf;
2459 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2460 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2461 $XML_SEPA_INFO .= ' </PstlAdr>'.$CrLf;
2462 $XML_SEPA_INFO .= ' </UltmtCdtr>'.$CrLf;*/
2463 $XML_SEPA_INFO .= ' <ChrgBr>SLEV</ChrgBr>'.$CrLf; // Field "Responsible of fees". Must be SLEV
2464 $XML_SEPA_INFO .= ' <CdtrSchmeId>'.$CrLf;
2465 $XML_SEPA_INFO .= ' <Id>'.$CrLf;
2466 $XML_SEPA_INFO .= ' <PrvtId>'.$CrLf;
2467 $XML_SEPA_INFO .= ' <Othr>'.$CrLf;
2468 $XML_SEPA_INFO .= ' <Id>'.$this->emetteur_ics.'</Id>'.$CrLf;
2469 $XML_SEPA_INFO .= ' <SchmeNm>'.$CrLf;
2470 $XML_SEPA_INFO .= ' <Prtry>SEPA</Prtry>'.$CrLf;
2471 $XML_SEPA_INFO .= ' </SchmeNm>'.$CrLf;
2472 $XML_SEPA_INFO .= ' </Othr>'.$CrLf;
2473 $XML_SEPA_INFO .= ' </PrvtId>'.$CrLf;
2474 $XML_SEPA_INFO .= ' </Id>'.$CrLf;
2475 $XML_SEPA_INFO .= ' </CdtrSchmeId>'.$CrLf;
2476 } else {
2477 // SEPA Paiement Information of my company for Credit Transfer
2478 $XML_SEPA_INFO = '';
2479 $XML_SEPA_INFO .= ' <PmtInf>'.$CrLf;
2480 $XML_SEPA_INFO .= ' <PmtInfId>'.('TRF/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).'</PmtInfId>'.$CrLf;
2481 $XML_SEPA_INFO .= ' <PmtMtd>TRF</PmtMtd>'.$CrLf;
2482 //$XML_SEPA_INFO .= ' <BtchBookg>False</BtchBookg>'.$CrLf;
2483 $XML_SEPA_INFO .= ' <NbOfTxs>'.$nombre.'</NbOfTxs>'.$CrLf;
2484 $XML_SEPA_INFO .= ' <CtrlSum>'.$total.'</CtrlSum>'.$CrLf;
2485 if (!empty($this->sepa_xml_pti_in_ctti) && !empty($format)) { // @TODO Using $format (FRST ou RCUR) in a section for a Credit Transfer looks strange.
2486 $XML_SEPA_INFO .= ' <PmtTpInf>' . $CrLf;
2487 $XML_SEPA_INFO .= ' <SvcLvl>' . $CrLf;
2488 $XML_SEPA_INFO .= ' <Cd>SEPA</Cd>' . $CrLf;
2489 $XML_SEPA_INFO .= ' </SvcLvl>' . $CrLf;
2490 $XML_SEPA_INFO .= ' <LclInstrm>' . $CrLf;
2491 $XML_SEPA_INFO .= ' <Cd>CORE</Cd>' . $CrLf;
2492 $XML_SEPA_INFO .= ' </LclInstrm>' . $CrLf;
2493 $XML_SEPA_INFO .= ' <SeqTp>' . $format . '</SeqTp>' . $CrLf;
2494 $XML_SEPA_INFO .= ' </PmtTpInf>' . $CrLf;
2495 }
2496 $XML_SEPA_INFO .= ' <ReqdExctnDt>'.dol_print_date($dateTime_ETAD, 'dayrfc').'</ReqdExctnDt>'.$CrLf;
2497 $XML_SEPA_INFO .= ' <Dbtr>'.$CrLf;
2498 $XML_SEPA_INFO .= ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf;
2499 $XML_SEPA_INFO .= ' <PstlAdr>'.$CrLf;
2500 $XML_SEPA_INFO .= ' <Ctry>'.$country[1].'</Ctry>'.$CrLf;
2501 $addressline1 = strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""));
2502 $addressline2 = strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""));
2503 if ($addressline1) {
2504 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2505 }
2506 if ($addressline2) {
2507 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2508 }
2509 $XML_SEPA_INFO .= ' </PstlAdr>'.$CrLf;
2510 $XML_SEPA_INFO .= ' </Dbtr>'.$CrLf;
2511 $XML_SEPA_INFO .= ' <DbtrAcct>'.$CrLf;
2512 $XML_SEPA_INFO .= ' <Id>'.$CrLf;
2513 $XML_SEPA_INFO .= ' <IBAN>'.preg_replace('/\s/', '', $this->emetteur_iban).'</IBAN>'.$CrLf;
2514 $XML_SEPA_INFO .= ' </Id>'.$CrLf;
2515 $XML_SEPA_INFO .= ' </DbtrAcct>'.$CrLf;
2516 $XML_SEPA_INFO .= ' <DbtrAgt>'.$CrLf;
2517 $XML_SEPA_INFO .= ' <FinInstnId>'.$CrLf;
2518 $XML_SEPA_INFO .= ' <BIC>'.$this->emetteur_bic.'</BIC>'.$CrLf;
2519 $XML_SEPA_INFO .= ' </FinInstnId>'.$CrLf;
2520 $XML_SEPA_INFO .= ' </DbtrAgt>'.$CrLf;
2521 /* $XML_SEPA_INFO .= ' <UltmtCdtr>'.$CrLf;
2522 $XML_SEPA_INFO .= ' <Nm>'.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).'</Nm>'.$CrLf;
2523 $XML_SEPA_INFO .= ' <PstlAdr>'.$CrLf;
2524 $XML_SEPA_INFO .= ' <Ctry>'.$country[1].'</Ctry>'.$CrLf;
2525 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2526 $XML_SEPA_INFO .= ' <AdrLine>'.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), ' '), 70, 'right', 'UTF-8', 1)).'</AdrLine>'.$CrLf;
2527 $XML_SEPA_INFO .= ' </PstlAdr>'.$CrLf;
2528 $XML_SEPA_INFO .= ' </UltmtCdtr>'.$CrLf;*/
2529 $XML_SEPA_INFO .= ' <ChrgBr>SLEV</ChrgBr>'.$CrLf; // Field "Responsible of fees". Must be SLEV
2530 /*$XML_SEPA_INFO .= ' <CdtrSchmeId>'.$CrLf;
2531 $XML_SEPA_INFO .= ' <Id>'.$CrLf;
2532 $XML_SEPA_INFO .= ' <PrvtId>'.$CrLf;
2533 $XML_SEPA_INFO .= ' <Othr>'.$CrLf;
2534 $XML_SEPA_INFO .= ' <Id>'.$this->emetteur_ics.'</Id>'.$CrLf;
2535 $XML_SEPA_INFO .= ' <SchmeNm>'.$CrLf;
2536 $XML_SEPA_INFO .= ' <Prtry>SEPA</Prtry>'.$CrLf;
2537 $XML_SEPA_INFO .= ' </SchmeNm>'.$CrLf;
2538 $XML_SEPA_INFO .= ' </Othr>'.$CrLf;
2539 $XML_SEPA_INFO .= ' </PrvtId>'.$CrLf;
2540 $XML_SEPA_INFO .= ' </Id>'.$CrLf;
2541 $XML_SEPA_INFO .= ' </CdtrSchmeId>'.$CrLf;*/
2542 }
2543 } else {
2544 fputs($this->file, 'INCORRECT EMETTEUR '.$this->raison_sociale.$CrLf);
2545 $XML_SEPA_INFO = '';
2546 }
2547 return $XML_SEPA_INFO;
2548 }
2549
2550 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2557 public function EnregTotal($total)
2558 {
2559 // phpcs:enable
2560 fputs($this->file, "08");
2561 fputs($this->file, "08"); // Prelevement ordinaire
2562
2563 fputs($this->file, " "); // Zone Reservee B2
2564
2565 fputs($this->file, $this->emetteur_ics); // ICS
2566
2567 // Reserve C1
2568
2569 fputs($this->file, substr(" ", 0, 12));
2570
2571
2572 // Raison Sociale C2
2573
2574 fputs($this->file, substr(" ", 0, 24));
2575
2576 // D1
2577
2578 fputs($this->file, substr(" ", 0, 24));
2579
2580 // Zone Reservee D2
2581
2582 fputs($this->file, substr(" ", 0, 8));
2583
2584 // Code Guichet D3
2585
2586 fputs($this->file, substr(" ", 0, 5));
2587
2588 // Numero de compte D4
2589
2590 fputs($this->file, substr(" ", 0, 11));
2591
2592 // Zone E Montant
2593
2594 $montant = ($total * 100);
2595
2596 fputs($this->file, substr("000000000000000".$montant, -16));
2597
2598 // Zone Reservee F
2599
2600 fputs($this->file, substr(" ", 0, 31));
2601
2602 // Code etablissement
2603
2604 fputs($this->file, substr(" ", 0, 5));
2605
2606 // Zone Reservee F
2607
2608 fputs($this->file, substr(" ", 0, 5));
2609
2610 fputs($this->file, "\n");
2611 }
2612
2619 public function getLibStatut($mode = 0)
2620 {
2621 return $this->LibStatut($this->statut, $mode);
2622 }
2623
2624 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2632 public function LibStatut($status, $mode = 0)
2633 {
2634 // phpcs:enable
2635 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
2636 global $langs;
2637 //$langs->load("mymodule");
2638 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('StatusWaiting');
2639 $this->labelStatus[self::STATUS_TRANSFERED] = $langs->transnoentitiesnoconv('StatusTrans');
2640 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('StatusWaiting');
2641 $this->labelStatusShort[self::STATUS_TRANSFERED] = $langs->transnoentitiesnoconv('StatusTrans');
2642 if ($this->type == 'bank-transfer') {
2643 $this->labelStatus[self::STATUS_DEBITED] = $langs->transnoentitiesnoconv('StatusDebited');
2644 $this->labelStatusShort[self::STATUS_DEBITED] = $langs->transnoentitiesnoconv('StatusDebited');
2645 } else {
2646 $this->labelStatus[self::STATUS_CREDITED] = $langs->transnoentitiesnoconv('StatusCredited');
2647 $this->labelStatusShort[self::STATUS_CREDITED] = $langs->transnoentitiesnoconv('StatusCredited');
2648 }
2649 }
2650
2651 $statusType = 'status1';
2652 if ($status == self::STATUS_TRANSFERED) {
2653 $statusType = 'status3';
2654 }
2655 if ($status == self::STATUS_CREDITED || $status == self::STATUS_DEBITED) {
2656 $statusType = 'status6';
2657 }
2658
2659 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
2660 }
2661
2662 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2670 public function load_board($user, $mode)
2671 {
2672 // phpcs:enable
2673 if ($user->socid) {
2674 return -1; // protection pour eviter appel par utilisateur externe
2675 }
2676
2677 /*
2678 if ($mode == 'direct_debit') {
2679 $sql = "SELECT b.rowid, f.datedue as datefin";
2680 $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
2681 $sql .= " WHERE f.entity IN (".getEntity('facture').")";
2682 $sql .= " AND f.total_ttc > 0";
2683 } else {
2684 $sql = "SELECT b.rowid, f.datedue as datefin";
2685 $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
2686 $sql .= " WHERE f.entity IN (".getEntity('facture_fourn').")";
2687 $sql .= " AND f.total_ttc > 0";
2688 }
2689
2690 $resql = $this->db->query($sql);
2691 if ($resql) {
2692 $langs->load("banks");
2693 $now = dol_now();
2694
2695 $response = new WorkboardResponse();
2696 if ($mode == 'direct_debit') {
2697 $response->warning_delay = $conf->prelevement->warning_delay / 60 / 60 / 24;
2698 $response->label = $langs->trans("PendingDirectDebitToComplete");
2699 $response->labelShort = $langs->trans("PendingDirectDebitToCompleteShort");
2700 $response->url = DOL_URL_ROOT.'/compta/prelevement/index.php?leftmenu=checks&mainmenu=bank';
2701 } else {
2702 $response->warning_delay = $conf->paymentbybanktransfer->warning_delay / 60 / 60 / 24;
2703 $response->label = $langs->trans("PendingCreditTransferToComplete");
2704 $response->labelShort = $langs->trans("PendingCreditTransferToCompleteShort");
2705 $response->url = DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php?leftmenu=checks&mainmenu=bank';
2706 }
2707 $response->img = img_object('', "payment");
2708
2709 while ($obj = $this->db->fetch_object($resql)) {
2710 $response->nbtodo++;
2711
2712 if ($this->db->jdate($obj->datefin) < ($now - $conf->withdraw->warning_delay)) {
2713 $response->nbtodolate++;
2714 }
2715 }
2716
2717 $response->nbtodo = 0;
2718 $response->nbtodolate = 0;
2719 // Return workboard only if quantity is not 0
2720 if ($response->nbtodo) {
2721 return $response;
2722 } else {
2723 return 0;
2724 }
2725 } else {
2726 dol_print_error($this->db);
2727 $this->error = $this->db->error();
2728 return -1;
2729 }
2730 */
2731 return 0;
2732 }
2733
2741 public function getKanbanView($option = '', $arraydata = null)
2742 {
2743 global $langs;
2744
2745 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2746
2747 $return = '<div class="box-flex-item box-flex-grow-zero">';
2748 $return .= '<div class="info-box info-box-sm">';
2749 $return .= '<span class="info-box-icon bg-infobox-action">';
2750 $return .= img_picto('', $this->picto);
2751 $return .= '</span>';
2752 $return .= '<div class="info-box-content">';
2753 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
2754 if ($selected >= 0) {
2755 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2756 }
2757 if (property_exists($this, 'date_echeance')) {
2758 $return .= '<br><span class="opacitymedium">'.$langs->trans("Date").'</span> : <span class="info-box-label">'.dol_print_date($this->db->jdate($this->date_echeance), 'day').'</span>';
2759 }
2760 if (property_exists($this, 'total')) {
2761 $return .= '<br><span class="opacitymedium">'.$langs->trans("Amount").'</span> : <span class="amount">'.price($this->total).'</span>';
2762 }
2763 if (method_exists($this, 'LibStatut')) {
2764 $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
2765 }
2766 $return .= '</div>';
2767 $return .= '</div>';
2768 $return .= '</div>';
2769 return $return;
2770 }
2771
2778 {
2779 if (!empty($this->id)) {
2780 $id = $this->id;
2781 } else {
2782 return 0;
2783 }
2784 if ($id) {
2785 $sql = "SELECT COUNT(*) AS nb FROM ".MAIN_DB_PREFIX."prelevement_lignes";
2786 $sql .= " WHERE fk_prelevement_bons = ".((int) $id);
2787 $sql .= " AND fk_soc = 0"; // fk_soc can't be NULL
2788 $sql .= " AND fk_user IS NOT NULL";
2789
2790 $num = 0;
2791 $resql = $this->db->query($sql);
2792 if ($resql) {
2793 $obj = $this->db->fetch_object($resql);
2794 $num = $obj->nb;
2795 }
2796 if ($num > 0) {
2797 return 1;
2798 }
2799 } else {
2800 dol_print_error($this->db);
2801 }
2802
2803 return 0;
2804 }
2805}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
checkSwiftForAccount(Account $account=null, $swift=null)
Check SWIFT informations for a bank account.
Definition bank.lib.php:282
checkIbanForAccount(Account $account=null, $ibantocheck=null)
Check IBAN number informations for a bank account.
Definition bank.lib.php:303
$object ref
Definition info.php:79
Class to manage bank accounts.
Class to manage withdrawal receipts.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
SommeAPrelever($mode='direct-debit', $type='')
Returns amount waiting for direct debit payment or credit transfer payment.
static buildRumNumber($row_code_client, $row_datec, $row_drum)
Generate dynamically a RUM number for a customer bank account.
EnregEmetteur($type='direct-debit')
Write sender of request (me).
update(User $user, $notrigger=false)
Update object into database.
checkIfSalaryBonPrelevement()
Check if is bon prelevement for salary invoice.
EnregTotal($total)
Write end.
NbFactureAPrelever($type='direct-debit', $forsalary=0)
Get number of invoices to pay.
fetch($rowid, $ref='')
Get object and lines from database.
getListInvoices($amounts=0, $type='')
Get invoice or salary list (with amount or not)
deleteNotificationById($rowid)
Delete a notification def by id.
AddFacture($invoice_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $type='debit-order', $sourcetype='')
Add invoice to withdrawal.
__construct($db)
Constructor.
EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom='', $type='direct-debit')
Write recipient of request (customer)
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Returns clickable name (with picto)
LibStatut($status, $mode=0)
Return status label for a status.
set_infotrans($user, $date, $method)
Set withdrawal to transmited status.
getErrorString($error)
Return error string.
generate($format='ALL', $executiondate=0, $type='direct-debit', $fk_bank_account=0, $user_dest=0)
Generate a direct debit or credit transfer file.
EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf='\n', $format='FRST', $type='direct-debit', $fk_bank_account=0)
Write sender of request (me).
set_infocredit($user, $date, $type='')
Set direct debit or credit transfer order to "paid" status.
addline(&$line_id, $client_id, $client_nom, $amount, $code_banque, $code_guichet, $number, $number_key, $sourcetype='')
Add line to withdrawal.
getLibStatut($mode=0)
Return status label of object.
EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum, $type='direct-debit', $row_comment='')
Write recipient (thirdparty concerned by request)
addNotification($db, $user, $action)
Add a notification.
nbOfInvoiceToPay($mode='direct-debit', $type='')
Get number of invoices waiting for payment.
create($banque=0, $agence=0, $mode='real', $format='ALL', $executiondate='', $notrigger=0, $type='direct-debit', $did=0, $fk_bank_account=0, $sourcetype='invoice')
Create a BAN payment order:
deleteNotification($user, $action)
Delete a notification.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
updateCommon(User $user, $notrigger=false)
Update object into database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage suppliers invoices.
Class to manage invoices.
Class to manage payments for supplier invoices.
Class to manage payments of customer invoices.
Class to manage payments of salaries.
Class to manage salary payments.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_string_nospecial($str, $newstr='_', $badcharstoreplace='', $badcharstoremove='', $keepspaces=0)
Clean a string from all punctuation characters to use it as a ref or login.
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_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_string_unaccent($str)
Clean a string from all accent characters to be used as ref, login or by dol_sanitizeFileName.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
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 dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e e e e e statut
Definition invoice.php:1926
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:121