dolibarr 21.0.0-alpha
account.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
6 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2015-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
11 * Copyright (C) 2019 JC Prieto <jcprieto@virtual20.com><prietojc@gmail.com>
12 * Copyright (C) 2022-2024 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27 */
28
35require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
36
37
41class Account extends CommonObject
42{
46 public $element = 'bank_account';
47
51 public $table_element = 'bank_account';
52
56 public $picto = 'account';
57
63 public $rowid;
64
69 public $label;
70
77 private $courant; // @phpstan-ignore-line
78
83 public $type;
84
89 public $bank;
90
98 private $clos = self::STATUS_OPEN;
99
104 public $rappro = 1;
105
110 public $url;
111
116 public $code_banque;
117
122 public $code_guichet;
123
128 public $number;
129
134 public $cle_rib;
135
140 public $bic;
141
146 public $iban;
147
154 public $iban_prefix;
155
160 public $pti_in_ctti = 0;
161
168 private $proprio;
169
174 public $owner_name;
175
180 public $owner_address;
181
186 public $owner_zip;
187
192 public $owner_town;
193 public $owner_country_id;
194 public $owner_country_code;
195
202 private $domiciliation;
203
208 public $address;
209 public $state_id;
210 public $state_code;
211 public $state;
212 public $country_id;
213
219 public $type_lib = array();
220
225 public $account_number;
226
230 public $fk_accountancy_journal;
231
235 public $accountancy_journal;
236
241 public $currency_code;
242
249 public $account_currency_code;
250
255 public $min_allowed;
256
261 public $min_desired;
262
267 public $comment;
268
273 public $date_solde;
274
281 private $solde; // @phpstan-ignore-line
282
287 public $balance;
288
293 public $ics;
294
299 public $ics_transfer;
300
301
326 // BEGIN MODULEBUILDER PROPERTIES
330 public $fields = array(
331 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
332 'ref' => array('type' => 'varchar(12)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 25),
333 'label' => array('type' => 'varchar(30)', 'label' => 'Label', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 30),
334 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 35, 'index' => 1),
335 'bank' => array('type' => 'varchar(60)', 'label' => 'Bank', 'enabled' => 1, 'visible' => -1, 'position' => 40),
336 'code_banque' => array('type' => 'varchar(128)', 'label' => 'Code banque', 'enabled' => 1, 'visible' => -1, 'position' => 45),
337 'code_guichet' => array('type' => 'varchar(6)', 'label' => 'Code guichet', 'enabled' => 1, 'visible' => -1, 'position' => 50),
338 'number' => array('type' => 'varchar(255)', 'label' => 'Number', 'enabled' => 1, 'visible' => -1, 'position' => 55),
339 'cle_rib' => array('type' => 'varchar(5)', 'label' => 'Cle rib', 'enabled' => 1, 'visible' => -1, 'position' => 60),
340 'bic' => array('type' => 'varchar(11)', 'label' => 'Bic', 'enabled' => 1, 'visible' => -1, 'position' => 65),
341 'iban_prefix' => array('type' => 'varchar(34)', 'label' => 'Iban prefix', 'enabled' => 1, 'visible' => -1, 'position' => 70),
342 'country_iban' => array('type' => 'varchar(2)', 'label' => 'Country iban', 'enabled' => 1, 'visible' => -1, 'position' => 75),
343 'cle_iban' => array('type' => 'varchar(2)', 'label' => 'Cle iban', 'enabled' => 1, 'visible' => -1, 'position' => 80),
344 'domiciliation' => array('type' => 'varchar(255)', 'label' => 'Domiciliation', 'enabled' => 1, 'visible' => -1, 'position' => 85),
345 'state_id' => array('type' => 'integer', 'label' => 'StateId', 'enabled' => 1, 'visible' => -1, 'position' => 90),
346 'fk_pays' => array('type' => 'integer', 'label' => 'Country', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 95),
347 'proprio' => array('type' => 'varchar(60)', 'label' => 'Proprio', 'enabled' => 1, 'visible' => -1, 'position' => 100),
348 'owner_address' => array('type' => 'varchar(255)', 'label' => 'Owner address', 'enabled' => 1, 'visible' => -1, 'position' => 105),
349 'owner_zip' => array('type' => 'varchar(25)', 'label' => 'Owner zip', 'enabled' => 1, 'visible' => -1, 'position' => 106),
350 'owner_town' => array('type' => 'varchar(50)', 'label' => 'Owner town', 'enabled' => 1, 'visible' => -1, 'position' => 107),
351 'owner_country_id' => array('type' => 'integer', 'label' => 'Owner country', 'enabled' => 1, 'visible' => -1, 'position' => 108),
352 'courant' => array('type' => 'smallint(6)', 'label' => 'Courant', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 110),
353 'clos' => array('type' => 'smallint(6)', 'label' => 'Clos', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 115),
354 'rappro' => array('type' => 'smallint(6)', 'label' => 'Rappro', 'enabled' => 1, 'visible' => -1, 'position' => 120),
355 'url' => array('type' => 'varchar(128)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 125),
356 'account_number' => array('type' => 'varchar(32)', 'label' => 'Account number', 'enabled' => 1, 'visible' => -1, 'position' => 130),
357 'fk_accountancy_journal' => array('type' => 'integer', 'label' => 'Accountancy journal ID', 'enabled' => 1, 'visible' => -1, 'position' => 132),
358 'accountancy_journal' => array('type' => 'varchar(20)', 'label' => 'Accountancy journal', 'enabled' => 1, 'visible' => -1, 'position' => 135),
359 'currency_code' => array('type' => 'varchar(3)', 'label' => 'Currency code', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 140),
360 'min_allowed' => array('type' => 'integer', 'label' => 'Min allowed', 'enabled' => 1, 'visible' => -1, 'position' => 145),
361 'min_desired' => array('type' => 'integer', 'label' => 'Min desired', 'enabled' => 1, 'visible' => -1, 'position' => 150),
362 'comment' => array('type' => 'text', 'label' => 'Comment', 'enabled' => 1, 'visible' => -1, 'position' => 155),
363 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 156),
364 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 157),
365 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 160),
366 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 165),
367 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 170),
368 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 175),
369 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 180),
370 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 185),
371 );
372 // END MODULEBUILDER PROPERTIES
373
377 const TYPE_CURRENT = 1;
381 const TYPE_CASH = 2;
385 const TYPE_SAVINGS = 0;
386
387
388 const STATUS_OPEN = 0;
389 const STATUS_CLOSED = 1;
390
391
397 protected function deprecatedProperties()
398 {
399 return array(
400 'proprio' => 'owner_name',
401 'domiciliation' => 'owner_address',
402 'courant' => 'type',
403 'clos' => 'status',
404 'solde' => 'balance',
405 ) + parent::deprecatedProperties();
406 }
407
413 public function __construct(DoliDB $db)
414 {
415 global $langs;
416
417 $this->db = $db;
418
419 $this->ismultientitymanaged = 1;
420
421 $this->balance = 0;
422
423 $this->type_lib = array(
424 self::TYPE_SAVINGS => $langs->transnoentitiesnoconv("BankType0"),
425 self::TYPE_CURRENT => $langs->transnoentitiesnoconv("BankType1"),
426 self::TYPE_CASH => $langs->transnoentitiesnoconv("BankType2"),
427 );
428
429 $this->labelStatus = array(
430 self::STATUS_OPEN => $langs->transnoentitiesnoconv("StatusAccountOpened"),
431 self::STATUS_CLOSED => $langs->transnoentitiesnoconv("StatusAccountClosed")
432 );
433 }
434
440 public function __toString()
441 {
442 $string = '';
443 foreach ($this->getFieldsToShow() as $val) {
444 if ($val == 'BankCode') {
445 $string .= $this->code_banque.' ';
446 } elseif ($val == 'BankAccountNumber') {
447 $string .= $this->number.' ';
448 } elseif ($val == 'DeskCode') {
449 $string .= $this->code_guichet.' ';
450 } elseif ($val == 'BankAccountNumberKey') {
451 $string .= $this->cle_rib.' ';
452 } elseif ($val == 'BIC') {
453 $string .= $this->bic.' ';
454 } elseif ($val == 'IBAN') {
455 $string .= $this->iban.' ';
456 }
457 }
458
459 return trim($string);
460 }
461
462
468 public function canBeConciliated()
469 {
470 global $conf;
471
472 if (empty($this->rappro)) {
473 return -1;
474 }
475 if ($this->type == Account::TYPE_CASH && !getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
476 return -2;
477 }
478 if ($this->status) {
479 return -3;
480 }
481 return 1;
482 }
483
484
485 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
496 public function add_url_line($line_id, $url_id, $url, $label, $type)
497 {
498 // phpcs:enable
499 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
500 $sql .= "fk_bank";
501 $sql .= ", url_id";
502 $sql .= ", url"; // deprecated
503 $sql .= ", label";
504 $sql .= ", type";
505 $sql .= ") VALUES (";
506 $sql .= ((int) $line_id);
507 $sql .= ", ".((int) $url_id);
508 $sql .= ", '".$this->db->escape($url)."'"; // deprecated
509 $sql .= ", '".$this->db->escape($label)."'";
510 $sql .= ", '".$this->db->escape($type)."'";
511 $sql .= ")";
512
513 dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
514 if ($this->db->query($sql)) {
515 $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
516 return $rowid;
517 } else {
518 $this->error = $this->db->lasterror();
519 return -1;
520 }
521 }
522
523 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
533 public function get_url($fk_bank = 0, $url_id = 0, $type = '')
534 {
535 // phpcs:enable
536 $lines = array();
537
538 // Check parameters
539 if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
540 $this->error = "ErrorBadParameter";
541 return -1;
542 }
543
544 $sql = "SELECT fk_bank, url_id, url, label, type";
545 $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
546 if ($fk_bank > 0) {
547 $sql .= " WHERE fk_bank = ".((int) $fk_bank);
548 } else {
549 $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
550 }
551 $sql .= " ORDER BY type, label";
552
553 dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
554 $result = $this->db->query($sql);
555 if ($result) {
556 $i = 0;
557 $num = $this->db->num_rows($result);
558 while ($i < $num) {
559 $obj = $this->db->fetch_object($result);
560 // Anciens liens (pour compatibilite)
561 $lines[$i][0] = $obj->url;
562 $lines[$i][1] = $obj->url_id;
563 $lines[$i][2] = $obj->label;
564 $lines[$i][3] = $obj->type;
565 // Nouveaux liens
566 $lines[$i]['url'] = $obj->url;
567 $lines[$i]['url_id'] = $obj->url_id;
568 $lines[$i]['label'] = $obj->label;
569 $lines[$i]['type'] = $obj->type;
570 $lines[$i]['fk_bank'] = $obj->fk_bank;
571 $i++;
572 }
573 } else {
574 dol_print_error($this->db);
575 }
576
577 return $lines;
578 }
579
598 public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
599 {
600 global $langs;
601
602 // Deprecation warning
603 if (is_numeric($oper)) {
604 dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
605 }
606
607 if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
608 $this->id = $this->rowid;
609 }
610
611 // Clean parameters
612 $emetteur = trim($emetteur);
613 $banque = trim($banque);
614 $label = trim($label);
615
616 $now = dol_now();
617
618 if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
619 $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
620 $sql .= " WHERE id = ".((int) $oper);
621 $sql .= " AND entity IN (".getEntity('c_paiement').")";
622 $resql = $this->db->query($sql);
623 if ($resql) {
624 $obj = $this->db->fetch_object($resql);
625 $oper = $obj->code;
626 } else {
627 dol_print_error($this->db, 'Failed to get payment type code');
628 return -1;
629 }
630 }
631
632 // Check parameters
633 if (!$oper) {
634 $this->error = $langs->trans("OperNotDefined");
635 return -1;
636 }
637 if (!$this->id) {
638 $this->error = $langs->trans("ThisIdNotDefined");
639 return -2;
640 }
641 if ($this->type == Account::TYPE_CASH && $oper != 'LIQ') {
642 $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
643 return -3;
644 }
645
646 $this->db->begin();
647
648 if (is_null($datev) || empty($datev)) {
649 $datev = $date;
650 }
651
652 $accline = new AccountLine($this->db);
653 $accline->datec = $now;
654 $accline->dateo = $date;
655 $accline->datev = $datev;
656 $accline->label = $label;
657 $accline->amount = $amount;
658 $accline->amount_main_currency = $amount_main_currency;
659 $accline->fk_user_author = $user->id;
660 $accline->fk_account = $this->id;
661 $accline->fk_type = $oper;
662 $accline->numero_compte = $accountancycode;
663 $accline->num_releve = $num_releve;
664
665 if ($num_chq) {
666 $accline->num_chq = $num_chq;
667 }
668
669 if ($emetteur) {
670 $accline->emetteur = $emetteur;
671 }
672
673 if ($banque) {
674 $accline->bank_chq = $banque;
675 }
676
677 if ($accline->insert() > 0) {
678 if ($categorie > 0) {
679 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class(";
680 $sql .= "lineid, fk_categ";
681 $sql .= ") VALUES (";
682 $sql .= ((int) $accline->id).", '".$this->db->escape($categorie)."'";
683 $sql .= ")";
684
685 $result = $this->db->query($sql);
686 if (!$result) {
687 $this->error = $this->db->lasterror();
688 $this->db->rollback();
689
690 return -4;
691 }
692 }
693
694 $this->db->commit();
695
696 return $accline->id;
697 } else {
698 $this->setErrorsFromObject($accline);
699 $this->db->rollback();
700
701 return -5;
702 }
703 }
704
712 public function create(User $user, $notrigger = 0)
713 {
714 global $langs, $conf;
715
716 $error = 0;
717
718 // Clean parameters
719 if (!$this->min_allowed) {
720 $this->min_allowed = 0;
721 }
722 if (!$this->min_desired) {
723 $this->min_desired = 0;
724 }
725
726 // Check parameters
727 if (empty($this->country_id)) {
728 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
729 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
730 return -1;
731 }
732 if (empty($this->ref)) {
733 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
734 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
735 return -1;
736 }
737 if (empty($this->date_solde)) {
738 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
739 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
740 return -1;
741 }
742
743 // Load libraries to check BAN
744 $balance = $this->balance;
745 if (empty($balance) && !empty($this->solde)) {
746 $balance = $this->solde;
747 }
748 if (empty($balance)) {
749 $balance = 0;
750 }
751 if (empty($this->address && !empty($this->domiciliation))) {
752 dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE);
753 $this->address = $this->domiciliation;
754 }
755 if (empty($this->status && !empty($this->clos))) {
756 dol_syslog(get_class($this)."::create clos is deprecated use status", LOG_NOTICE);
757 $this->status = $this->clos;
758 }
759
760 // Load the library to validate/check a BAN account
761 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
762
763 $now = dol_now();
764
765 $this->db->begin();
766
767 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
768 $sql .= "datec";
769 $sql .= ", ref";
770 $sql .= ", label";
771 $sql .= ", entity";
772 $sql .= ", account_number";
773 $sql .= ", fk_accountancy_journal";
774 $sql .= ", bank";
775 $sql .= ", code_banque";
776 $sql .= ", code_guichet";
777 $sql .= ", number";
778 $sql .= ", cle_rib";
779 $sql .= ", bic";
780 $sql .= ", iban_prefix";
781 $sql .= ", domiciliation";
782 $sql .= ", pti_in_ctti";
783 $sql .= ", proprio";
784 $sql .= ", owner_address";
785 $sql .= ", owner_zip";
786 $sql .= ", owner_town";
787 $sql .= ", owner_country_id";
788 $sql .= ", currency_code";
789 $sql .= ", rappro";
790 $sql .= ", min_allowed";
791 $sql .= ", min_desired";
792 $sql .= ", comment";
793 $sql .= ", state_id";
794 $sql .= ", fk_pays";
795 $sql .= ", ics";
796 $sql .= ", ics_transfer";
797 $sql .= ") VALUES (";
798 $sql .= "'".$this->db->idate($now)."'";
799 $sql .= ", '".$this->db->escape($this->ref)."'";
800 $sql .= ", '".$this->db->escape($this->label)."'";
801 $sql .= ", ".((int) $conf->entity);
802 $sql .= ", '".$this->db->escape($this->account_number)."'";
803 $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
804 $sql .= ", '".$this->db->escape($this->bank)."'";
805 $sql .= ", '".$this->db->escape($this->code_banque)."'";
806 $sql .= ", '".$this->db->escape($this->code_guichet)."'";
807 $sql .= ", '".$this->db->escape($this->number)."'";
808 $sql .= ", '".$this->db->escape($this->cle_rib)."'";
809 $sql .= ", '".$this->db->escape($this->bic)."'";
810 $sql .= ", '".$this->db->escape($this->iban)."'";
811 $sql .= ", '".$this->db->escape($this->address)."'";
812 $sql .= ", ".((int) $this->pti_in_ctti);
813 $sql .= ", '".$this->db->escape($this->proprio)."'";
814 $sql .= ", '".$this->db->escape($this->owner_address)."'";
815 $sql .= ", '".$this->db->escape($this->owner_zip)."'";
816 $sql .= ", '".$this->db->escape($this->owner_town)."'";
817 $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
818 $sql .= ", '".$this->db->escape($this->currency_code)."'";
819 $sql .= ", ".((int) $this->rappro);
820 $sql .= ", ".price2num($this->min_allowed, 'MT');
821 $sql .= ", ".price2num($this->min_desired, 'MT');
822 $sql .= ", '".$this->db->escape($this->comment)."'";
823 $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
824 $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
825 $sql .= ", '".$this->db->escape($this->ics)."'";
826 $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
827 $sql .= ")";
828
829 dol_syslog(get_class($this)."::create", LOG_DEBUG);
830 $resql = $this->db->query($sql);
831 if ($resql) {
832 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
833
834 $result = $this->update($user, 1);
835 if ($result > 0) {
836 $accline = new AccountLine($this->db);
837 $accline->datec = $now;
838 $accline->label = '('.$langs->trans("InitialBankBalance").')';
839 $accline->amount = (float) price2num($balance);
840 $accline->fk_user_author = $user->id;
841 $accline->fk_account = $this->id;
842 $accline->datev = $this->date_solde;
843 $accline->dateo = $this->date_solde;
844 $accline->fk_type = 'SOLD';
845
846 if ($accline->insert() < 0) {
847 $error++;
848 $this->error = $accline->error;
849 $this->errors = $accline->errors;
850 }
851
852 if (!$error) {
853 $result = $this->insertExtraFields();
854 if ($result < 0) {
855 $error++;
856 }
857 }
858
859 if (!$error && !$notrigger) {
860 // Call trigger
861 $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
862 if ($result < 0) {
863 $error++;
864 }
865 // End call triggers
866 }
867 } else {
868 $error++;
869 }
870 } else {
871 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
872 $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
873 $error++;
874 } else {
875 $this->error = $this->db->error()." sql=".$sql;
876 $error++;
877 }
878 }
879
880 if (!$error) {
881 $this->db->commit();
882 return $this->id;
883 } else {
884 $this->db->rollback();
885 return -1 * $error;
886 }
887 }
888
896 public function update(User $user, $notrigger = 0)
897 {
898 global $langs;
899
900 $error = 0;
901
902 $this->db->begin();
903
904 // Check parameters
905 if (empty($this->country_id)) {
906 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
907 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
908 return -1;
909 }
910 if (empty($this->ref)) {
911 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
912 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
913 return -1;
914 }
915 if (!$this->label) {
916 $this->label = "???";
917 }
918
919 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
920
921 $sql .= " ref = '".$this->db->escape($this->ref)."'";
922 $sql .= ",label = '".$this->db->escape($this->label)."'";
923
924 $sql .= ",courant = ".((int) $this->type);
925 $sql .= ",clos = ".((int) $this->status);
926 $sql .= ",rappro = ".((int) $this->rappro);
927 $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
928 $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
929 $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
930 $sql .= ",bank = '".$this->db->escape($this->bank)."'";
931 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
932 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
933 $sql .= ",number='".$this->db->escape($this->number)."'";
934 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
935 $sql .= ",bic='".$this->db->escape($this->bic)."'";
936 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
937 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
938 $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
939 $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
940 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
941 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
942 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
943 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
944
945 $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
946
947 $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
948 $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
949 $sql .= ",comment = '".$this->db->escape($this->comment)."'";
950
951 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
952 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
953 $sql .= ",ics = '".$this->db->escape($this->ics)."'";
954 $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
955
956 $sql .= " WHERE rowid = ".((int) $this->id);
957
958 dol_syslog(get_class($this)."::update", LOG_DEBUG);
959 $result = $this->db->query($sql);
960 if ($result) {
961 // Actions on extra fields (by external module or standard code)
962 if (!$error) {
963 $result = $this->insertExtraFields();
964 if ($result < 0) {
965 $error++;
966 }
967 }
968
969 if (!$error && !$notrigger) {
970 // Call trigger
971 $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
972 if ($result < 0) {
973 $error++;
974 }
975 // End call triggers
976 }
977 } else {
978 $error++;
979 $this->error = $this->db->lasterror();
980 dol_print_error($this->db);
981 }
982
983 if (!$error) {
984 $this->db->commit();
985 return $this->id;
986 } else {
987 $this->db->rollback();
988 return -1 * $error;
989 }
990 }
991
992
993 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1000 public function update_bban(User $user = null)
1001 {
1002 // phpcs:enable
1003 global $conf, $langs;
1004
1005 // Load library to get BAN control function
1006 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1007
1008 dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
1009
1010 // Check parameters
1011 if (!$this->ref) {
1012 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
1013 return -2;
1014 }
1015
1016 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
1017 $sql .= " bank = '".$this->db->escape($this->bank)."'";
1018 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1019 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1020 $sql .= ",number='".$this->db->escape($this->number)."'";
1021 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1022 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1023 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1024 $sql .= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
1025 $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
1026 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1027 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1028 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1029 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1030 $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
1031 $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
1032 $sql .= " WHERE rowid = ".((int) $this->id);
1033 $sql .= " AND entity = ".((int) $conf->entity);
1034
1035 dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
1036
1037 $result = $this->db->query($sql);
1038 if ($result) {
1039 return 1;
1040 } else {
1041 $this->error = $this->db->lasterror();
1042 dol_print_error($this->db);
1043 return -1;
1044 }
1045 }
1046
1047
1055 public function fetch($id, $ref = '')
1056 {
1057 if (empty($id) && empty($ref)) {
1058 $this->error = "ErrorBadParameters";
1059 return -1;
1060 }
1061
1062 $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant as type, ba.clos as status, ba.rappro, ba.url,";
1063 $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1064 $sql .= " ba.domiciliation as address, ba.pti_in_ctti, ba.proprio as owner_name, ba.owner_address, ba.owner_zip, ba.owner_town, ba.owner_country_id, ba.state_id, ba.fk_pays as country_id,";
1065 $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1066 $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1067 $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1068 $sql .= ' c.code as country_code, c.label as country,';
1069 $sql .= ' d.code_departement as state_code, d.nom as state,';
1070 $sql .= ' aj.code as accountancy_journal';
1071 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1072 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1073 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1074 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1075 $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1076 if ($id) {
1077 $sql .= " AND ba.rowid = ".((int) $id);
1078 }
1079 if ($ref) {
1080 $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1081 }
1082
1083 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1084 $result = $this->db->query($sql);
1085 if ($result) {
1086 if ($this->db->num_rows($result)) {
1087 $obj = $this->db->fetch_object($result);
1088
1089 $this->id = $obj->rowid;
1090 $this->rowid = $obj->rowid;
1091 $this->ref = $obj->ref;
1092 $this->label = $obj->label;
1093 $this->type = $obj->type;
1094 $this->courant = $obj->type;
1095 $this->bank = $obj->bank;
1096 $this->clos = $obj->status;
1097 $this->status = $obj->status;
1098 $this->rappro = $obj->rappro;
1099 $this->url = $obj->url;
1100
1101 $this->code_banque = $obj->code_banque;
1102 $this->code_guichet = $obj->code_guichet;
1103 $this->number = $obj->number;
1104 $this->cle_rib = $obj->cle_rib;
1105 $this->bic = $obj->bic;
1106 $this->iban = $obj->iban;
1107 $this->domiciliation = $obj->address;
1108 $this->address = $obj->address;
1109 $this->pti_in_ctti = $obj->pti_in_ctti;
1110 $this->proprio = $obj->owner_name;
1111 $this->owner_name = $obj->owner_name;
1112 $this->owner_address = $obj->owner_address;
1113 $this->owner_zip = $obj->owner_zip;
1114 $this->owner_town = $obj->owner_town;
1115 $this->owner_country_id = $obj->owner_country_id;
1116
1117 $this->state_id = $obj->state_id;
1118 $this->state_code = $obj->state_code;
1119 $this->state = $obj->state;
1120
1121 $this->country_id = $obj->country_id;
1122 $this->country_code = $obj->country_code;
1123 $this->country = $obj->country;
1124
1125 $this->account_number = $obj->account_number;
1126 $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1127 $this->accountancy_journal = $obj->accountancy_journal;
1128
1129 $this->currency_code = $obj->currency_code;
1130 $this->account_currency_code = $obj->currency_code;
1131 $this->min_allowed = $obj->min_allowed;
1132 $this->min_desired = $obj->min_desired;
1133 $this->comment = $obj->comment;
1134
1135 $this->date_creation = $this->db->jdate($obj->date_creation);
1136 $this->date_modification = $this->db->jdate($obj->date_modification);
1137
1138 $this->ics = $obj->ics;
1139 $this->ics_transfer = $obj->ics_transfer;
1140
1141 // Retrieve all extrafield
1142 // fetch optionals attributes and labels
1143 $this->fetch_optionals();
1144
1145 return 1;
1146 } else {
1147 return 0;
1148 }
1149 } else {
1150 $this->error = $this->db->lasterror();
1151 $this->errors[] = $this->error;
1152 return -1;
1153 }
1154 }
1155
1166 public function setCategories($categories)
1167 {
1168 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1169 return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1170 }
1171
1179 public function delete(User $user = null, $notrigger = 0)
1180 {
1181 $error = 0;
1182
1183 $this->db->begin();
1184
1185 // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1186
1187 // Delete link between tag and bank account
1188 if (!$error) {
1189 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1190 $sql .= " WHERE fk_account = ".((int) $this->id);
1191
1192 $resql = $this->db->query($sql);
1193 if (!$resql) {
1194 $error++;
1195 $this->error = "Error ".$this->db->lasterror();
1196 }
1197 }
1198
1199 if (!$error) {
1200 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1201 $sql .= " WHERE rowid = ".((int) $this->id);
1202
1203 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1204 $result = $this->db->query($sql);
1205 if ($result) {
1206 // Remove extrafields
1207 if (!$error) {
1208 $result = $this->deleteExtraFields();
1209 if ($result < 0) {
1210 $error++;
1211 dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1212 }
1213 }
1214 } else {
1215 $error++;
1216 $this->error = "Error ".$this->db->lasterror();
1217 }
1218 }
1219
1220 if (!$error) {
1221 $this->db->commit();
1222 return 1;
1223 } else {
1224 $this->db->rollback();
1225 return -1;
1226 }
1227 }
1228
1229
1236 public function getLibStatut($mode = 0)
1237 {
1238 return $this->LibStatut($this->status, $mode);
1239 }
1240
1241 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1249 public function LibStatut($status, $mode = 0)
1250 {
1251 // phpcs:enable
1252 global $langs;
1253 $langs->load('banks');
1254
1255 if ($status == self::STATUS_OPEN) {
1256 $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1257 $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1258 $statusType = 'status4';
1259 } else {
1260 $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1261 $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1262 $statusType = 'status5';
1263 }
1264
1265 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1266 }
1267
1268
1269 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1275 public function can_be_deleted()
1276 {
1277 // phpcs:enable
1278 $can_be_deleted = false;
1279
1280 $sql = "SELECT COUNT(rowid) as nb";
1281 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1282 $sql .= " WHERE fk_account = ".((int) $this->id);
1283
1284 $resql = $this->db->query($sql);
1285 if ($resql) {
1286 $obj = $this->db->fetch_object($resql);
1287 if ($obj->nb <= 1) {
1288 $can_be_deleted = true; // Juste le solde
1289 }
1290 } else {
1291 dol_print_error($this->db);
1292 }
1293 return $can_be_deleted;
1294 }
1295
1296
1302 public function error()
1303 {
1304 return $this->error;
1305 }
1306
1315 public function solde($option = 0, $date_end = '', $field = 'dateo')
1316 {
1317 $solde = 0;
1318
1319 $sql = "SELECT sum(amount) as amount";
1320 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1321 $sql .= " WHERE fk_account = ".((int) $this->id);
1322 if ($option == 1) {
1323 $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1324 }
1325
1326 $resql = $this->db->query($sql);
1327 if ($resql) {
1328 if ($this->db->num_rows($resql)) {
1329 $obj = $this->db->fetch_object($resql);
1330 $solde = $obj->amount;
1331 }
1332 $this->db->free($resql);
1333 } else {
1334 $this->errors[] = $this->db->lasterror;
1335 return -1;
1336 }
1337
1338 return (float) price2num($solde, 'MU');
1339 }
1340
1341 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1349 public function load_board(User $user, $filteraccountid = 0)
1350 {
1351 // phpcs:enable
1352 global $conf, $langs;
1353
1354 if ($user->socid) {
1355 return -1; // protection pour eviter appel par utilisateur externe
1356 }
1357
1358 $sql = "SELECT b.rowid, b.datev as datefin";
1359 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1360 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1361 $sql .= " WHERE b.rappro=0";
1362 $sql .= " AND b.fk_account = ba.rowid";
1363 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1364 $sql .= " AND (ba.rappro = 1 AND ba.courant != " . Account::TYPE_CASH . ")"; // Compte rapprochable
1365 $sql .= " AND clos = 0";
1366 if ($filteraccountid) {
1367 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1368 }
1369
1370 $resql = $this->db->query($sql);
1371 if ($resql) {
1372 $langs->load("banks");
1373 $now = dol_now();
1374
1375 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1376
1377 $response = new WorkboardResponse();
1378 $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1379 $response->label = $langs->trans("TransactionsToConciliate");
1380 $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1381 $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1382 $response->img = img_object('', "payment");
1383
1384 while ($obj = $this->db->fetch_object($resql)) {
1385 $response->nbtodo++;
1386 if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1387 $response->nbtodolate++;
1388 }
1389 }
1390
1391 return $response;
1392 } else {
1393 dol_print_error($this->db);
1394 $this->error = $this->db->error();
1395 return -1;
1396 }
1397 }
1398
1405 public function loadStateBoard($filteraccountid = 0)
1406 {
1407 global $user;
1408
1409 if ($user->socid) {
1410 return -1; // protection pour eviter appel par utilisateur externe
1411 }
1412
1413 $sql = "SELECT count(b.rowid) as nb";
1414 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1415 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1416 $sql .= " WHERE b.fk_account = ba.rowid";
1417 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1418 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1419 $sql .= " AND clos = 0";
1420 if ($filteraccountid) {
1421 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1422 }
1423
1424 $resql = $this->db->query($sql);
1425 if ($resql) {
1426 while ($obj = $this->db->fetch_object($resql)) {
1427 $this->nb["banklines"] = $obj->nb;
1428 }
1429 $this->db->free($resql);
1430 return 1;
1431 } else {
1432 dol_print_error($this->db);
1433 $this->error = $this->db->error();
1434 return -1;
1435 }
1436 }
1437
1438
1444 public function countAccountToReconcile()
1445 {
1446 global $user;
1447
1448 //Protection against external users
1449 if ($user->socid) {
1450 return 0;
1451 }
1452
1453 $nb = 0;
1454
1455 $sql = "SELECT COUNT(ba.rowid) as nb";
1456 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1457 $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1458 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1459 if (!getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
1460 $sql .= " AND ba.courant != " . Account::TYPE_CASH;
1461 }
1462
1463 $resql = $this->db->query($sql);
1464 if ($resql) {
1465 $obj = $this->db->fetch_object($resql);
1466 $nb = $obj->nb;
1467 } else {
1468 dol_print_error($this->db);
1469 }
1470
1471 return $nb;
1472 }
1473
1481 public function getTooltipContentArray($params)
1482 {
1483 global $langs;
1484 $langs->loadLangs(['banks', 'compta']);
1485 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1486
1487 $datas = array();
1488
1489 $nofetch = !empty($params['nofetch']);
1490 $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1491 if (isset($this->status)) {
1492 $pictos .= ' '.$this->getLibStatut(5);
1493 }
1494 $datas['picto'] = $pictos;
1495 $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1496 $datas['accountnumber'] = '<br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1497 $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1498 $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1499 $datas['accountcurrency'] = '<br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1500
1501 if (isModEnabled('accounting')) {
1502 include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1503 $langs->load("accountancy");
1504 $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1505 $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1506 }
1507 // show categories for this record only in ajax to not overload lists
1508 if (isModEnabled('category') && !$nofetch) {
1509 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1510 $form = new Form($this->db);
1511 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1512 }
1513
1514 return $datas;
1515 }
1516
1528 public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1529 {
1530 global $conf, $langs;
1531
1532 if (!empty($conf->dol_no_mouse_hover)) {
1533 $notooltip = 1; // Force disable tooltips
1534 }
1535
1536 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1537
1538 $result = '';
1539 $classfortooltip = 'classfortooltip';
1540 $dataparams = '';
1541 $params = [
1542 'id' => $this->id,
1543 'objecttype' => $this->element,
1544 'option' => $option,
1545 'nofetch' => 1,
1546 ];
1547 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1548 $classfortooltip = 'classforajaxtooltip';
1549 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1550 $label = '';
1551 } else {
1552 $label = implode($this->getTooltipContentArray($params));
1553 }
1554
1555 $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1556 if ($mode == 'transactions') {
1557 $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1558 } elseif ($mode == 'receipts') {
1559 $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1560 }
1561
1562 if ($option != 'nolink') {
1563 // Add param to save lastsearch_values or not
1564 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1565 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1566 $add_save_lastsearch_values = 1;
1567 }
1568 if ($add_save_lastsearch_values) {
1569 $url .= '&save_lastsearch_values=1';
1570 }
1571 }
1572
1573 $linkclose = '';
1574 if (empty($notooltip)) {
1575 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1576 $label = $langs->trans("BankAccount");
1577 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1578 }
1579 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1580 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1581 } else {
1582 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1583 }
1584
1585 if ($option == 'nolink' || empty($url)) {
1586 $linkstart = '<span';
1587 } else {
1588 $linkstart = '<a href="'.$url.'"';
1589 }
1590 $linkstart .= $linkclose.'>';
1591 if ($option == 'nolink' || empty($url)) {
1592 $linkend = '</span>';
1593 } else {
1594 $linkend = '</a>';
1595 }
1596
1597 $result .= $linkstart;
1598
1599 if ($withpicto) {
1600 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1601 }
1602 if ($withpicto != 2) {
1603 $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1604 }
1605 $result .= $linkend;
1606
1607 return $result;
1608 }
1609
1610
1611 // Method after here are common to Account and CompanyBankAccount
1612
1613
1619 public function verif()
1620 {
1621 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1622
1623 $error = 0;
1624
1625 // Call functions to check BAN
1626 if (!checkIbanForAccount($this)) {
1627 $error++;
1628 $this->error = 'IBANNotValid';
1629 }
1630 if (!checkSwiftForAccount($this) or !(empty($this->bic) && getDolGlobalInt('WITHDRAWAL_WITHOUT_BIC'))) {
1631 $error++;
1632 $this->error = 'SwiftNotValid';
1633 }
1634
1635 if (! $error) {
1636 return 1;
1637 } else {
1638 return 0;
1639 }
1640 }
1641
1647 public function getCountryCode()
1648 {
1649 global $mysoc;
1650
1651 // We return country code of bank account
1652 if (!empty($this->country_code)) {
1653 return $this->country_code;
1654 }
1655
1656 // For backward compatibility, we try to guess country from other information
1657 if (!empty($this->iban)) {
1658 // If IBAN defined, we can know country of account from it
1659 $reg = array();
1660 if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1661 return $reg[1];
1662 }
1663 }
1664
1665 // If this class is linked to a third party
1666 if (!empty($this->socid)) {
1667 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1668 $company = new Societe($this->db);
1669 $result = $company->fetch($this->socid);
1670 if (!empty($company->country_code)) {
1671 return $company->country_code;
1672 }
1673 }
1674
1675 // We return country code of managed company
1676 if (!empty($mysoc->country_code)) {
1677 return $mysoc->country_code;
1678 }
1679
1680 return '';
1681 }
1682
1690 public function getBannerAddress($htmlkey, $object)
1691 {
1692 global $conf, $langs;
1693
1694 $out = '';
1695
1696 $outdone = 0;
1697 $coords = $this->getFullAddress(1, ', ', getDolGlobalInt('MAIN_SHOW_REGION_IN_STATE_SELECT'));
1698 if ($coords) {
1699 if (!empty($conf->use_javascript_ajax)) {
1700 // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
1701 $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
1702 $out .= img_picto($langs->trans("Address"), 'map-marker-alt');
1703 $out .= '</a> ';
1704 }
1705 $address = dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
1706 if ($address) {
1707 $out .= $address;
1708 $outdone++;
1709 }
1710 $outdone++;
1711 }
1712
1713 return $out;
1714 }
1715
1716
1725 public function useDetailedBBAN()
1726 {
1727 $country_code = $this->getCountryCode();
1728
1729 if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1730 return 1; // France, Spain, Gabon, ... - Not valid for CH
1731 }
1732 if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1733 return 2; // Australia, England...
1734 }
1735 return 0;
1736 }
1737
1743 public function needIBAN()
1744 {
1745 global $conf;
1746
1747 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1748 return 0;
1749 }
1750
1751 $country_code = $this->getCountryCode();
1752
1753 $country_code_in_EEC = array(
1754 'AT', // Austria
1755 'BE', // Belgium
1756 'BG', // Bulgaria
1757 'CY', // Cyprus
1758 'CZ', // Czech republic
1759 'DE', // Germany
1760 'DK', // Danemark
1761 'EE', // Estonia
1762 'ES', // Spain
1763 'FI', // Finland
1764 'FR', // France
1765 'GB', // United Kingdom
1766 'GR', // Greece
1767 'HR', // Croatia
1768 'NL', // Holland
1769 'HU', // Hungary
1770 'IE', // Ireland
1771 'IM', // Isle of Man - Included in UK
1772 'IT', // Italy
1773 'LT', // Lithuania
1774 'LU', // Luxembourg
1775 'LV', // Latvia
1776 'MC', // Monaco - Included in France
1777 'MT', // Malta
1778 //'NO', // Norway
1779 'PL', // Poland
1780 'PT', // Portugal
1781 'RO', // Romania
1782 'SE', // Sweden
1783 'SK', // Slovakia
1784 'SI', // Slovenia
1785 'UK', // United Kingdom
1786 //'CH', // Switzerland - No. Swizerland in not in EEC
1787 );
1788
1789 if (in_array($country_code, $country_code_in_EEC)) {
1790 return 1; // France, Spain, ...
1791 }
1792 return 0;
1793 }
1794
1801 public function info($id)
1802 {
1803 }
1804
1819 public function getFieldsToShow($includeibanbic = 0)
1820 {
1821 //Get the required properties depending on the country
1822 $detailedBBAN = $this->useDetailedBBAN();
1823
1824 if ($detailedBBAN == 0) {
1825 $fieldarray = array(
1826 'BankAccountNumber'
1827 );
1828 } elseif ($detailedBBAN == 2) {
1829 $fieldarray = array(
1830 'BankCode',
1831 'BankAccountNumber'
1832 );
1833 } else {
1834 $fieldarray = self::getAccountNumberOrder();
1835 }
1836
1837 //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1838 if ($includeibanbic) {
1839 $fieldarray[] = 'IBAN';
1840 $fieldarray[] = 'BIC';
1841 }
1842 //}
1843
1844 //Get the order the properties are shown
1845 return $fieldarray;
1846 }
1847
1858 public static function getAccountNumberOrder()
1859 {
1860 global $conf;
1861
1862 $fieldlists = array(
1863 'BankCode',
1864 'DeskCode',
1865 'BankAccountNumber',
1866 'BankAccountNumberKey'
1867 );
1868
1869 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION')) {
1870 if (is_numeric(getDolGlobalString('BANK_SHOW_ORDER_OPTION'))) {
1871 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION') == '1') {
1872 $fieldlists = array(
1873 'BankCode',
1874 'DeskCode',
1875 'BankAccountNumberKey',
1876 'BankAccountNumber'
1877 );
1878 }
1879 } else {
1880 //Replace the old AccountNumber key with the new BankAccountNumber key
1881 $fieldlists = explode(
1882 ' ',
1883 preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1884 );
1885 }
1886 }
1887
1888 return $fieldlists;
1889 }
1890
1891
1899 public function initAsSpecimen()
1900 {
1901 // Example of IBAN FR7630001007941234567890185
1902 $this->specimen = 1;
1903 $this->ref = 'MBA';
1904 $this->label = 'My Big Company Bank account';
1905 $this->courant = Account::TYPE_CURRENT;
1906 $this->clos = Account::STATUS_OPEN;
1907 $this->type = Account::TYPE_CURRENT;
1908 $this->status = Account::STATUS_OPEN;
1909 $this->code_banque = '30001';
1910 $this->code_guichet = '00794';
1911 $this->number = '12345678901';
1912 $this->cle_rib = '85';
1913 $this->bic = 'AA12';
1914 $this->iban = 'FR7630001007941234567890185';
1915
1916 $this->bank = 'MyBank';
1917 $this->address = 'Rue de Paris';
1918 $this->proprio = 'Owner';
1919 $this->owner_name = 'Owner';
1920 $this->owner_address = 'Owner address';
1921 $this->owner_zip = 'Owner zip';
1922 $this->owner_town = 'Owner town';
1923 $this->owner_country_id = 'Owner country_id';
1924 $this->country_id = 1;
1925
1926 return 1;
1927 }
1928
1937 public static function replaceThirdparty($dbs, $origin_id, $dest_id)
1938 {
1939 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'";
1940
1941 if ($dbs->query($sql)) {
1942 return true;
1943 } else {
1944 //if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdparty and B-C on old one, we must get A-B-C after merge. Not A-B.
1945 //$this->errors = $dbs->lasterror();
1946 return false;
1947 }
1948 }
1949
1957 public function getKanbanView($option = '', $arraydata = null)
1958 {
1959 global $langs;
1960
1961 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1962
1963 $return = '<div class="box-flex-item box-flex-grow-zero">';
1964 $return .= '<div class="info-box info-box-sm">';
1965 $return .= '<span class="info-box-icon bg-infobox-action">';
1966 $return .= img_picto('', $this->picto);
1967 $return .= '</span>';
1968 $return .= '<div class="info-box-content">';
1969 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1970 if ($selected >= 0) {
1971 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1972 }
1973 if (property_exists($this, 'type_lib')) {
1974 $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
1975 }
1976 if (method_exists($this, 'solde')) {
1977 $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
1978 $return .= '<span class="opacitymedium">'.$langs->trans("Balance").'</span> : <span class="amount">'.price(price2num($this->solde(1), 'MT'), 0, $langs, 1, -1, -1, $this->currency_code).'</span>';
1979 }
1980 if (method_exists($this, 'getLibStatut')) {
1981 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1982 }
1983 $return .= '</div>';
1984 $return .= '</div>';
1985 $return .= '</div>';
1986 return $return;
1987 }
1988}
1989
1990
1991require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1992
1996class AccountLine extends CommonObjectLine
1997{
2001 public $db;
2002
2006 public $element = 'bank';
2007
2011 public $table_element = 'bank';
2012
2016 public $picto = 'accountline';
2017
2021 public $id;
2022
2026 public $ref;
2027
2033 public $datec;
2034
2040 public $dateo;
2041
2047 public $datev;
2048
2052 public $amount;
2053
2057 public $amount_main_currency;
2058
2062 public $fk_user_author;
2063
2067 public $fk_user_rappro;
2068
2072 public $fk_type;
2073
2077 public $fk_bordereau;
2078
2082 public $fk_account;
2083
2087 public $bank_account_ref;
2088
2092 public $bank_account_label;
2093
2097 public $numero_compte;
2098
2102 public $emetteur;
2103
2107 public $rappro;
2108
2112 public $num_releve;
2113
2117 public $num_chq;
2118
2122 public $bank_chq;
2123
2127 public $label;
2128
2132 public $note;
2133
2138 public $user_rappro;
2139
2140
2146 public function __construct(DoliDB $db)
2147 {
2148 $this->db = $db;
2149 }
2150
2159 public function fetch($rowid, $ref = '', $num = '')
2160 {
2161 // Check parameters
2162 if (empty($rowid) && empty($ref) && empty($num)) {
2163 return -1;
2164 }
2165
2166 $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2167 $sql .= " b.fk_user_author, b.fk_user_rappro,";
2168 $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2169 $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2170 $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2171 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2172 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2173 $sql .= " WHERE b.fk_account = ba.rowid";
2174 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2175 if ($num) {
2176 $sql .= " AND b.num_chq = '".$this->db->escape($num)."'";
2177 } elseif ($ref) {
2178 $sql .= " AND b.rowid = '".$this->db->escape($ref)."'";
2179 } else {
2180 $sql .= " AND b.rowid = ".((int) $rowid);
2181 }
2182
2183 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2184 $result = $this->db->query($sql);
2185 if ($result) {
2186 $ret = 0;
2187
2188 $obj = $this->db->fetch_object($result);
2189 if ($obj) {
2190 $this->id = $obj->rowid;
2191 $this->rowid = $obj->rowid;
2192 $this->ref = $obj->rowid;
2193
2194 $this->datec = $this->db->jdate($obj->datec);
2195 $this->datev = $this->db->jdate($obj->datev);
2196 $this->dateo = $this->db->jdate($obj->dateo);
2197 $this->amount = $obj->amount;
2198 $this->label = $obj->label;
2199 $this->note = $obj->note;
2200
2201 $this->fk_user_author = $obj->fk_user_author;
2202 $this->fk_user_rappro = $obj->fk_user_rappro;
2203
2204 $this->fk_type = $obj->fk_type; // Type of transaction
2205 $this->rappro = (int) $obj->rappro;
2206 $this->num_releve = $obj->num_releve;
2207
2208 $this->num_chq = $obj->num_chq;
2209 $this->bank_chq = $obj->banque;
2210 $this->fk_bordereau = $obj->fk_bordereau;
2211
2212 $this->fk_account = $obj->fk_account;
2213 $this->bank_account_ref = $obj->bank_account_ref;
2214 $this->bank_account_label = $obj->bank_account_label;
2215
2216 // Retrieve all extrafield
2217 // fetch optionals attributes and labels
2218 $this->fetch_optionals();
2219
2220 $ret = 1;
2221 }
2222 $this->db->free($result);
2223 return $ret;
2224 } else {
2225 return -1;
2226 }
2227 }
2228
2234 public function insert()
2235 {
2236 $error = 0;
2237
2238 $this->db->begin();
2239
2240 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2241 $sql .= "datec";
2242 $sql .= ", dateo";
2243 $sql .= ", datev";
2244 $sql .= ", label";
2245 $sql .= ", amount";
2246 $sql .= ", amount_main_currency";
2247 $sql .= ", fk_user_author";
2248 $sql .= ", num_chq";
2249 $sql .= ", fk_account";
2250 $sql .= ", fk_type";
2251 $sql .= ", emetteur,banque";
2252 $sql .= ", rappro";
2253 $sql .= ", numero_compte";
2254 $sql .= ", num_releve";
2255 $sql .= ") VALUES (";
2256 $sql .= "'".$this->db->idate($this->datec)."'";
2257 $sql .= ", '".$this->db->idate($this->dateo)."'";
2258 $sql .= ", '".$this->db->idate($this->datev)."'";
2259 $sql .= ", '".$this->db->escape($this->label)."'";
2260 $sql .= ", ".price2num($this->amount);
2261 $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2262 $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2263 $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2264 $sql .= ", '".$this->db->escape($this->fk_account)."'";
2265 $sql .= ", '".$this->db->escape($this->fk_type)."'";
2266 $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2267 $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2268 $sql .= ", ".(int) $this->rappro;
2269 $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2270 $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2271 $sql .= ")";
2272
2273
2274 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2275 $resql = $this->db->query($sql);
2276 if ($resql) {
2277 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2278 // Actions on extra fields (by external module or standard code)
2279 $result = $this->insertExtraFields();
2280 if ($result < 0) {
2281 $error++;
2282 }
2283 } else {
2284 $error++;
2285 $this->error = $this->db->lasterror();
2286 dol_print_error($this->db);
2287 }
2288
2289 if (!$error) {
2290 $this->db->commit();
2291 return $this->id;
2292 } else {
2293 $this->db->rollback();
2294 return -1 * $error;
2295 }
2296 }
2297
2305 public function delete(User $user = null, $notrigger = 0)
2306 {
2307 $nbko = 0;
2308
2309 if ($this->rappro) {
2310 // Protection to avoid any delete of consolidated lines
2311 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2312 return -1;
2313 }
2314
2315 $this->db->begin();
2316
2317 if (!$notrigger) {
2318 // Call trigger
2319 $result = $this->call_trigger('BANKACCOUNTLINE_DELETE', $user);
2320 if ($result < 0) {
2321 $this->db->rollback();
2322 return -1;
2323 }
2324 // End call triggers
2325 }
2326
2327 // Protection to avoid any delete of accounted lines. Protection on by default
2328 if (!getDolGlobalString('BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING')) {
2329 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2330 $resql = $this->db->query($sql);
2331 if ($resql) {
2332 $obj = $this->db->fetch_object($resql);
2333 if ($obj && $obj->nb) {
2334 $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2335 $this->db->rollback();
2336 return -1;
2337 }
2338 } else {
2339 $this->error = $this->db->lasterror();
2340 $this->db->rollback();
2341 return -1;
2342 }
2343 }
2344
2345 // Delete urls
2346 $result = $this->delete_urls($user);
2347 if ($result < 0) {
2348 $nbko++;
2349 }
2350
2351 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid=".(int) $this->rowid;
2352 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2353 $result = $this->db->query($sql);
2354 if (!$result) {
2355 $nbko++;
2356 }
2357
2358 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2359 $result = $this->db->query($sql);
2360 if (!$result) {
2361 $nbko++;
2362 }
2363
2364 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2365 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2366 $result = $this->db->query($sql);
2367 if (!$result) {
2368 $nbko++;
2369 }
2370
2371 if (!$nbko) {
2372 $this->db->commit();
2373 return 1;
2374 } else {
2375 $this->db->rollback();
2376 return -$nbko;
2377 }
2378 }
2379
2380
2381 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2388 public function delete_urls(User $user = null)
2389 {
2390 // phpcs:enable
2391 $nbko = 0;
2392
2393 if ($this->rappro) {
2394 // Protection to avoid any delete of consolidated lines
2395 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2396 return -1;
2397 }
2398
2399 $this->db->begin();
2400
2401 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2402 dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2403 $result = $this->db->query($sql);
2404 if (!$result) {
2405 $nbko++;
2406 }
2407
2408 if (!$nbko) {
2409 $this->db->commit();
2410 return 1;
2411 } else {
2412 $this->db->rollback();
2413 return -$nbko;
2414 }
2415 }
2416
2417
2425 public function update(User $user, $notrigger = 0)
2426 {
2427 $this->db->begin();
2428
2429 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2430 $sql .= " amount = ".price2num($this->amount).",";
2431 $sql .= " datev='".$this->db->idate($this->datev)."',";
2432 $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2433 $sql .= " WHERE rowid = ".((int) $this->rowid);
2434
2435 dol_syslog(get_class($this)."::update", LOG_DEBUG);
2436 $resql = $this->db->query($sql);
2437 if ($resql) {
2438 $this->db->commit();
2439 return 1;
2440 } else {
2441 $this->db->rollback();
2442 $this->error = $this->db->error();
2443 return -1;
2444 }
2445 }
2446
2447
2453 public function updateLabel()
2454 {
2455 $this->db->begin();
2456
2457 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2458 $sql .= " label = '".$this->db->escape($this->label)."'";
2459 $sql .= " WHERE rowid = ".((int) $this->rowid);
2460
2461 dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
2462 $resql = $this->db->query($sql);
2463 if ($resql) {
2464 $this->db->commit();
2465 return 1;
2466 } else {
2467 $this->db->rollback();
2468 $this->error = $this->db->error();
2469 return -1;
2470 }
2471 }
2472
2473
2474 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2483 public function update_conciliation(User $user, $cat, $conciliated = 1)
2484 {
2485 // phpcs:enable
2486 global $conf, $langs;
2487
2488 $this->db->begin();
2489
2490 // Check statement field
2491 if (getDolGlobalString('BANK_STATEMENT_REGEX_RULE')) {
2492 if (!preg_match('/' . getDolGlobalString('BANK_STATEMENT_REGEX_RULE').'/', $this->num_releve)) {
2493 $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", getDolGlobalString('BANK_STATEMENT_REGEX_RULE'));
2494 return -1;
2495 }
2496 }
2497
2498 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2499 $sql .= " rappro = ".((int) $conciliated);
2500 $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2501 if ($conciliated) {
2502 $sql .= ", fk_user_rappro = ".$user->id;
2503 }
2504 $sql .= " WHERE rowid = ".((int) $this->id);
2505
2506 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2507 $resql = $this->db->query($sql);
2508 if ($resql) {
2509 if (!empty($cat) && $cat > 0) {
2510 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
2511 $sql .= "lineid";
2512 $sql .= ", fk_categ";
2513 $sql .= ") VALUES (";
2514 $sql .= $this->id;
2515 $sql .= ", ".((int) $cat);
2516 $sql .= ")";
2517
2518 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2519 $this->db->query($sql);
2520
2521 // No error check. Can fail if category already affected
2522 // TODO Do no try the insert if link already exists
2523 }
2524
2525 $this->rappro = (int) $conciliated;
2526
2527 $this->db->commit();
2528 return 1;
2529 } else {
2530 $this->db->rollback();
2531 return -1;
2532 }
2533 }
2534
2535
2536 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2544 public function datev_change($rowid, $sign = 1)
2545 {
2546 // phpcs:enable
2547 $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2548 $resql = $this->db->query($sql);
2549 if ($resql) {
2550 $obj = $this->db->fetch_object($resql);
2551 $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2552
2553 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2554 $sql .= " datev = '".$this->db->idate($newdate)."'";
2555 $sql .= " WHERE rowid = ".((int) $rowid);
2556
2557 $result = $this->db->query($sql);
2558 if ($result) {
2559 if ($this->db->affected_rows($result)) {
2560 return 1;
2561 }
2562 } else {
2563 dol_print_error($this->db);
2564 return 0;
2565 }
2566 } else {
2567 dol_print_error($this->db);
2568 }
2569 return 0;
2570 }
2571
2572 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2579 public function datev_next($id)
2580 {
2581 // phpcs:enable
2582 return $this->datev_change($id, 1);
2583 }
2584
2585 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2592 public function datev_previous($id)
2593 {
2594 // phpcs:enable
2595 return $this->datev_change($id, -1);
2596 }
2597
2598
2599 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2607 public function dateo_change($rowid, $sign = 1)
2608 {
2609 // phpcs:enable
2610 $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2611 $resql = $this->db->query($sql);
2612 if ($resql) {
2613 $obj = $this->db->fetch_object($resql);
2614 $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2615
2616 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2617 $sql .= " dateo = '".$this->db->idate($newdate)."'";
2618 $sql .= " WHERE rowid = ".((int) $rowid);
2619
2620 $result = $this->db->query($sql);
2621 if ($result) {
2622 if ($this->db->affected_rows($result)) {
2623 return 1;
2624 }
2625 } else {
2626 dol_print_error($this->db);
2627 return 0;
2628 }
2629 } else {
2630 dol_print_error($this->db);
2631 }
2632 return 0;
2633 }
2634
2635 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2642 public function dateo_next($id)
2643 {
2644 // phpcs:enable
2645 return $this->dateo_change($id, 1);
2646 }
2647
2648 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2655 public function dateo_previous($id)
2656 {
2657 // phpcs:enable
2658 return $this->dateo_change($id, -1);
2659 }
2660
2661
2668 public function info($id)
2669 {
2670 $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2671 $sql .= ' b.fk_user_author, b.fk_user_rappro';
2672 $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2673 $sql .= ' WHERE b.rowid = '.((int) $id);
2674
2675 $result = $this->db->query($sql);
2676 if ($result) {
2677 if ($this->db->num_rows($result)) {
2678 $obj = $this->db->fetch_object($result);
2679
2680 $this->id = $obj->rowid;
2681
2682 $this->user_creation_id = $obj->fk_user_author;
2683 $this->user_rappro = $obj->fk_user_rappro;
2684 $this->date_creation = $this->db->jdate($obj->datec);
2685 $this->date_modification = $this->db->jdate($obj->datem);
2686 //$this->date_rappro = $obj->daterappro; // Not yet managed
2687 }
2688 $this->db->free($result);
2689 } else {
2690 dol_print_error($this->db);
2691 }
2692 }
2693
2694
2704 public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2705 {
2706 global $conf, $langs;
2707
2708 $result = '';
2709
2710 $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2711 $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2712 if ($this->amount) {
2713 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2714 }
2715
2716 $linkstart = '<a href="'.DOL_URL_ROOT.'/compta/bank/line.php?rowid='.((int) $this->id).'&save_lastsearch_values=1" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
2717 $linkend = '</a>';
2718
2719 $result .= $linkstart;
2720 if ($withpicto) {
2721 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'account'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
2722 }
2723 if ($withpicto != 2) {
2724 $result .= ($this->ref ? $this->ref : $this->id);
2725 }
2726
2727 $result .= $linkend;
2728
2729 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2730 $result .= ' <span class="opacitymedium">(';
2731 }
2732 if ($option == 'showall') {
2733 $result .= $langs->trans("BankAccount").': ';
2734 $accountstatic = new Account($this->db);
2735 $accountstatic->id = $this->fk_account;
2736 $accountstatic->ref = $this->bank_account_ref;
2737 $accountstatic->label = $this->bank_account_label;
2738 $result .= $accountstatic->getNomUrl(0).', ';
2739 }
2740 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2741 $result .= $langs->trans("BankLineConciliated").': ';
2742 $result .= yn($this->rappro);
2743 }
2744 if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2745 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2746 $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2747 $resql = $this->db->query($sql);
2748 if ($resql) {
2749 $obj = $this->db->fetch_object($resql);
2750 if ($obj && $obj->nb) {
2751 $result .= ' - '.$langs->trans("Accounted").': '.yn(1);
2752 } else {
2753 $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2754 }
2755 }
2756 }
2757 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2758 $result .= ')</span>';
2759 }
2760
2761 return $result;
2762 }
2763
2764
2771 public function getLibStatut($mode = 0)
2772 {
2773 return $this->LibStatut($this->status, $mode);
2774 }
2775
2776 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2784 public function LibStatut($status, $mode = 0)
2785 {
2786 // phpcs:enable
2787 return '';
2788 }
2789
2795 public function getVentilExportCompta()
2796 {
2797 $alreadydispatched = 0;
2798
2799 $type = 'bank';
2800
2801 $sql = " SELECT COUNT(ab.rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='".$this->db->escape($type)."' AND ab.fk_doc = ".((int) $this->id);
2802 $resql = $this->db->query($sql);
2803 if ($resql) {
2804 $obj = $this->db->fetch_object($resql);
2805 if ($obj) {
2806 $alreadydispatched = $obj->nb;
2807 }
2808 } else {
2809 $this->error = $this->db->lasterror();
2810 return -1;
2811 }
2812
2813 if ($alreadydispatched) {
2814 return 1;
2815 }
2816 return 0;
2817 }
2818}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:626
checkSwiftForAccount(Account $account=null, $swift=null)
Check SWIFT information for a bank account.
Definition bank.lib.php:284
checkIbanForAccount(Account $account=null, $ibantocheck=null)
Check IBAN number information for a bank account.
Definition bank.lib.php:305
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition bank.lib.php:330
$object ref
Definition info.php:79
Class to manage bank accounts.
solde($option=0, $date_end='', $field='dateo')
Return current balance.
fetch($id, $ref='')
Load a bank account into memory from database.
__construct(DoliDB $db)
Constructor.
getNomUrl($withpicto=0, $mode='', $option='', $save_lastsearch_value=-1, $notooltip=0, $morecss='')
Return clicable name (with picto eventually)
add_url_line($line_id, $url_id, $url, $label, $type)
Add a link between bank line record and its source.
loadStateBoard($filteraccountid=0)
Load the indicators this->nb for the state board.
update(User $user, $notrigger=0)
Update bank account card.
getCountryCode()
Return account country code.
getLibStatut($mode=0)
Return label of object status.
delete(User $user=null, $notrigger=0)
Delete bank account from database.
getBannerAddress($htmlkey, $object)
Return full address for banner.
error()
Return error.
deprecatedProperties()
Provide list of deprecated properties and replacements.
info($id)
Load miscellaneous information for tab "Info".
const TYPE_CASH
Cash account.
__toString()
Shows the account number in the appropriate format.
const TYPE_SAVINGS
Savings account.
getTooltipContentArray($params)
getTooltipContentArray
canBeConciliated()
Return if a bank account need to be conciliated.
create(User $user, $notrigger=0)
Create bank account into database.
can_be_deleted()
Indicates if an account can be deleted or not (without movements)
update_bban(User $user=null)
Update BBAN (RIB) account fields.
const TYPE_CURRENT
Current account.
setCategories($categories)
Sets object to supplied categories.
countAccountToReconcile()
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
verif()
Return if an account has valid information for Direct debit payment.
getFieldsToShow($includeibanbic=0)
Returns the fields in order that this bank account should show to the user Will return an array with ...
load_board(User $user, $filteraccountid=0)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
get_url($fk_bank=0, $url_id=0, $type='')
TODO Move this into AccountLine Return array with links from llx_bank_url.
addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur='', $banque='', $accountancycode='', $datev=null, $num_releve='', $amount_main_currency=null)
Add an entry into table ".MAIN_DB_PREFIX."bank.
LibStatut($status, $mode=0)
Return label of given object status.
Class to manage bank transaction lines.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
setErrorsFromObject($object)
setErrorsFromObject
getFullAddress($withcountry=0, $sep="\n", $withregion=0, $extralangcode='')
Return full address of contact.
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class to manage generation of HTML components Only common components must be here.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
table table fiche title col title div col center btnTitle icon
Automatically calls the icon named with the corresponding "object_" prefix.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:139
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e rowid
Definition invoice.php:1929