dolibarr 21.0.0-beta
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 public $courant;
78
83 public $type;
84
89 public $bank;
90
98 public $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 public $proprio;
169
174 public $owner_name;
175
180 public $owner_address;
181
186 public $owner_zip;
187
192 public $owner_town;
196 public $owner_country_id;
200 public $owner_country_code;
201
208 public $domiciliation;
209
214 public $address;
218 public $state_id;
222 public $state_code;
226 public $state;
230 public $country_id;
231
237 public $type_lib = array();
238
243 public $account_number;
244
248 public $fk_accountancy_journal;
249
253 public $accountancy_journal;
254
259 public $currency_code;
260
267 public $account_currency_code;
268
273 public $min_allowed;
274
279 public $min_desired;
280
285 public $comment;
286
291 public $date_solde;
292
299 public $solde;
300
305 public $balance;
306
311 public $ics;
312
317 public $ics_transfer;
318
322 public $oldref;
323
324
349 // BEGIN MODULEBUILDER PROPERTIES
353 public $fields = array(
354 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
355 'ref' => array('type' => 'varchar(12)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 25),
356 'label' => array('type' => 'varchar(30)', 'label' => 'Label', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 30),
357 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 35, 'index' => 1),
358 'bank' => array('type' => 'varchar(60)', 'label' => 'Bank', 'enabled' => 1, 'visible' => -1, 'position' => 40),
359 'code_banque' => array('type' => 'varchar(128)', 'label' => 'Code banque', 'enabled' => 1, 'visible' => -1, 'position' => 45),
360 'code_guichet' => array('type' => 'varchar(6)', 'label' => 'Code guichet', 'enabled' => 1, 'visible' => -1, 'position' => 50),
361 'number' => array('type' => 'varchar(255)', 'label' => 'Number', 'enabled' => 1, 'visible' => -1, 'position' => 55),
362 'cle_rib' => array('type' => 'varchar(5)', 'label' => 'Cle rib', 'enabled' => 1, 'visible' => -1, 'position' => 60),
363 'bic' => array('type' => 'varchar(11)', 'label' => 'Bic', 'enabled' => 1, 'visible' => -1, 'position' => 65),
364 'iban_prefix' => array('type' => 'varchar(34)', 'label' => 'Iban prefix', 'enabled' => 1, 'visible' => -1, 'position' => 70),
365 'country_iban' => array('type' => 'varchar(2)', 'label' => 'Country iban', 'enabled' => 1, 'visible' => -1, 'position' => 75),
366 'cle_iban' => array('type' => 'varchar(2)', 'label' => 'Cle iban', 'enabled' => 1, 'visible' => -1, 'position' => 80),
367 'domiciliation' => array('type' => 'varchar(255)', 'label' => 'Domiciliation', 'enabled' => 1, 'visible' => -1, 'position' => 85),
368 'state_id' => array('type' => 'integer', 'label' => 'StateId', 'enabled' => 1, 'visible' => -1, 'position' => 90),
369 'fk_pays' => array('type' => 'integer', 'label' => 'Country', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 95),
370 'proprio' => array('type' => 'varchar(60)', 'label' => 'Proprio', 'enabled' => 1, 'visible' => -1, 'position' => 100),
371 'owner_address' => array('type' => 'varchar(255)', 'label' => 'Owner address', 'enabled' => 1, 'visible' => -1, 'position' => 105),
372 'owner_zip' => array('type' => 'varchar(25)', 'label' => 'Owner zip', 'enabled' => 1, 'visible' => -1, 'position' => 106),
373 'owner_town' => array('type' => 'varchar(50)', 'label' => 'Owner town', 'enabled' => 1, 'visible' => -1, 'position' => 107),
374 'owner_country_id' => array('type' => 'integer', 'label' => 'Owner country', 'enabled' => 1, 'visible' => -1, 'position' => 108),
375 'courant' => array('type' => 'smallint(6)', 'label' => 'Courant', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 110),
376 'clos' => array('type' => 'smallint(6)', 'label' => 'Clos', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 115),
377 'rappro' => array('type' => 'smallint(6)', 'label' => 'Rappro', 'enabled' => 1, 'visible' => -1, 'position' => 120),
378 'url' => array('type' => 'varchar(128)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 125),
379 'account_number' => array('type' => 'varchar(32)', 'label' => 'Account number', 'enabled' => 1, 'visible' => -1, 'position' => 130),
380 'fk_accountancy_journal' => array('type' => 'integer', 'label' => 'Accountancy journal ID', 'enabled' => 1, 'visible' => -1, 'position' => 132),
381 'accountancy_journal' => array('type' => 'varchar(20)', 'label' => 'Accountancy journal', 'enabled' => 1, 'visible' => -1, 'position' => 135),
382 'currency_code' => array('type' => 'varchar(3)', 'label' => 'Currency code', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 140),
383 'min_allowed' => array('type' => 'integer', 'label' => 'Min allowed', 'enabled' => 1, 'visible' => -1, 'position' => 145),
384 'min_desired' => array('type' => 'integer', 'label' => 'Min desired', 'enabled' => 1, 'visible' => -1, 'position' => 150),
385 'comment' => array('type' => 'text', 'label' => 'Comment', 'enabled' => 1, 'visible' => -1, 'position' => 155),
386 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 156),
387 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 157),
388 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 160),
389 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 165),
390 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 170),
391 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 175),
392 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 180),
393 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 185),
394 );
395 // END MODULEBUILDER PROPERTIES
396
400 const TYPE_CURRENT = 1;
404 const TYPE_CASH = 2;
408 const TYPE_SAVINGS = 0;
409
410
411 const STATUS_OPEN = 0;
412 const STATUS_CLOSED = 1;
413
414
420 public function __construct(DoliDB $db)
421 {
422 global $langs;
423
424 $this->db = $db;
425
426 $this->ismultientitymanaged = 1;
427
428 $this->balance = 0;
429
430 $this->type_lib = array(
431 self::TYPE_SAVINGS => $langs->transnoentitiesnoconv("BankType0"),
432 self::TYPE_CURRENT => $langs->transnoentitiesnoconv("BankType1"),
433 self::TYPE_CASH => $langs->transnoentitiesnoconv("BankType2"),
434 );
435
436 $this->labelStatus = array(
437 self::STATUS_OPEN => $langs->transnoentitiesnoconv("StatusAccountOpened"),
438 self::STATUS_CLOSED => $langs->transnoentitiesnoconv("StatusAccountClosed")
439 );
440 }
441
447 public function __toString()
448 {
449 $string = '';
450 foreach ($this->getFieldsToShow() as $val) {
451 if ($val == 'BankCode') {
452 $string .= $this->code_banque.' ';
453 } elseif ($val == 'BankAccountNumber') {
454 $string .= $this->number.' ';
455 } elseif ($val == 'DeskCode') {
456 $string .= $this->code_guichet.' ';
457 } elseif ($val == 'BankAccountNumberKey') {
458 $string .= $this->cle_rib.' ';
459 } elseif ($val == 'BIC') {
460 $string .= $this->bic.' ';
461 } elseif ($val == 'IBAN') {
462 $string .= $this->iban.' ';
463 }
464 }
465
466 return trim($string);
467 }
468
469
475 public function canBeConciliated()
476 {
477 global $conf;
478
479 if (empty($this->rappro)) {
480 return -1;
481 }
482 if ($this->type == Account::TYPE_CASH && !getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
483 return -2;
484 }
485 if ($this->status) {
486 return -3;
487 }
488 return 1;
489 }
490
491
492 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
503 public function add_url_line($line_id, $url_id, $url, $label, $type)
504 {
505 // phpcs:enable
506 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
507 $sql .= "fk_bank";
508 $sql .= ", url_id";
509 $sql .= ", url"; // deprecated
510 $sql .= ", label";
511 $sql .= ", type";
512 $sql .= ") VALUES (";
513 $sql .= ((int) $line_id);
514 $sql .= ", ".((int) $url_id);
515 $sql .= ", '".$this->db->escape($url)."'"; // deprecated
516 $sql .= ", '".$this->db->escape($label)."'";
517 $sql .= ", '".$this->db->escape($type)."'";
518 $sql .= ")";
519
520 dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
521 if ($this->db->query($sql)) {
522 $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
523 return $rowid;
524 } else {
525 $this->error = $this->db->lasterror();
526 return -1;
527 }
528 }
529
530 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
540 public function get_url($fk_bank = 0, $url_id = 0, $type = '')
541 {
542 // phpcs:enable
543 $lines = array();
544
545 // Check parameters
546 if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
547 $this->error = "ErrorBadParameter";
548 return -1;
549 }
550
551 $sql = "SELECT fk_bank, url_id, url, label, type";
552 $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
553 if ($fk_bank > 0) {
554 $sql .= " WHERE fk_bank = ".((int) $fk_bank);
555 } else {
556 $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
557 }
558 $sql .= " ORDER BY type, label";
559
560 dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
561 $result = $this->db->query($sql);
562 if ($result) {
563 $i = 0;
564 $num = $this->db->num_rows($result);
565 while ($i < $num) {
566 $obj = $this->db->fetch_object($result);
567 // Old links (for compatibility)
568 $lines[$i][0] = $obj->url;
569 $lines[$i][1] = $obj->url_id;
570 $lines[$i][2] = $obj->label;
571 $lines[$i][3] = $obj->type;
572 // New links
573 $lines[$i]['url'] = $obj->url;
574 $lines[$i]['url_id'] = $obj->url_id;
575 $lines[$i]['label'] = $obj->label;
576 $lines[$i]['type'] = $obj->type;
577 $lines[$i]['fk_bank'] = $obj->fk_bank;
578 $i++;
579 }
580 } else {
581 dol_print_error($this->db);
582 }
583
584 return $lines;
585 }
586
605 public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
606 {
607 global $langs;
608
609 // Deprecation warning
610 if (is_numeric($oper)) {
611 dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
612 }
613
614 if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
615 $this->id = $this->rowid;
616 }
617
618 // Clean parameters
619 $emetteur = trim($emetteur);
620 $banque = trim($banque);
621 $label = trim($label);
622
623 $now = dol_now();
624
625 if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
626 $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
627 $sql .= " WHERE id = ".((int) $oper);
628 $sql .= " AND entity IN (".getEntity('c_paiement').")";
629 $resql = $this->db->query($sql);
630 if ($resql) {
631 $obj = $this->db->fetch_object($resql);
632 $oper = $obj->code;
633 } else {
634 dol_print_error($this->db, 'Failed to get payment type code');
635 return -1;
636 }
637 }
638
639 // Check parameters
640 if (!$oper) {
641 $this->error = $langs->trans("OperNotDefined");
642 return -1;
643 }
644 if (!$this->id) {
645 $this->error = $langs->trans("ThisIdNotDefined");
646 return -2;
647 }
648 if ($this->type == Account::TYPE_CASH && $oper != 'LIQ') {
649 $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
650 return -3;
651 }
652
653 $this->db->begin();
654
655 if (is_null($datev) || empty($datev)) {
656 $datev = $date;
657 }
658
659 $accline = new AccountLine($this->db);
660 $accline->datec = $now;
661 $accline->dateo = $date;
662 $accline->datev = $datev;
663 $accline->label = $label;
664 $accline->amount = $amount;
665 $accline->amount_main_currency = $amount_main_currency;
666 $accline->fk_user_author = $user->id;
667 $accline->fk_account = $this->id;
668 $accline->fk_type = $oper;
669 $accline->numero_compte = $accountancycode;
670 $accline->num_releve = $num_releve;
671
672 if ($num_chq) {
673 $accline->num_chq = $num_chq;
674 }
675
676 if ($emetteur) {
677 $accline->emetteur = $emetteur;
678 }
679
680 if ($banque) {
681 $accline->bank_chq = $banque;
682 }
683
684 if ($accline->insert() > 0) {
685 if ($categorie > 0) {
686 $sql = "INSERT INTO ".MAIN_DB_PREFIX."category_bankline(";
687 $sql .= "lineid, fk_categ";
688 $sql .= ") VALUES (";
689 $sql .= ((int) $accline->id).", '".$this->db->escape($categorie)."'";
690 $sql .= ")";
691
692 $result = $this->db->query($sql);
693 if (!$result) {
694 $this->error = $this->db->lasterror();
695 $this->db->rollback();
696
697 return -4;
698 }
699 }
700
701 $this->db->commit();
702
703 return $accline->id;
704 } else {
705 $this->setErrorsFromObject($accline);
706 $this->db->rollback();
707
708 return -5;
709 }
710 }
711
719 public function create($user, $notrigger = 0)
720 {
721 global $langs, $conf;
722
723 $error = 0;
724
725 // Clean parameters
726 if (!$this->min_allowed) {
727 $this->min_allowed = 0;
728 }
729 if (!$this->min_desired) {
730 $this->min_desired = 0;
731 }
732
733 // Check parameters
734 if (empty($this->country_id)) {
735 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
736 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
737 return -1;
738 }
739 if (empty($this->ref)) {
740 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
741 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
742 return -1;
743 }
744 if (empty($this->date_solde)) {
745 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
746 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
747 return -1;
748 }
749
750 // Load libraries to check BAN
751 $balance = $this->balance;
752 if (empty($balance) && !empty($this->solde)) {
753 $balance = $this->solde;
754 }
755 if (empty($balance)) {
756 $balance = 0;
757 }
758 if (empty($this->status && !empty($this->clos))) {
759 dol_syslog(get_class($this)."::create clos is deprecated use status", LOG_NOTICE);
760 $this->status = $this->clos;
761 }
762
763 // Load the library to validate/check a BAN account
764 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
765
766 $now = dol_now();
767
768 $this->db->begin();
769
770 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
771 $sql .= "datec";
772 $sql .= ", ref";
773 $sql .= ", label";
774 $sql .= ", entity";
775 $sql .= ", account_number";
776 $sql .= ", fk_accountancy_journal";
777 $sql .= ", bank";
778 $sql .= ", code_banque";
779 $sql .= ", code_guichet";
780 $sql .= ", number";
781 $sql .= ", cle_rib";
782 $sql .= ", bic";
783 $sql .= ", iban_prefix";
784 $sql .= ", domiciliation";
785 $sql .= ", pti_in_ctti";
786 $sql .= ", proprio";
787 $sql .= ", owner_address";
788 $sql .= ", owner_zip";
789 $sql .= ", owner_town";
790 $sql .= ", owner_country_id";
791 $sql .= ", currency_code";
792 $sql .= ", rappro";
793 $sql .= ", min_allowed";
794 $sql .= ", min_desired";
795 $sql .= ", comment";
796 $sql .= ", state_id";
797 $sql .= ", fk_pays";
798 $sql .= ", ics";
799 $sql .= ", ics_transfer";
800 $sql .= ") VALUES (";
801 $sql .= "'".$this->db->idate($now)."'";
802 $sql .= ", '".$this->db->escape($this->ref)."'";
803 $sql .= ", '".$this->db->escape($this->label)."'";
804 $sql .= ", ".((int) $conf->entity);
805 $sql .= ", '".$this->db->escape($this->account_number)."'";
806 $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
807 $sql .= ", '".$this->db->escape($this->bank)."'";
808 $sql .= ", '".$this->db->escape($this->code_banque)."'";
809 $sql .= ", '".$this->db->escape($this->code_guichet)."'";
810 $sql .= ", '".$this->db->escape($this->number)."'";
811 $sql .= ", '".$this->db->escape($this->cle_rib)."'";
812 $sql .= ", '".$this->db->escape($this->bic)."'";
813 $sql .= ", '".$this->db->escape($this->iban)."'";
814 $sql .= ", '".$this->db->escape($this->address)."'";
815 $sql .= ", ".((int) $this->pti_in_ctti);
816 $sql .= ", '".$this->db->escape($this->owner_name)."'";
817 $sql .= ", '".$this->db->escape($this->owner_address)."'";
818 $sql .= ", '".$this->db->escape($this->owner_zip)."'";
819 $sql .= ", '".$this->db->escape($this->owner_town)."'";
820 $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
821 $sql .= ", '".$this->db->escape($this->currency_code)."'";
822 $sql .= ", ".((int) $this->rappro);
823 $sql .= ", ".price2num($this->min_allowed, 'MT');
824 $sql .= ", ".price2num($this->min_desired, 'MT');
825 $sql .= ", '".$this->db->escape($this->comment)."'";
826 $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
827 $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
828 $sql .= ", '".$this->db->escape($this->ics)."'";
829 $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
830 $sql .= ")";
831
832 dol_syslog(get_class($this)."::create", LOG_DEBUG);
833 $resql = $this->db->query($sql);
834 if ($resql) {
835 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
836
837 $result = $this->update($user, 1);
838 if ($result > 0) {
839 $accline = new AccountLine($this->db);
840 $accline->datec = $now;
841 $accline->label = '('.$langs->trans("InitialBankBalance").')';
842 $accline->amount = (float) price2num($balance);
843 $accline->fk_user_author = $user->id;
844 $accline->fk_account = $this->id;
845 $accline->datev = $this->date_solde;
846 $accline->dateo = $this->date_solde;
847 $accline->fk_type = 'SOLD';
848
849 if ($accline->insert() < 0) {
850 $error++;
851 $this->error = $accline->error;
852 $this->errors = $accline->errors;
853 }
854
855 if (!$error) {
856 $result = $this->insertExtraFields();
857 if ($result < 0) {
858 $error++;
859 }
860 }
861
862 if (!$error && !$notrigger) {
863 // Call trigger
864 $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
865 if ($result < 0) {
866 $error++;
867 }
868 // End call triggers
869 }
870 } else {
871 $error++;
872 }
873 } else {
874 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
875 $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
876 $error++;
877 } else {
878 $this->error = $this->db->error()." sql=".$sql;
879 $error++;
880 }
881 }
882
883 if (!$error) {
884 $this->db->commit();
885 return $this->id;
886 } else {
887 $this->db->rollback();
888 return -1 * $error;
889 }
890 }
891
899 public function update($user, $notrigger = 0)
900 {
901 global $langs, $conf;
902
903 $error = 0;
904
905 $this->db->begin();
906
907 // Check parameters
908 if (empty($this->country_id)) {
909 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
910 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
911 return -1;
912 }
913 if (empty($this->ref)) {
914 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
915 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
916 return -1;
917 }
918 if (!$this->label) {
919 $this->label = "???";
920 }
921
922 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
923 $sql .= " ref = '".$this->db->escape($this->ref)."'";
924 $sql .= ",label = '".$this->db->escape($this->label)."'";
925 $sql .= ",courant = ".((int) $this->type);
926 $sql .= ",clos = ".((int) $this->status);
927 $sql .= ",rappro = ".((int) $this->rappro);
928 $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
929 $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
930 $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
931 $sql .= ",bank = '".$this->db->escape($this->bank)."'";
932 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
933 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
934 $sql .= ",number='".$this->db->escape($this->number)."'";
935 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
936 $sql .= ",bic='".$this->db->escape($this->bic)."'";
937 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
938 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
939 $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
940 $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'";
941 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
942 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
943 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
944 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
945
946 $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
947
948 $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
949 $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
950 $sql .= ",comment = '".$this->db->escape($this->comment)."'";
951
952 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
953 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
954 $sql .= ",ics = '".$this->db->escape($this->ics)."'";
955 $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
956
957 $sql .= " WHERE rowid = ".((int) $this->id);
958
959 dol_syslog(get_class($this)."::update", LOG_DEBUG);
960 $result = $this->db->query($sql);
961 if ($result) {
962 // Actions on extra fields (by external module or standard code)
963 if (!$error) {
964 $result = $this->insertExtraFields();
965 if ($result < 0) {
966 $error++;
967 }
968 }
969
970 if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
971 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
972 $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type='bank_account' and entity = ".((int) $conf->entity);
973 $resql = $this->db->query($sql);
974 if (!$resql) {
975 $error++;
976 $this->error = $this->db->lasterror();
977 }
978
979 // We rename directory in order not to lose the attachments
980 $oldref = dol_sanitizeFileName($this->oldref);
981 $newref = dol_sanitizeFileName($this->ref);
982 $dirsource = $conf->bank->dir_output.'/'.$oldref;
983 $dirdest = $conf->bank->dir_output.'/'.$newref;
984 if (file_exists($dirsource)) {
985 dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
986 if (@rename($dirsource, $dirdest)) {
987 dol_syslog("Rename ok", LOG_DEBUG);
988 }
989 }
990 }
991
992 if (!$error && !$notrigger) {
993 // Call trigger
994 $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
995 if ($result < 0) {
996 $error++;
997 }
998 // End call triggers
999 }
1000 } else {
1001 $error++;
1002 $this->error = $this->db->lasterror();
1003 dol_print_error($this->db);
1004 }
1005
1006 if (!$error) {
1007 $this->db->commit();
1008 return $this->id;
1009 } else {
1010 $this->db->rollback();
1011 return -1 * $error;
1012 }
1013 }
1014
1015
1016 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1023 public function update_bban($user = null)
1024 {
1025 // phpcs:enable
1026 global $conf, $langs;
1027
1028 // Load library to get BAN control function
1029 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1030
1031 dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
1032
1033 // Check parameters
1034 if (!$this->ref) {
1035 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
1036 return -2;
1037 }
1038
1039 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
1040 $sql .= " bank = '".$this->db->escape($this->bank)."'";
1041 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1042 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1043 $sql .= ",number='".$this->db->escape($this->number)."'";
1044 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1045 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1046 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1047 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
1048 $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'";
1049 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1050 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1051 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1052 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1053 $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
1054 $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
1055 $sql .= " WHERE rowid = ".((int) $this->id);
1056 $sql .= " AND entity = ".((int) $conf->entity);
1057
1058 dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
1059
1060 $result = $this->db->query($sql);
1061 if ($result) {
1062 return 1;
1063 } else {
1064 $this->error = $this->db->lasterror();
1065 dol_print_error($this->db);
1066 return -1;
1067 }
1068 }
1069
1070
1078 public function fetch($id, $ref = '')
1079 {
1080 if (empty($id) && empty($ref)) {
1081 $this->error = "ErrorBadParameters";
1082 return -1;
1083 }
1084
1085 $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant as type, ba.clos as status, ba.rappro, ba.url,";
1086 $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1087 $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,";
1088 $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1089 $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1090 $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1091 $sql .= ' c.code as country_code, c.label as country,';
1092 $sql .= ' d.code_departement as state_code, d.nom as state,';
1093 $sql .= ' aj.code as accountancy_journal';
1094 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1095 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1096 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1097 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1098 $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1099 if ($id) {
1100 $sql .= " AND ba.rowid = ".((int) $id);
1101 }
1102 if ($ref) {
1103 $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1104 }
1105
1106 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1107 $result = $this->db->query($sql);
1108 if ($result) {
1109 if ($this->db->num_rows($result)) {
1110 $obj = $this->db->fetch_object($result);
1111
1112 $this->id = $obj->rowid;
1113 $this->rowid = $obj->rowid;
1114 $this->ref = $obj->ref;
1115 $this->label = $obj->label;
1116 $this->type = $obj->type;
1117 $this->courant = $obj->type;
1118 $this->bank = $obj->bank;
1119 $this->clos = $obj->status;
1120 $this->status = $obj->status;
1121 $this->rappro = $obj->rappro;
1122 $this->url = $obj->url;
1123
1124 $this->code_banque = $obj->code_banque;
1125 $this->code_guichet = $obj->code_guichet;
1126 $this->number = $obj->number;
1127 $this->cle_rib = $obj->cle_rib;
1128 $this->bic = $obj->bic;
1129 $this->iban = $obj->iban;
1130 $this->address = $obj->address;
1131
1132 $this->owner_name = $obj->owner_name;
1133 $this->proprio = $this->owner_name;
1134 $this->owner_address = $obj->owner_address;
1135 $this->owner_zip = $obj->owner_zip;
1136 $this->owner_town = $obj->owner_town;
1137 $this->owner_country_id = $obj->owner_country_id;
1138
1139 $this->pti_in_ctti = $obj->pti_in_ctti;
1140
1141 $this->state_id = $obj->state_id;
1142 $this->state_code = $obj->state_code;
1143 $this->state = $obj->state;
1144
1145 $this->country_id = $obj->country_id;
1146 $this->country_code = $obj->country_code;
1147 $this->country = $obj->country;
1148
1149 $this->account_number = $obj->account_number;
1150 $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1151 $this->accountancy_journal = $obj->accountancy_journal;
1152
1153 $this->currency_code = $obj->currency_code;
1154 $this->account_currency_code = $obj->currency_code;
1155 $this->min_allowed = $obj->min_allowed;
1156 $this->min_desired = $obj->min_desired;
1157 $this->comment = $obj->comment;
1158
1159 $this->date_creation = $this->db->jdate($obj->date_creation);
1160 $this->date_modification = $this->db->jdate($obj->date_modification);
1161
1162 $this->ics = $obj->ics;
1163 $this->ics_transfer = $obj->ics_transfer;
1164
1165 // Retrieve all extrafield
1166 // fetch optionals attributes and labels
1167 $this->fetch_optionals();
1168
1169 return 1;
1170 } else {
1171 return 0;
1172 }
1173 } else {
1174 $this->error = $this->db->lasterror();
1175 $this->errors[] = $this->error;
1176 return -1;
1177 }
1178 }
1179
1190 public function setCategories($categories)
1191 {
1192 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1193 return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1194 }
1195
1203 public function delete($user = null, $notrigger = 0)
1204 {
1205 $error = 0;
1206
1207 $this->db->begin();
1208
1209 // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1210
1211 // Delete link between tag and bank account
1212 if (!$error) {
1213 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1214 $sql .= " WHERE fk_account = ".((int) $this->id);
1215
1216 $resql = $this->db->query($sql);
1217 if (!$resql) {
1218 $error++;
1219 $this->error = "Error ".$this->db->lasterror();
1220 }
1221 }
1222
1223 if (!$error) {
1224 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1225 $sql .= " WHERE rowid = ".((int) $this->id);
1226
1227 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1228 $result = $this->db->query($sql);
1229 if ($result) {
1230 // Remove extrafields
1231 if (!$error) {
1232 $result = $this->deleteExtraFields();
1233 if ($result < 0) {
1234 $error++;
1235 dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1236 }
1237 }
1238 } else {
1239 $error++;
1240 $this->error = "Error ".$this->db->lasterror();
1241 }
1242 }
1243
1244 if (!$error) {
1245 $this->db->commit();
1246 return 1;
1247 } else {
1248 $this->db->rollback();
1249 return -1;
1250 }
1251 }
1252
1253
1260 public function getLibStatut($mode = 0)
1261 {
1262 return $this->LibStatut($this->status, $mode);
1263 }
1264
1265 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1273 public function LibStatut($status, $mode = 0)
1274 {
1275 // phpcs:enable
1276 global $langs;
1277 $langs->load('banks');
1278
1279 if ($status == self::STATUS_OPEN) {
1280 $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1281 $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1282 $statusType = 'status4';
1283 } else {
1284 $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1285 $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1286 $statusType = 'status5';
1287 }
1288
1289 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1290 }
1291
1292
1293 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1299 public function can_be_deleted()
1300 {
1301 // phpcs:enable
1302 $can_be_deleted = false;
1303
1304 $sql = "SELECT COUNT(rowid) as nb";
1305 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1306 $sql .= " WHERE fk_account = ".((int) $this->id);
1307
1308 $resql = $this->db->query($sql);
1309 if ($resql) {
1310 $obj = $this->db->fetch_object($resql);
1311 if ($obj->nb <= 1) {
1312 $can_be_deleted = true; // Juste le solde
1313 }
1314 } else {
1315 dol_print_error($this->db);
1316 }
1317 return $can_be_deleted;
1318 }
1319
1320
1326 public function error()
1327 {
1328 return $this->error;
1329 }
1330
1339 public function solde($option = 0, $date_end = '', $field = 'dateo')
1340 {
1341 $solde = 0;
1342
1343 $sql = "SELECT sum(amount) as amount";
1344 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1345 $sql .= " WHERE fk_account = ".((int) $this->id);
1346 if ($option == 1) {
1347 $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1348 }
1349
1350 $resql = $this->db->query($sql);
1351 if ($resql) {
1352 if ($this->db->num_rows($resql)) {
1353 $obj = $this->db->fetch_object($resql);
1354 $solde = $obj->amount;
1355 }
1356 $this->db->free($resql);
1357 } else {
1358 $this->errors[] = $this->db->lasterror;
1359 return -1;
1360 }
1361
1362 return (float) price2num($solde, 'MU');
1363 }
1364
1365 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1373 public function load_board(User $user, $filteraccountid = 0)
1374 {
1375 // phpcs:enable
1376 global $conf, $langs;
1377
1378 if ($user->socid) {
1379 return -1; // protection pour eviter appel par utilisateur externe
1380 }
1381
1382 $sql = "SELECT b.rowid, b.datev as datefin";
1383 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1384 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1385 $sql .= " WHERE b.rappro=0";
1386 $sql .= " AND b.fk_account = ba.rowid";
1387 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1388 $sql .= " AND (ba.rappro = 1 AND ba.courant != " . Account::TYPE_CASH . ")"; // Compte rapprochable
1389 $sql .= " AND clos = 0";
1390 if ($filteraccountid) {
1391 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1392 }
1393
1394 $resql = $this->db->query($sql);
1395 if ($resql) {
1396 $langs->load("banks");
1397 $now = dol_now();
1398
1399 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1400
1401 $response = new WorkboardResponse();
1402 $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1403 $response->label = $langs->trans("TransactionsToConciliate");
1404 $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1405 $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1406 $response->img = img_object('', "payment");
1407
1408 while ($obj = $this->db->fetch_object($resql)) {
1409 $response->nbtodo++;
1410 if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1411 $response->nbtodolate++;
1412 }
1413 }
1414
1415 return $response;
1416 } else {
1417 dol_print_error($this->db);
1418 $this->error = $this->db->error();
1419 return -1;
1420 }
1421 }
1422
1429 public function loadStateBoard($filteraccountid = 0)
1430 {
1431 global $user;
1432
1433 if ($user->socid) {
1434 return -1; // protection pour eviter appel par utilisateur externe
1435 }
1436
1437 $sql = "SELECT count(b.rowid) as nb";
1438 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1439 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1440 $sql .= " WHERE b.fk_account = ba.rowid";
1441 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1442 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1443 $sql .= " AND clos = 0";
1444 if ($filteraccountid) {
1445 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1446 }
1447
1448 $resql = $this->db->query($sql);
1449 if ($resql) {
1450 while ($obj = $this->db->fetch_object($resql)) {
1451 $this->nb["banklines"] = $obj->nb;
1452 }
1453 $this->db->free($resql);
1454 return 1;
1455 } else {
1456 dol_print_error($this->db);
1457 $this->error = $this->db->error();
1458 return -1;
1459 }
1460 }
1461
1462
1468 public function countAccountToReconcile()
1469 {
1470 global $user;
1471
1472 //Protection against external users
1473 if ($user->socid) {
1474 return 0;
1475 }
1476
1477 $nb = 0;
1478
1479 $sql = "SELECT COUNT(ba.rowid) as nb";
1480 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1481 $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1482 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1483 if (!getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
1484 $sql .= " AND ba.courant != " . Account::TYPE_CASH;
1485 }
1486
1487 $resql = $this->db->query($sql);
1488 if ($resql) {
1489 $obj = $this->db->fetch_object($resql);
1490 $nb = $obj->nb;
1491 } else {
1492 dol_print_error($this->db);
1493 }
1494
1495 return $nb;
1496 }
1497
1504 public function getTooltipContentArray($params)
1505 {
1506 global $langs;
1507 $langs->loadLangs(['banks', 'compta']);
1508 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1509
1510 $datas = array();
1511
1512 $nofetch = !empty($params['nofetch']);
1513 $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1514 if (isset($this->status)) {
1515 $pictos .= ' '.$this->getLibStatut(5);
1516 }
1517 $datas['picto'] = $pictos;
1518 $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1519 $datas['accountnumber'] = '<br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1520 $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1521 $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1522 $datas['accountcurrency'] = '<br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1523
1524 if (isModEnabled('accounting')) {
1525 include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1526 $langs->load("accountancy");
1527 $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1528 $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1529 }
1530 // show categories for this record only in ajax to not overload lists
1531 if (isModEnabled('category') && !$nofetch) {
1532 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1533 $form = new Form($this->db);
1534 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1535 }
1536
1537 return $datas;
1538 }
1539
1551 public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1552 {
1553 global $conf, $langs;
1554
1555 if (!empty($conf->dol_no_mouse_hover)) {
1556 $notooltip = 1; // Force disable tooltips
1557 }
1558
1559 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1560
1561 $result = '';
1562 $classfortooltip = 'classfortooltip';
1563 $dataparams = '';
1564 $params = [
1565 'id' => $this->id,
1566 'objecttype' => $this->element,
1567 'option' => $option,
1568 'nofetch' => 1,
1569 ];
1570 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1571 $classfortooltip = 'classforajaxtooltip';
1572 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1573 $label = '';
1574 } else {
1575 $label = implode($this->getTooltipContentArray($params));
1576 }
1577
1578 $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1579 if ($mode == 'transactions') {
1580 $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1581 } elseif ($mode == 'receipts') {
1582 $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1583 }
1584
1585 if ($option != 'nolink') {
1586 // Add param to save lastsearch_values or not
1587 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1588 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1589 $add_save_lastsearch_values = 1;
1590 }
1591 if ($add_save_lastsearch_values) {
1592 $url .= '&save_lastsearch_values=1';
1593 }
1594 }
1595
1596 $linkclose = '';
1597 if (empty($notooltip)) {
1598 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1599 $label = $langs->trans("BankAccount");
1600 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1601 }
1602 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1603 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1604 } else {
1605 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1606 }
1607
1608 if ($option == 'nolink' || empty($url)) {
1609 $linkstart = '<span';
1610 } else {
1611 $linkstart = '<a href="'.$url.'"';
1612 }
1613 $linkstart .= $linkclose.'>';
1614 if ($option == 'nolink' || empty($url)) {
1615 $linkend = '</span>';
1616 } else {
1617 $linkend = '</a>';
1618 }
1619
1620 $result .= $linkstart;
1621
1622 if ($withpicto) {
1623 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1624 }
1625 if ($withpicto != 2) {
1626 $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1627 }
1628 $result .= $linkend;
1629
1630 return $result;
1631 }
1632
1633
1634 // Method after here are common to Account and CompanyBankAccount
1635
1636
1642 public function verif()
1643 {
1644 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1645
1646 $error = 0;
1647
1648 // Call functions to check BAN
1649 if (!checkIbanForAccount($this)) {
1650 $error++;
1651 $this->error = 'IBANNotValid';
1652 }
1653 // Call function to check Swift/BIC.
1654 // A non valid BIC/Swift is a problem if: it is not empty or always a problem if WITHDRAWAL_WITHOUT_BIC is not set).
1655 if (!checkSwiftForAccount($this) && (!empty($this->bic) || !getDolGlobalInt('WITHDRAWAL_WITHOUT_BIC'))) {
1656 $error++;
1657 $this->error = 'SwiftNotValid';
1658 }
1659
1660 if (! $error) {
1661 return 1;
1662 } else {
1663 return 0;
1664 }
1665 }
1666
1672 public function getCountryCode()
1673 {
1674 global $mysoc;
1675
1676 // We return country code of bank account
1677 if (!empty($this->country_code)) {
1678 return $this->country_code;
1679 }
1680
1681 // For backward compatibility, we try to guess country from other information
1682 if (!empty($this->iban)) {
1683 // If IBAN defined, we can know country of account from it
1684 $reg = array();
1685 if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1686 return $reg[1];
1687 }
1688 }
1689
1690 // If this class is linked to a third party
1691 if (!empty($this->socid)) {
1692 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1693 $company = new Societe($this->db);
1694 $result = $company->fetch($this->socid);
1695 if (!empty($company->country_code)) {
1696 return $company->country_code;
1697 }
1698 }
1699
1700 // We return country code of managed company
1701 if (!empty($mysoc->country_code)) {
1702 return $mysoc->country_code;
1703 }
1704
1705 return '';
1706 }
1707
1715 public function getBannerAddress($htmlkey, $object)
1716 {
1717 global $conf, $langs;
1718
1719 $out = '';
1720
1721 $outdone = 0;
1722 $coords = $this->getFullAddress(1, ', ', getDolGlobalInt('MAIN_SHOW_REGION_IN_STATE_SELECT'));
1723 if ($coords) {
1724 if (!empty($conf->use_javascript_ajax)) {
1725 // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
1726 $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
1727 $out .= img_picto($langs->trans("Address"), 'map-marker-alt');
1728 $out .= '</a> ';
1729 }
1730 $address = dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
1731 if ($address) {
1732 $out .= $address;
1733 $outdone++;
1734 }
1735 $outdone++;
1736 }
1737
1738 return $out;
1739 }
1740
1741
1750 public function useDetailedBBAN()
1751 {
1752 $country_code = $this->getCountryCode();
1753
1754 if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1755 return 1; // France, Spain, Gabon, ... - Not valid for CH
1756 }
1757 if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1758 return 2; // Australia, England...
1759 }
1760 return 0;
1761 }
1762
1768 public function needIBAN()
1769 {
1770 global $conf;
1771
1772 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1773 return 0;
1774 }
1775
1776 $country_code = $this->getCountryCode();
1777
1778 $country_code_in_EEC = array(
1779 'AT', // Austria
1780 'BE', // Belgium
1781 'BG', // Bulgaria
1782 'CY', // Cyprus
1783 'CZ', // Czech republic
1784 'DE', // Germany
1785 'DK', // Danemark
1786 'EE', // Estonia
1787 'ES', // Spain
1788 'FI', // Finland
1789 'FR', // France
1790 'GB', // United Kingdom
1791 'GR', // Greece
1792 'HR', // Croatia
1793 'NL', // Holland
1794 'HU', // Hungary
1795 'IE', // Ireland
1796 'IM', // Isle of Man - Included in UK
1797 'IT', // Italy
1798 'LT', // Lithuania
1799 'LU', // Luxembourg
1800 'LV', // Latvia
1801 'MC', // Monaco - Included in France
1802 'MT', // Malta
1803 //'NO', // Norway
1804 'PL', // Poland
1805 'PT', // Portugal
1806 'RO', // Romania
1807 'SE', // Sweden
1808 'SK', // Slovakia
1809 'SI', // Slovenia
1810 'UK', // United Kingdom
1811 //'CH', // Switzerland - No. Swizerland in not in EEC
1812 );
1813
1814 if (in_array($country_code, $country_code_in_EEC)) {
1815 return 1; // France, Spain, ...
1816 }
1817 return 0;
1818 }
1819
1825 public function needBIC()
1826 {
1827 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1828 return 0;
1829 }
1830
1831 $country_code = $this->getCountryCode();
1832
1833 $country_code_in_EEC = array(
1834 'AD', // Andorra
1835 'BH', // Bahrein
1836 'DK', // Denmark
1837 'FR', // France
1838 'GH', // Ghana
1839 'HU', // Hungary
1840 'JP', // Japan
1841 'LV', // Latvia
1842 'SE', // Sweden
1843 );
1844
1845 if (in_array($country_code, $country_code_in_EEC)) {
1846 return 1; // Andorra, Bahrein, ...
1847 }
1848 return 0;
1849 }
1850
1857 public function info($id)
1858 {
1859 }
1860
1875 public function getFieldsToShow($includeibanbic = 0)
1876 {
1877 //Get the required properties depending on the country
1878 $detailedBBAN = $this->useDetailedBBAN();
1879
1880 if ($detailedBBAN == 0) {
1881 $fieldarray = array(
1882 'BankAccountNumber'
1883 );
1884 } elseif ($detailedBBAN == 2) {
1885 $fieldarray = array(
1886 'BankCode',
1887 'BankAccountNumber'
1888 );
1889 } else {
1890 $fieldarray = self::getAccountNumberOrder();
1891 }
1892
1893 //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1894 if ($includeibanbic) {
1895 $fieldarray[] = 'IBAN';
1896 $fieldarray[] = 'BIC';
1897 }
1898 //}
1899
1900 //Get the order the properties are shown
1901 return $fieldarray;
1902 }
1903
1914 public static function getAccountNumberOrder()
1915 {
1916 global $conf;
1917
1918 $fieldlists = array(
1919 'BankCode',
1920 'DeskCode',
1921 'BankAccountNumber',
1922 'BankAccountNumberKey'
1923 );
1924
1925 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION')) {
1926 if (is_numeric(getDolGlobalString('BANK_SHOW_ORDER_OPTION'))) {
1927 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION') == '1') {
1928 $fieldlists = array(
1929 'BankCode',
1930 'DeskCode',
1931 'BankAccountNumberKey',
1932 'BankAccountNumber'
1933 );
1934 }
1935 } else {
1936 //Replace the old AccountNumber key with the new BankAccountNumber key
1937 $fieldlists = explode(
1938 ' ',
1939 preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1940 );
1941 }
1942 }
1943
1944 return $fieldlists;
1945 }
1946
1947
1955 public function initAsSpecimen()
1956 {
1957 // Example of IBAN FR7630001007941234567890185
1958 $this->specimen = 1;
1959 $this->ref = 'MBA';
1960 $this->label = 'My Big Company Bank account';
1961 $this->courant = Account::TYPE_CURRENT;
1962 $this->clos = Account::STATUS_OPEN;
1963 $this->type = Account::TYPE_CURRENT;
1964 $this->status = Account::STATUS_OPEN;
1965 $this->code_banque = '30001';
1966 $this->code_guichet = '00794';
1967 $this->number = '12345678901';
1968 $this->cle_rib = '85';
1969 $this->bic = 'AA12';
1970 $this->iban = 'FR7630001007941234567890185';
1971
1972 $this->bank = 'MyBank';
1973 $this->address = 'Rue de Paris';
1974 $this->owner_name = 'Owner';
1975 $this->owner_address = 'Owner address';
1976 $this->owner_zip = 'Owner zip';
1977 $this->owner_town = 'Owner town';
1978 $this->owner_country_id = 1;
1979 $this->country_id = 1;
1980
1981 return 1;
1982 }
1983
1992 public static function replaceThirdparty($dbs, $origin_id, $dest_id)
1993 {
1994 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'";
1995
1996 if ($dbs->query($sql)) {
1997 return true;
1998 } else {
1999 //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.
2000 //$this->errors = $dbs->lasterror();
2001 return false;
2002 }
2003 }
2004
2012 public function getKanbanView($option = '', $arraydata = null)
2013 {
2014 global $langs;
2015
2016 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2017
2018 $return = '<div class="box-flex-item box-flex-grow-zero">';
2019 $return .= '<div class="info-box info-box-sm">';
2020 $return .= '<span class="info-box-icon bg-infobox-action">';
2021 $return .= img_picto('', $this->picto);
2022 $return .= '</span>';
2023 $return .= '<div class="info-box-content">';
2024 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
2025 if ($selected >= 0) {
2026 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2027 }
2028 if (property_exists($this, 'type_lib')) {
2029 $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
2030 }
2031 if (method_exists($this, 'solde')) {
2032 $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
2033 $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>';
2034 }
2035 if (method_exists($this, 'getLibStatut')) {
2036 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2037 }
2038 $return .= '</div>';
2039 $return .= '</div>';
2040 $return .= '</div>';
2041 return $return;
2042 }
2043}
2044
2045
2046require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
2047
2051class AccountLine extends CommonObjectLine
2052{
2056 public $db;
2057
2061 public $element = 'bank';
2062
2066 public $table_element = 'bank';
2067
2071 public $picto = 'accountline';
2072
2076 public $id;
2077
2081 public $ref;
2082
2088 public $datec;
2089
2095 public $dateo;
2096
2102 public $datev;
2103
2107 public $amount;
2108
2112 public $amount_main_currency;
2113
2117 public $fk_user_author;
2118
2122 public $fk_user_rappro;
2123
2127 public $fk_type;
2128
2132 public $fk_bordereau;
2133
2137 public $fk_account;
2138
2142 public $bank_account_ref;
2143
2147 public $bank_account_label;
2148
2152 public $numero_compte;
2153
2157 public $emetteur;
2158
2162 public $rappro;
2163
2167 public $num_releve;
2168
2172 public $num_chq;
2173
2177 public $bank_chq;
2178
2182 public $label;
2183
2187 public $note;
2188
2194 public $user_rappro;
2195
2196
2202 public function __construct(DoliDB $db)
2203 {
2204 $this->db = $db;
2205 }
2206
2215 public function fetch($rowid, $ref = '', $num = '')
2216 {
2217 // Check parameters
2218 if (empty($rowid) && empty($ref) && empty($num)) {
2219 return -1;
2220 }
2221
2222 $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2223 $sql .= " b.fk_user_author, b.fk_user_rappro,";
2224 $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2225 $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2226 $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2227 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2228 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2229 $sql .= " WHERE b.fk_account = ba.rowid";
2230 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2231 if ($num) {
2232 $sql .= " AND b.num_chq = '".$this->db->escape($num)."'";
2233 } elseif ($ref) {
2234 $sql .= " AND b.rowid = '".$this->db->escape($ref)."'";
2235 } else {
2236 $sql .= " AND b.rowid = ".((int) $rowid);
2237 }
2238
2239 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2240 $result = $this->db->query($sql);
2241 if ($result) {
2242 $ret = 0;
2243
2244 $obj = $this->db->fetch_object($result);
2245 if ($obj) {
2246 $this->id = $obj->rowid;
2247 $this->rowid = $obj->rowid;
2248 $this->ref = $obj->rowid;
2249
2250 $this->datec = $this->db->jdate($obj->datec);
2251 $this->datev = $this->db->jdate($obj->datev);
2252 $this->dateo = $this->db->jdate($obj->dateo);
2253 $this->amount = $obj->amount;
2254 $this->label = $obj->label;
2255 $this->note = $obj->note;
2256
2257 $this->fk_user_author = $obj->fk_user_author;
2258 $this->fk_user_rappro = $obj->fk_user_rappro;
2259
2260 $this->fk_type = $obj->fk_type; // Type of transaction
2261 $this->rappro = (int) $obj->rappro;
2262 $this->num_releve = $obj->num_releve;
2263
2264 $this->num_chq = $obj->num_chq;
2265 $this->bank_chq = $obj->banque;
2266 $this->fk_bordereau = $obj->fk_bordereau;
2267
2268 $this->fk_account = $obj->fk_account;
2269 $this->bank_account_ref = $obj->bank_account_ref;
2270 $this->bank_account_label = $obj->bank_account_label;
2271
2272 // Retrieve all extrafield
2273 // fetch optionals attributes and labels
2274 $this->fetch_optionals();
2275
2276 $ret = 1;
2277 }
2278 $this->db->free($result);
2279 return $ret;
2280 } else {
2281 return -1;
2282 }
2283 }
2284
2290 public function insert()
2291 {
2292 $error = 0;
2293
2294 $this->db->begin();
2295
2296 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2297 $sql .= "datec";
2298 $sql .= ", dateo";
2299 $sql .= ", datev";
2300 $sql .= ", label";
2301 $sql .= ", amount";
2302 $sql .= ", amount_main_currency";
2303 $sql .= ", fk_user_author";
2304 $sql .= ", num_chq";
2305 $sql .= ", fk_account";
2306 $sql .= ", fk_type";
2307 $sql .= ", emetteur,banque";
2308 $sql .= ", rappro";
2309 $sql .= ", numero_compte";
2310 $sql .= ", num_releve";
2311 $sql .= ") VALUES (";
2312 $sql .= "'".$this->db->idate($this->datec)."'";
2313 $sql .= ", '".$this->db->idate($this->dateo)."'";
2314 $sql .= ", '".$this->db->idate($this->datev)."'";
2315 $sql .= ", '".$this->db->escape($this->label)."'";
2316 $sql .= ", ".price2num($this->amount);
2317 $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2318 $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2319 $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2320 $sql .= ", '".$this->db->escape($this->fk_account)."'";
2321 $sql .= ", '".$this->db->escape($this->fk_type)."'";
2322 $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2323 $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2324 $sql .= ", ".(int) $this->rappro;
2325 $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2326 $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2327 $sql .= ")";
2328
2329
2330 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2331 $resql = $this->db->query($sql);
2332 if ($resql) {
2333 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2334 // Actions on extra fields (by external module or standard code)
2335 $result = $this->insertExtraFields();
2336 if ($result < 0) {
2337 $error++;
2338 }
2339 } else {
2340 $error++;
2341 $this->error = $this->db->lasterror();
2342 dol_print_error($this->db);
2343 }
2344
2345 if (!$error) {
2346 $this->db->commit();
2347 return $this->id;
2348 } else {
2349 $this->db->rollback();
2350 return -1 * $error;
2351 }
2352 }
2353
2361 public function delete($user = null, $notrigger = 0)
2362 {
2363 $nbko = 0;
2364
2365 if ($this->rappro) {
2366 // Protection to avoid any delete of consolidated lines
2367 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2368 return -1;
2369 }
2370
2371 $this->db->begin();
2372
2373 if (!$notrigger) {
2374 // Call trigger
2375 $result = $this->call_trigger('BANKACCOUNTLINE_DELETE', $user);
2376 if ($result < 0) {
2377 $this->db->rollback();
2378 return -1;
2379 }
2380 // End call triggers
2381 }
2382
2383 // Protection to avoid any delete of accounted lines. Protection on by default
2384 if (!getDolGlobalString('BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING')) {
2385 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2386 $resql = $this->db->query($sql);
2387 if ($resql) {
2388 $obj = $this->db->fetch_object($resql);
2389 if ($obj && $obj->nb) {
2390 $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2391 $this->db->rollback();
2392 return -1;
2393 }
2394 } else {
2395 $this->error = $this->db->lasterror();
2396 $this->db->rollback();
2397 return -1;
2398 }
2399 }
2400
2401 // Delete urls
2402 $result = $this->delete_urls($user);
2403 if ($result < 0) {
2404 $nbko++;
2405 }
2406
2407 $sql = "DELETE FROM ".MAIN_DB_PREFIX."category_bankline WHERE lineid=".(int) $this->rowid;
2408 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2409 $result = $this->db->query($sql);
2410 if (!$result) {
2411 $nbko++;
2412 }
2413
2414 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2415 $result = $this->db->query($sql);
2416 if (!$result) {
2417 $nbko++;
2418 }
2419
2420 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2421 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2422 $result = $this->db->query($sql);
2423 if (!$result) {
2424 $nbko++;
2425 }
2426
2427 if (!$nbko) {
2428 $this->db->commit();
2429 return 1;
2430 } else {
2431 $this->db->rollback();
2432 return -$nbko;
2433 }
2434 }
2435
2436
2437 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2444 public function delete_urls($user = null)
2445 {
2446 // phpcs:enable
2447 $nbko = 0;
2448
2449 if ($this->rappro) {
2450 // Protection to avoid any delete of consolidated lines
2451 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2452 return -1;
2453 }
2454
2455 $this->db->begin();
2456
2457 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2458 dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2459 $result = $this->db->query($sql);
2460 if (!$result) {
2461 $nbko++;
2462 }
2463
2464 if (!$nbko) {
2465 $this->db->commit();
2466 return 1;
2467 } else {
2468 $this->db->rollback();
2469 return -$nbko;
2470 }
2471 }
2472
2473
2481 public function update(User $user, $notrigger = 0)
2482 {
2483 $this->db->begin();
2484
2485 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2486 $sql .= " amount = ".price2num($this->amount).",";
2487 $sql .= " datev='".$this->db->idate($this->datev)."',";
2488 $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2489 $sql .= " WHERE rowid = ".((int) $this->rowid);
2490
2491 dol_syslog(get_class($this)."::update", LOG_DEBUG);
2492 $resql = $this->db->query($sql);
2493 if ($resql) {
2494 $this->db->commit();
2495 return 1;
2496 } else {
2497 $this->db->rollback();
2498 $this->error = $this->db->error();
2499 return -1;
2500 }
2501 }
2502
2503
2509 public function updateLabel()
2510 {
2511 $this->db->begin();
2512
2513 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2514 $sql .= " label = '".$this->db->escape($this->label)."'";
2515 $sql .= " WHERE rowid = ".((int) $this->rowid);
2516
2517 dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
2518 $resql = $this->db->query($sql);
2519 if ($resql) {
2520 $this->db->commit();
2521 return 1;
2522 } else {
2523 $this->db->rollback();
2524 $this->error = $this->db->error();
2525 return -1;
2526 }
2527 }
2528
2529
2530 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2539 public function update_conciliation(User $user, $cat, $conciliated = 1)
2540 {
2541 // phpcs:enable
2542 global $conf, $langs;
2543
2544 $this->db->begin();
2545
2546 // Check statement field
2547 if (getDolGlobalString('BANK_STATEMENT_REGEX_RULE')) {
2548 if (!preg_match('/' . getDolGlobalString('BANK_STATEMENT_REGEX_RULE').'/', $this->num_releve)) {
2549 $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", getDolGlobalString('BANK_STATEMENT_REGEX_RULE'));
2550 return -1;
2551 }
2552 }
2553
2554 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2555 $sql .= " rappro = ".((int) $conciliated);
2556 $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2557 if ($conciliated) {
2558 $sql .= ", fk_user_rappro = ".$user->id;
2559 }
2560 $sql .= " WHERE rowid = ".((int) $this->id);
2561
2562 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2563 $resql = $this->db->query($sql);
2564 if ($resql) {
2565 if (!empty($cat) && $cat > 0) {
2566 $sql = "INSERT INTO ".MAIN_DB_PREFIX."category_bankline (";
2567 $sql .= "lineid";
2568 $sql .= ", fk_categ";
2569 $sql .= ") VALUES (";
2570 $sql .= $this->id;
2571 $sql .= ", ".((int) $cat);
2572 $sql .= ")";
2573
2574 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2575 $this->db->query($sql);
2576
2577 // No error check. Can fail if category already affected
2578 // TODO Do no try the insert if link already exists
2579 }
2580
2581 $this->rappro = (int) $conciliated;
2582
2583 $this->db->commit();
2584 return 1;
2585 } else {
2586 $this->db->rollback();
2587 return -1;
2588 }
2589 }
2590
2591
2592 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2600 public function datev_change($rowid, $sign = 1)
2601 {
2602 // phpcs:enable
2603 $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2604 $resql = $this->db->query($sql);
2605 if ($resql) {
2606 $obj = $this->db->fetch_object($resql);
2607 $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2608
2609 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2610 $sql .= " datev = '".$this->db->idate($newdate)."'";
2611 $sql .= " WHERE rowid = ".((int) $rowid);
2612
2613 $result = $this->db->query($sql);
2614 if ($result) {
2615 if ($this->db->affected_rows($result)) {
2616 return 1;
2617 }
2618 } else {
2619 dol_print_error($this->db);
2620 return 0;
2621 }
2622 } else {
2623 dol_print_error($this->db);
2624 }
2625 return 0;
2626 }
2627
2628 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2635 public function datev_next($id)
2636 {
2637 // phpcs:enable
2638 return $this->datev_change($id, 1);
2639 }
2640
2641 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2648 public function datev_previous($id)
2649 {
2650 // phpcs:enable
2651 return $this->datev_change($id, -1);
2652 }
2653
2654
2655 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2663 public function dateo_change($rowid, $sign = 1)
2664 {
2665 // phpcs:enable
2666 $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2667 $resql = $this->db->query($sql);
2668 if ($resql) {
2669 $obj = $this->db->fetch_object($resql);
2670 $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2671
2672 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2673 $sql .= " dateo = '".$this->db->idate($newdate)."'";
2674 $sql .= " WHERE rowid = ".((int) $rowid);
2675
2676 $result = $this->db->query($sql);
2677 if ($result) {
2678 if ($this->db->affected_rows($result)) {
2679 return 1;
2680 }
2681 } else {
2682 dol_print_error($this->db);
2683 return 0;
2684 }
2685 } else {
2686 dol_print_error($this->db);
2687 }
2688 return 0;
2689 }
2690
2691 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2698 public function dateo_next($id)
2699 {
2700 // phpcs:enable
2701 return $this->dateo_change($id, 1);
2702 }
2703
2704 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2711 public function dateo_previous($id)
2712 {
2713 // phpcs:enable
2714 return $this->dateo_change($id, -1);
2715 }
2716
2717
2724 public function info($id)
2725 {
2726 $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2727 $sql .= ' b.fk_user_author, b.fk_user_rappro';
2728 $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2729 $sql .= ' WHERE b.rowid = '.((int) $id);
2730
2731 $result = $this->db->query($sql);
2732 if ($result) {
2733 if ($this->db->num_rows($result)) {
2734 $obj = $this->db->fetch_object($result);
2735
2736 $this->id = $obj->rowid;
2737
2738 $this->user_creation_id = $obj->fk_user_author;
2739 $this->user_rappro = $obj->fk_user_rappro;
2740 $this->date_creation = $this->db->jdate($obj->datec);
2741 $this->date_modification = $this->db->jdate($obj->datem);
2742 //$this->date_rappro = $obj->daterappro; // Not yet managed
2743 }
2744 $this->db->free($result);
2745 } else {
2746 dol_print_error($this->db);
2747 }
2748 }
2749
2750
2760 public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2761 {
2762 global $conf, $langs;
2763
2764 $result = '';
2765
2766 $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2767 $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2768 if ($this->amount) {
2769 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2770 }
2771
2772 $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">';
2773 $linkend = '</a>';
2774
2775 $result .= $linkstart;
2776 if ($withpicto) {
2777 $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);
2778 }
2779 if ($withpicto != 2) {
2780 $result .= ($this->ref ? $this->ref : $this->id);
2781 }
2782
2783 $result .= $linkend;
2784
2785 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2786 $result .= ' <span class="opacitymedium">(';
2787 }
2788 if ($option == 'showall') {
2789 $result .= $langs->trans("BankAccount").': ';
2790 $accountstatic = new Account($this->db);
2791 $accountstatic->id = $this->fk_account;
2792 $accountstatic->ref = $this->bank_account_ref;
2793 $accountstatic->label = $this->bank_account_label;
2794 $result .= $accountstatic->getNomUrl(0).', ';
2795 }
2796 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2797 $result .= $langs->trans("BankLineConciliated").': ';
2798 $result .= yn($this->rappro);
2799 }
2800 if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2801 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2802 $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2803 $resql = $this->db->query($sql);
2804 if ($resql) {
2805 $obj = $this->db->fetch_object($resql);
2806 if ($obj && $obj->nb) {
2807 $result .= ' - '.$langs->trans("Accounted").': '.yn(1);
2808 } else {
2809 $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2810 }
2811 }
2812 }
2813 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2814 $result .= ')</span>';
2815 }
2816
2817 return $result;
2818 }
2819
2820
2827 public function getLibStatut($mode = 0)
2828 {
2829 return $this->LibStatut($this->status, $mode);
2830 }
2831
2832 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2840 public function LibStatut($status, $mode = 0)
2841 {
2842 // phpcs:enable
2843 return '';
2844 }
2845
2851 public function getVentilExportCompta()
2852 {
2853 $alreadydispatched = 0;
2854
2855 $type = 'bank';
2856
2857 $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);
2858 $resql = $this->db->query($sql);
2859 if ($resql) {
2860 $obj = $this->db->fetch_object($resql);
2861 if ($obj) {
2862 $alreadydispatched = $obj->nb;
2863 }
2864 } else {
2865 $this->error = $this->db->lasterror();
2866 return -1;
2867 }
2868
2869 if ($alreadydispatched) {
2870 return 1;
2871 }
2872 return 0;
2873 }
2874}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
checkIbanForAccount($account=null, $ibantocheck=null)
Check IBAN number information for a bank account.
Definition bank.lib.php:342
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition bank.lib.php:367
checkSwiftForAccount($account=null, $swift=null)
Check SWIFT information for a bank account.
Definition bank.lib.php:321
$object ref
Definition info.php:89
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 clickable 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.
getCountryCode()
Return account country code.
getLibStatut($mode=0)
Return label of object status.
update_bban($user=null)
Update BBAN (RIB) account fields.
create($user, $notrigger=0)
Create bank account into database.
getBannerAddress($htmlkey, $object)
Return full address for banner.
error()
Return error.
info($id)
Load miscellaneous information for tab "Info".
const TYPE_CASH
Cash account.
delete($user=null, $notrigger=0)
Delete bank account from database.
update($user, $notrigger=0)
Update bank account card.
__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.
can_be_deleted()
Indicates if an account can be deleted or not (without movements)
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.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
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 a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
div refaddress div address
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:149