dolibarr 23.0.3
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-2025 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2024-2025 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' => 'UserAuthor', '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 if (empty($this->rappro)) {
478 return -1;
479 }
480 if ($this->type == Account::TYPE_CASH && !getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
481 return -2;
482 }
483 if ($this->status) {
484 return -3;
485 }
486 return 1;
487 }
488
489
490 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
501 public function add_url_line($line_id, $url_id, $url, $label, $type)
502 {
503 // phpcs:enable
504 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
505 $sql .= "fk_bank";
506 $sql .= ", url_id";
507 $sql .= ", url"; // deprecated
508 $sql .= ", label";
509 $sql .= ", type";
510 $sql .= ") VALUES (";
511 $sql .= ((int) $line_id);
512 $sql .= ", ".((int) $url_id);
513 $sql .= ", '".$this->db->escape($url)."'"; // deprecated
514 $sql .= ", '".$this->db->escape($label)."'";
515 $sql .= ", '".$this->db->escape($type)."'";
516 $sql .= ")";
517
518 dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
519 if ($this->db->query($sql)) {
520 $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
521 return $rowid;
522 } else {
523 $this->error = $this->db->lasterror();
524 return -1;
525 }
526 }
527
528 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
538 public function get_url($fk_bank = 0, $url_id = 0, $type = '')
539 {
540 // phpcs:enable
541 $lines = array();
542
543 // Check parameters
544 if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
545 $this->error = "ErrorBadParameter";
546 return -1;
547 }
548
549 $sql = "SELECT fk_bank, url_id, url, label, type";
550 $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
551 if ($fk_bank > 0) {
552 $sql .= " WHERE fk_bank = ".((int) $fk_bank);
553 } else {
554 $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
555 }
556 $sql .= " ORDER BY type, label";
557
558 dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
559 $result = $this->db->query($sql);
560 if ($result) {
561 $i = 0;
562 $num = $this->db->num_rows($result);
563 while ($i < $num) {
564 $obj = $this->db->fetch_object($result);
565 // Old links (for compatibility)
566 $lines[$i][0] = $obj->url;
567 $lines[$i][1] = $obj->url_id;
568 $lines[$i][2] = $obj->label;
569 $lines[$i][3] = $obj->type;
570 // New links
571 $lines[$i]['url'] = $obj->url;
572 $lines[$i]['url_id'] = $obj->url_id;
573 $lines[$i]['label'] = $obj->label;
574 $lines[$i]['type'] = $obj->type;
575 $lines[$i]['fk_bank'] = $obj->fk_bank;
576 $i++;
577 }
578 } else {
579 dol_print_error($this->db);
580 }
581
582 return $lines;
583 }
584
604 public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null, $note_private = '')
605 {
606 global $langs;
607
608 // Deprecation warning
609 if (is_numeric($oper)) {
610 dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
611 }
612
613 if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
614 $this->id = $this->rowid;
615 }
616
617 // Clean parameters
618 $emetteur = trim($emetteur);
619 $banque = trim($banque);
620 $label = trim($label);
621
622 $now = dol_now();
623
624 if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
625 $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
626 $sql .= " WHERE id = ".((int) $oper);
627 $sql .= " AND entity IN (".getEntity('c_paiement').")";
628 $resql = $this->db->query($sql);
629 if ($resql) {
630 $obj = $this->db->fetch_object($resql);
631 $oper = $obj->code;
632 } else {
633 dol_print_error($this->db, 'Failed to get payment type code');
634 return -1;
635 }
636 }
637
638 // Check parameters
639 if (!$oper) {
640 $this->error = $langs->trans("OperNotDefined");
641 return -1;
642 }
643 if (!$this->id) {
644 $this->error = $langs->trans("ThisIdNotDefined");
645 return -2;
646 }
647 if ($this->type == Account::TYPE_CASH && $oper != 'LIQ') {
648 $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
649 return -3;
650 }
651
652 $this->db->begin();
653
654 if (is_null($datev) || empty($datev)) {
655 $datev = $date;
656 }
657
658 $accline = new AccountLine($this->db);
659 $accline->datec = $now;
660 $accline->dateo = $date;
661 $accline->datev = $datev;
662 $accline->label = $label;
663 $accline->amount = $amount;
664 $accline->amount_main_currency = $amount_main_currency;
665 $accline->fk_user_author = $user->id;
666 $accline->fk_account = $this->id;
667 $accline->fk_type = $oper;
668 $accline->numero_compte = $accountancycode;
669 $accline->num_releve = $num_releve;
670 $accline->note_private = $note_private;
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).", ".((int) $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 $langs->load('errors');
736 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
737 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
738 return -1;
739 }
740 if (empty($this->ref)) {
741 $langs->load('errors');
742 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
743 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
744 return -1;
745 }
746 if (empty($this->date_solde)) {
747 $langs->load('errors');
748 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
749 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
750 return -1;
751 }
752
753 // Load libraries to check BAN
754 $balance = $this->balance;
755 if (empty($balance) && !empty($this->solde)) {
756 dol_syslog(get_class($this)."::create solde is deprecated use balance", LOG_NOTICE);
757 $balance = $this->solde;
758 }
759 if (empty($balance)) {
760 $balance = 0;
761 }
762 if (empty($this->status && !empty($this->clos))) {
763 dol_syslog(get_class($this)."::create clos is deprecated use status", LOG_NOTICE);
764 $this->status = $this->clos;
765 }
766
767 if (empty($this->country_id) && !empty($this->country_code)) {
768 $country_id = getCountry($this->country_code, '3');
769 $this->country_id = is_int($country_id) ? $country_id : 0;
770 }
771
772 // Load the library to validate/check a BAN account
773 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
774
775 $now = dol_now();
776
777 $this->db->begin();
778
779 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
780 $sql .= "datec";
781 $sql .= ", ref";
782 $sql .= ", label";
783 $sql .= ", entity";
784 $sql .= ", account_number";
785 $sql .= ", fk_accountancy_journal";
786 $sql .= ", bank";
787 $sql .= ", code_banque";
788 $sql .= ", code_guichet";
789 $sql .= ", number";
790 $sql .= ", cle_rib";
791 $sql .= ", bic";
792 $sql .= ", iban_prefix";
793 $sql .= ", domiciliation";
794 $sql .= ", pti_in_ctti";
795 $sql .= ", proprio";
796 $sql .= ", owner_address";
797 $sql .= ", owner_zip";
798 $sql .= ", owner_town";
799 $sql .= ", owner_country_id";
800 $sql .= ", currency_code";
801 $sql .= ", rappro";
802 $sql .= ", min_allowed";
803 $sql .= ", min_desired";
804 $sql .= ", comment";
805 $sql .= ", state_id";
806 $sql .= ", fk_pays";
807 $sql .= ", ics";
808 $sql .= ", ics_transfer";
809 $sql .= ") VALUES (";
810 $sql .= "'".$this->db->idate($now)."'";
811 $sql .= ", '".$this->db->escape($this->ref)."'";
812 $sql .= ", '".$this->db->escape($this->label)."'";
813 $sql .= ", ".((int) $conf->entity);
814 $sql .= ", '".$this->db->escape($this->account_number)."'";
815 $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
816 $sql .= ", '".$this->db->escape($this->bank)."'";
817 $sql .= ", '".$this->db->escape($this->code_banque)."'";
818 $sql .= ", '".$this->db->escape($this->code_guichet)."'";
819 $sql .= ", '".$this->db->escape($this->number)."'";
820 $sql .= ", '".$this->db->escape($this->cle_rib)."'";
821 $sql .= ", '".$this->db->escape($this->bic)."'";
822 $sql .= ", '".$this->db->escape($this->iban)."'";
823 $sql .= ", '".$this->db->escape($this->address)."'";
824 $sql .= ", ".((int) $this->pti_in_ctti);
825 $sql .= ", '".$this->db->escape($this->owner_name)."'";
826 $sql .= ", '".$this->db->escape($this->owner_address)."'";
827 $sql .= ", '".$this->db->escape($this->owner_zip)."'";
828 $sql .= ", '".$this->db->escape($this->owner_town)."'";
829 $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
830 $sql .= ", '".$this->db->escape($this->currency_code)."'";
831 $sql .= ", ".((int) $this->rappro);
832 $sql .= ", ".price2num($this->min_allowed, 'MT');
833 $sql .= ", ".price2num($this->min_desired, 'MT');
834 $sql .= ", '".$this->db->escape($this->comment)."'";
835 $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
836 $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
837 $sql .= ", '".$this->db->escape($this->ics)."'";
838 $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
839 $sql .= ")";
840
841 dol_syslog(get_class($this)."::create", LOG_DEBUG);
842 $resql = $this->db->query($sql);
843 if ($resql) {
844 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
845
846 $result = $this->update($user, 1);
847 if ($result > 0) {
848 $accline = new AccountLine($this->db);
849 $accline->datec = $now;
850 $accline->label = '('.$langs->trans("InitialBankBalance").')';
851 $accline->amount = (float) price2num($balance);
852 $accline->fk_user_author = $user->id;
853 $accline->fk_account = $this->id;
854 $accline->datev = $this->date_solde;
855 $accline->dateo = $this->date_solde;
856 $accline->fk_type = 'SOLD';
857
858 if ($accline->insert() < 0) {
859 $error++;
860 $this->setErrorsFromObject($accline);
861 }
862
863 if (!$error) {
864 $result = $this->insertExtraFields();
865 if ($result < 0) {
866 $error++;
867 }
868 }
869
870 if (!$error && !$notrigger) {
871 // Call trigger
872 $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
873 if ($result < 0) {
874 $error++;
875 }
876 // End call triggers
877 }
878 } else {
879 $error++;
880 }
881 } else {
882 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
883 $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
884 $error++;
885 } else {
886 $this->error = $this->db->error()." sql=".$sql;
887 $error++;
888 }
889 }
890
891 if (!$error) {
892 $this->db->commit();
893 return $this->id;
894 } else {
895 $this->db->rollback();
896 return -1 * $error;
897 }
898 }
899
907 public function update($user, $notrigger = 0)
908 {
909 global $langs, $conf;
910
911 if (empty($this->country_id) && !empty($this->country_code)) {
912 $country_id = getCountry($this->country_code, '3');
913 $this->country_id = is_int($country_id) ? $country_id : 0;
914 }
915
916 $error = 0;
917
918 $this->db->begin();
919
920 // Check parameters
921 if (empty($this->country_id)) {
922 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
923 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
924 return -1;
925 }
926 if (empty($this->ref)) {
927 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
928 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
929 return -1;
930 }
931 if (!$this->label) {
932 $this->label = "???";
933 }
934
935 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
936 $sql .= " ref = '".$this->db->escape($this->ref)."'";
937 $sql .= ",label = '".$this->db->escape($this->label)."'";
938 $sql .= ",courant = ".((int) $this->type);
939 $sql .= ",clos = ".((int) $this->status);
940 $sql .= ",rappro = ".((int) $this->rappro);
941 $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
942 $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
943 $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
944 $sql .= ",bank = '".$this->db->escape($this->bank)."'";
945 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
946 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
947 $sql .= ",number='".$this->db->escape($this->number)."'";
948 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
949 $sql .= ",bic='".$this->db->escape($this->bic)."'";
950 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
951 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
952 $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
953 $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'";
954 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
955 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
956 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
957 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
958
959 $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
960
961 $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
962 $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
963 $sql .= ",comment = '".$this->db->escape($this->comment)."'";
964
965 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
966 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
967 $sql .= ",ics = '".$this->db->escape($this->ics)."'";
968 $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
969
970 $sql .= " WHERE rowid = ".((int) $this->id);
971
972 dol_syslog(get_class($this)."::update", LOG_DEBUG);
973 $result = $this->db->query($sql);
974 if ($result) {
975 // Actions on extra fields (by external module or standard code)
976 if (!$error) {
977 $result = $this->insertExtraFields();
978 if ($result < 0) {
979 $error++;
980 }
981 }
982
983 if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
984 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
985 $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type = 'bank_account' and entity = ".((int) $conf->entity);
986 $resql = $this->db->query($sql);
987 if (!$resql) {
988 $error++;
989 $this->error = $this->db->lasterror();
990 }
991
992 // We rename directory in order not to lose the attachments
993 $oldref = dol_sanitizeFileName($this->oldref);
994 $newref = dol_sanitizeFileName($this->ref);
995 $dirsource = $conf->bank->dir_output.'/'.$oldref;
996 $dirdest = $conf->bank->dir_output.'/'.$newref;
997 if (file_exists($dirsource)) {
998 dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
999 if (@rename($dirsource, $dirdest)) {
1000 dol_syslog("Rename ok", LOG_DEBUG);
1001 }
1002 }
1003 }
1004
1005 if (!$error && !$notrigger) {
1006 // Call trigger
1007 $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
1008 if ($result < 0) {
1009 $error++;
1010 }
1011 // End call triggers
1012 }
1013 } else {
1014 $error++;
1015 $this->error = $this->db->lasterror();
1016 dol_print_error($this->db);
1017 }
1018
1019 if (!$error) {
1020 $this->db->commit();
1021 return $this->id;
1022 } else {
1023 $this->db->rollback();
1024 return -1 * $error;
1025 }
1026 }
1027
1028
1029 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1036 public function update_bban($user = null)
1037 {
1038 // phpcs:enable
1039 global $conf, $langs;
1040
1041 // Load library to get BAN control function
1042 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1043
1044 dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
1045
1046 // Check parameters
1047 if (!$this->ref) {
1048 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
1049 return -2;
1050 }
1051
1052 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
1053 $sql .= " bank = '".$this->db->escape($this->bank)."'";
1054 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1055 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1056 $sql .= ",number='".$this->db->escape($this->number)."'";
1057 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1058 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1059 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1060 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
1061 $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'";
1062 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1063 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1064 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1065 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1066 $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
1067 $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
1068 $sql .= " WHERE rowid = ".((int) $this->id);
1069 $sql .= " AND entity = ".((int) $conf->entity);
1070
1071 dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
1072
1073 $result = $this->db->query($sql);
1074 if ($result) {
1075 return 1;
1076 } else {
1077 $this->error = $this->db->lasterror();
1078 dol_print_error($this->db);
1079 return -1;
1080 }
1081 }
1082
1083
1091 public function fetch($id, $ref = '')
1092 {
1093 if (empty($id) && empty($ref)) {
1094 $this->error = "ErrorBadParameters";
1095 return -1;
1096 }
1097
1098 $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant as type, ba.clos as status, ba.rappro, ba.url,";
1099 $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1100 $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,";
1101 $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1102 $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1103 $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1104 $sql .= ' c.code as country_code, c.label as country,';
1105 $sql .= ' d.code_departement as state_code, d.nom as state,';
1106 $sql .= ' aj.code as accountancy_journal';
1107 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1108 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1109 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1110 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1111 $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1112 if ($id) {
1113 $sql .= " AND ba.rowid = ".((int) $id);
1114 }
1115 if ($ref) {
1116 $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1117 }
1118
1119 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1120 $result = $this->db->query($sql);
1121 if ($result) {
1122 if ($this->db->num_rows($result)) {
1123 $obj = $this->db->fetch_object($result);
1124
1125 $this->id = $obj->rowid;
1126 $this->rowid = $obj->rowid;
1127 $this->ref = $obj->ref;
1128 $this->label = $obj->label;
1129 $this->type = $obj->type;
1130 $this->courant = $obj->type;
1131 $this->bank = $obj->bank;
1132 $this->clos = $obj->status;
1133 $this->status = $obj->status;
1134 $this->rappro = $obj->rappro;
1135 $this->url = $obj->url;
1136
1137 $this->code_banque = $obj->code_banque;
1138 $this->code_guichet = $obj->code_guichet;
1139 $this->number = $obj->number;
1140 $this->cle_rib = $obj->cle_rib;
1141 $this->bic = $obj->bic;
1142 $this->iban = $obj->iban;
1143 $this->address = $obj->address;
1144
1145 $this->owner_name = $obj->owner_name;
1146 $this->proprio = $this->owner_name;
1147 $this->owner_address = $obj->owner_address;
1148 $this->owner_zip = $obj->owner_zip;
1149 $this->owner_town = $obj->owner_town;
1150 $this->owner_country_id = $obj->owner_country_id;
1151
1152 $this->pti_in_ctti = $obj->pti_in_ctti;
1153
1154 $this->state_id = $obj->state_id;
1155 $this->state_code = $obj->state_code;
1156 $this->state = $obj->state;
1157
1158 $this->country_id = $obj->country_id;
1159 $this->country_code = $obj->country_code;
1160 $this->country = $obj->country;
1161
1162 $this->account_number = $obj->account_number;
1163 $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1164 $this->accountancy_journal = $obj->accountancy_journal;
1165
1166 $this->currency_code = $obj->currency_code;
1167 $this->account_currency_code = $obj->currency_code;
1168 $this->min_allowed = $obj->min_allowed;
1169 $this->min_desired = $obj->min_desired;
1170 $this->comment = $obj->comment;
1171
1172 $this->date_creation = $this->db->jdate($obj->date_creation);
1173 $this->date_modification = $this->db->jdate($obj->date_modification);
1174
1175 $this->ics = $obj->ics;
1176 $this->ics_transfer = $obj->ics_transfer;
1177
1178 // Retrieve all extrafield
1179 // fetch optionals attributes and labels
1180 $this->fetch_optionals();
1181
1182 return 1;
1183 } else {
1184 return 0;
1185 }
1186 } else {
1187 $this->error = $this->db->lasterror();
1188 $this->errors[] = $this->error;
1189 return -1;
1190 }
1191 }
1192
1203 public function setCategories($categories)
1204 {
1205 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1206 return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1207 }
1208
1216 public function delete($user, $notrigger = 0)
1217 {
1218 $error = 0;
1219
1220 $this->db->begin();
1221
1222 // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1223
1224 // Delete link between tag and bank account
1225 if (!$error) {
1226 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1227 $sql .= " WHERE fk_account = ".((int) $this->id);
1228
1229 $resql = $this->db->query($sql);
1230 if (!$resql) {
1231 $error++;
1232 $this->error = "Error ".$this->db->lasterror();
1233 }
1234 }
1235
1236 if (!$error) {
1237 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1238 $sql .= " WHERE rowid = ".((int) $this->id);
1239
1240 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1241 $result = $this->db->query($sql);
1242 if ($result) {
1243 // Remove extrafields
1244 if (!$error) {
1245 $result = $this->deleteExtraFields();
1246 if ($result < 0) {
1247 $error++;
1248 dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1249 }
1250 }
1251 } else {
1252 $error++;
1253 $this->error = "Error ".$this->db->lasterror();
1254 }
1255 }
1256
1257 if (!$error) {
1258 $this->db->commit();
1259 return 1;
1260 } else {
1261 $this->db->rollback();
1262 return -1;
1263 }
1264 }
1265
1266
1273 public function getLibStatut($mode = 0)
1274 {
1275 return $this->LibStatut($this->status, $mode);
1276 }
1277
1278 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1286 public function LibStatut($status, $mode = 0)
1287 {
1288 // phpcs:enable
1289 global $langs;
1290 $langs->load('banks');
1291
1292 if ($status == self::STATUS_OPEN) {
1293 $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1294 $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1295 $statusType = 'status4';
1296 } else {
1297 $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1298 $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1299 $statusType = 'status5';
1300 }
1301
1302 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1303 }
1304
1305
1306 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1312 public function can_be_deleted()
1313 {
1314 // phpcs:enable
1315 $can_be_deleted = false;
1316
1317 $sql = "SELECT COUNT(rowid) as nb";
1318 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1319 $sql .= " WHERE fk_account = ".((int) $this->id);
1320
1321 $resql = $this->db->query($sql);
1322 if ($resql) {
1323 $obj = $this->db->fetch_object($resql);
1324 if ($obj->nb <= 1) {
1325 $can_be_deleted = true; // Juste le solde
1326 }
1327 } else {
1328 dol_print_error($this->db);
1329 }
1330 return $can_be_deleted;
1331 }
1332
1333
1339 public function error()
1340 {
1341 return $this->error;
1342 }
1343
1352 public function solde($option = 0, $date_end = '', $field = 'dateo')
1353 {
1354 $solde = 0;
1355
1356 $sql = "SELECT sum(amount) as amount";
1357 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1358 $sql .= " WHERE fk_account = ".((int) $this->id);
1359 if ($option == 1) {
1360 $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1361 }
1362
1363 $resql = $this->db->query($sql);
1364 if ($resql) {
1365 if ($this->db->num_rows($resql)) {
1366 $obj = $this->db->fetch_object($resql);
1367 $solde = $obj->amount;
1368 }
1369 $this->db->free($resql);
1370 } else {
1371 $this->errors[] = $this->db->lasterror;
1372 return -1;
1373 }
1374
1375 return (float) price2num($solde, 'MU');
1376 }
1377
1378 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1386 public function load_board(User $user, $filteraccountid = 0)
1387 {
1388 // phpcs:enable
1389 global $conf, $langs;
1390
1391 if ($user->socid) {
1392 return -1; // protection pour eviter appel par utilisateur externe
1393 }
1394
1395 $sql = "SELECT b.rowid, b.datev as datefin";
1396 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1397 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1398 $sql .= " WHERE b.rappro=0";
1399 $sql .= " AND b.fk_account = ba.rowid";
1400 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1401 $sql .= " AND (ba.rappro = 1 AND ba.courant != " . Account::TYPE_CASH . ")"; // Compte rapprochable
1402 $sql .= " AND clos = 0";
1403 if ($filteraccountid) {
1404 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1405 }
1406
1407 $resql = $this->db->query($sql);
1408 if ($resql) {
1409 $langs->load("banks");
1410 $now = dol_now();
1411
1412 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1413
1414 $response = new WorkboardResponse();
1415 $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1416 $response->label = $langs->trans("TransactionsToConciliate");
1417 $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1418 $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1419 $response->img = img_object('', "payment");
1420
1421 while ($obj = $this->db->fetch_object($resql)) {
1422 $response->nbtodo++;
1423 if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1424 $response->nbtodolate++;
1425 }
1426 }
1427
1428 return $response;
1429 } else {
1430 dol_print_error($this->db);
1431 $this->error = $this->db->error();
1432 return -1;
1433 }
1434 }
1435
1442 public function loadStateBoard($filteraccountid = 0)
1443 {
1444 global $user;
1445
1446 if ($user->socid) {
1447 return -1; // protection pour eviter appel par utilisateur externe
1448 }
1449
1450 $sql = "SELECT count(b.rowid) as nb";
1451 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1452 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1453 $sql .= " WHERE b.fk_account = ba.rowid";
1454 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1455 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1456 $sql .= " AND clos = 0";
1457 if ($filteraccountid) {
1458 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1459 }
1460
1461 $resql = $this->db->query($sql);
1462 if ($resql) {
1463 while ($obj = $this->db->fetch_object($resql)) {
1464 $this->nb["banklines"] = $obj->nb;
1465 }
1466 $this->db->free($resql);
1467 return 1;
1468 } else {
1469 dol_print_error($this->db);
1470 $this->error = $this->db->error();
1471 return -1;
1472 }
1473 }
1474
1475
1481 public function countAccountToReconcile()
1482 {
1483 global $user;
1484
1485 //Protection against external users
1486 if ($user->socid) {
1487 return 0;
1488 }
1489
1490 $nb = 0;
1491
1492 $sql = "SELECT COUNT(ba.rowid) as nb";
1493 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1494 $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1495 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1496 if (!getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
1497 $sql .= " AND ba.courant != " . Account::TYPE_CASH;
1498 }
1499
1500 $resql = $this->db->query($sql);
1501 if ($resql) {
1502 $obj = $this->db->fetch_object($resql);
1503 $nb = (int) $obj->nb;
1504 } else {
1505 dol_print_error($this->db);
1506 }
1507
1508 return $nb;
1509 }
1510
1519 public function getTooltipContentArray($params)
1520 {
1521 global $langs;
1522 $langs->loadLangs(['banks', 'compta']);
1523 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1524
1525 $datas = array();
1526
1527 $nofetch = !empty($params['nofetch']);
1528 $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1529 if (isset($this->status)) {
1530 $pictos .= ' '.$this->getLibStatut(5);
1531 }
1532 $datas['picto'] = $pictos;
1533 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1534 $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1535 $datas['accountnumber'] = '<br><br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1536 $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1537 $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1538 $datas['accountcurrency'] = '<br><br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1539
1540 if (isModEnabled('accounting')) {
1541 include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1542 $langs->load("accountancy");
1543 $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1544 $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1545 }
1546 // show categories for this record only in ajax to not overload lists
1547 if (isModEnabled('category') && !$nofetch) {
1548 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1549 $form = new Form($this->db);
1550 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1551 }
1552
1553 return $datas;
1554 }
1555
1567 public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1568 {
1569 global $conf, $langs;
1570
1571 if (!empty($conf->dol_no_mouse_hover)) {
1572 $notooltip = 1; // Force disable tooltips
1573 }
1574
1575 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1576
1577 $result = '';
1578 $classfortooltip = 'classfortooltip';
1579 $dataparams = '';
1580 $params = [
1581 'id' => $this->id,
1582 'objecttype' => $this->element,
1583 'option' => $option,
1584 'nofetch' => 1,
1585 ];
1586 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1587 $classfortooltip = 'classforajaxtooltip';
1588 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1589 $label = '';
1590 } else {
1591 $label = implode($this->getTooltipContentArray($params));
1592 }
1593
1594 $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1595 if ($mode == 'transactions') {
1596 $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1597 } elseif ($mode == 'receipts') {
1598 $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1599 }
1600
1601 if ($option != 'nolink') {
1602 // Add param to save lastsearch_values or not
1603 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1604 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1605 $add_save_lastsearch_values = 1;
1606 }
1607 if ($add_save_lastsearch_values) {
1608 $url .= '&save_lastsearch_values=1';
1609 }
1610 }
1611
1612 $linkclose = '';
1613 if (empty($notooltip)) {
1614 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1615 $label = $langs->trans("BankAccount");
1616 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1617 }
1618 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1619 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1620 } else {
1621 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1622 }
1623
1624 if ($option == 'nolink' || empty($url)) {
1625 $linkstart = '<span';
1626 } else {
1627 $linkstart = '<a href="'.$url.'"';
1628 }
1629 $linkstart .= $linkclose.'>';
1630 if ($option == 'nolink' || empty($url)) {
1631 $linkend = '</span>';
1632 } else {
1633 $linkend = '</a>';
1634 }
1635
1636 $result .= $linkstart;
1637
1638 if ($withpicto) {
1639 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1640 }
1641 if ($withpicto != 2) {
1642 $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1643 }
1644 $result .= $linkend;
1645
1646 return $result;
1647 }
1648
1649
1650 // Method after here are common to Account and CompanyBankAccount
1651
1652
1658 public function verif()
1659 {
1660 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1661
1662 $error = 0;
1663
1664 // Call functions to check BAN
1665 if (!checkIbanForAccount($this)) {
1666 $error++;
1667 $this->error = 'IBANNotValid';
1668 }
1669 // Call function to check Swift/BIC.
1670 // A non valid BIC/Swift is a problem if: it is not empty or always a problem if WITHDRAWAL_WITHOUT_BIC is not set).
1671 if (!checkSwiftForAccount($this) && (!empty($this->bic) || !getDolGlobalInt('WITHDRAWAL_WITHOUT_BIC'))) {
1672 $error++;
1673 $this->error = 'SwiftNotValid';
1674 }
1675
1676 if (! $error) {
1677 return 1;
1678 } else {
1679 return 0;
1680 }
1681 }
1682
1688 public function getCountryCode()
1689 {
1690 global $mysoc;
1691
1692 // We return country code of bank account
1693 if (!empty($this->country_code)) {
1694 return $this->country_code;
1695 }
1696
1697 // For backward compatibility, we try to guess country from other information
1698 if (!empty($this->iban)) {
1699 // If IBAN defined, we can know country of account from it
1700 $reg = array();
1701 if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1702 return $reg[1];
1703 }
1704 }
1705
1706 // If this class is linked to a third party
1707 if (!empty($this->socid)) {
1708 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1709 $company = new Societe($this->db);
1710 $result = $company->fetch($this->socid);
1711 if (!empty($company->country_code)) {
1712 return $company->country_code;
1713 }
1714 }
1715
1716 // We return country code of managed company
1717 if (!empty($mysoc->country_code)) {
1718 return $mysoc->country_code;
1719 }
1720
1721 return '';
1722 }
1723
1731 public function getBannerAddress($htmlkey, $object)
1732 {
1733 global $conf, $langs;
1734
1735 $out = '';
1736
1737 $outdone = 0;
1738 $coords = $this->getFullAddress(1, ', ', getDolGlobalInt('MAIN_SHOW_REGION_IN_STATE_SELECT'));
1739 if ($coords) {
1740 if (!empty($conf->use_javascript_ajax)) {
1741 // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
1742 $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
1743 $out .= img_picto($langs->trans("Address"), 'map-marker-alt');
1744 $out .= '</a> ';
1745 }
1746 $address = dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
1747 if ($address) {
1748 $out .= $address;
1749 $outdone++;
1750 }
1751 $outdone++;
1752 }
1753
1754 return $out;
1755 }
1756
1757
1766 public function useDetailedBBAN()
1767 {
1768 $country_code = $this->getCountryCode();
1769
1770 if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1771 return 1; // France, Spain, Gabon, ... - Not valid for CH
1772 }
1773 if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1774 return 2; // Australia, England...
1775 }
1776 return 0;
1777 }
1778
1784 public function needIBAN()
1785 {
1786 global $conf;
1787
1788 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1789 return 0;
1790 }
1791
1792 $country_code = $this->getCountryCode();
1793
1794 $country_code_in_EEC = array(
1795 'AT', // Austria
1796 'BE', // Belgium
1797 'BG', // Bulgaria
1798 'CY', // Cyprus
1799 'CZ', // Czech republic
1800 'DE', // Germany
1801 'DK', // Danemark
1802 'EE', // Estonia
1803 'ES', // Spain
1804 'FI', // Finland
1805 'FR', // France
1806 'GB', // United Kingdom
1807 'GR', // Greece
1808 'HR', // Croatia
1809 'NL', // Holland
1810 'HU', // Hungary
1811 'IE', // Ireland
1812 'IM', // Isle of Man - Included in UK
1813 'IT', // Italy
1814 'LT', // Lithuania
1815 'LU', // Luxembourg
1816 'LV', // Latvia
1817 'MC', // Monaco - Included in France
1818 'MT', // Malta
1819 //'NO', // Norway
1820 'PL', // Poland
1821 'PT', // Portugal
1822 'RO', // Romania
1823 'SE', // Sweden
1824 'SK', // Slovakia
1825 'SI', // Slovenia
1826 'UK', // United Kingdom
1827 //'CH', // Switzerland - No. Swizerland in not in EEC
1828 );
1829
1830 if (in_array($country_code, $country_code_in_EEC)) {
1831 return 1; // France, Spain, ...
1832 }
1833 return 0;
1834 }
1835
1841 public function needBIC()
1842 {
1843 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1844 return 0;
1845 }
1846
1847 $country_code = $this->getCountryCode();
1848
1849 $country_code_in_EEC = array(
1850 'AD', // Andorra
1851 'BH', // Bahrein
1852 'DK', // Denmark
1853 'FR', // France
1854 'GH', // Ghana
1855 'HU', // Hungary
1856 'JP', // Japan
1857 'LV', // Latvia
1858 'SE', // Sweden
1859 );
1860
1861 if (in_array($country_code, $country_code_in_EEC)) {
1862 return 1; // Andorra, Bahrein, ...
1863 }
1864 return 0;
1865 }
1866
1873 public function info($id)
1874 {
1875 }
1876
1891 public function getFieldsToShow($includeibanbic = 0)
1892 {
1893 //Get the required properties depending on the country
1894 $detailedBBAN = $this->useDetailedBBAN();
1895
1896 if ($detailedBBAN == 0) {
1897 $fieldarray = array(
1898 'BankAccountNumber'
1899 );
1900 } elseif ($detailedBBAN == 2) {
1901 $fieldarray = array(
1902 'BankCode',
1903 'BankAccountNumber'
1904 );
1905 } else {
1906 $fieldarray = self::getAccountNumberOrder();
1907 }
1908
1909 //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1910 if ($includeibanbic) {
1911 $fieldarray[] = 'IBAN';
1912 $fieldarray[] = 'BIC';
1913 }
1914 //}
1915
1916 //Get the order the properties are shown
1917 return $fieldarray;
1918 }
1919
1930 public static function getAccountNumberOrder()
1931 {
1932 global $conf;
1933
1934 $fieldlists = array(
1935 'BankCode',
1936 'DeskCode',
1937 'BankAccountNumber',
1938 'BankAccountNumberKey'
1939 );
1940
1941 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION')) {
1942 if (is_numeric(getDolGlobalString('BANK_SHOW_ORDER_OPTION'))) {
1943 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION') == '1') {
1944 $fieldlists = array(
1945 'BankCode',
1946 'DeskCode',
1947 'BankAccountNumberKey',
1948 'BankAccountNumber'
1949 );
1950 }
1951 } else {
1952 //Replace the old AccountNumber key with the new BankAccountNumber key
1953 $fieldlists = explode(
1954 ' ',
1955 preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1956 );
1957 }
1958 }
1959
1960 return $fieldlists;
1961 }
1962
1963
1971 public function initAsSpecimen()
1972 {
1973 // Example of IBAN FR7630001007941234567890185
1974 $this->specimen = 1;
1975 $this->ref = 'MBA';
1976 $this->label = 'My Big Company Bank account';
1977 $this->clos = Account::STATUS_OPEN;
1978 $this->type = Account::TYPE_CURRENT;
1979 $this->status = Account::STATUS_OPEN;
1980 $this->code_banque = '30001';
1981 $this->code_guichet = '00794';
1982 $this->number = '12345678901';
1983 $this->cle_rib = '85';
1984 $this->bic = 'AA12';
1985 $this->iban = 'FR7630001007941234567890185';
1986
1987 $this->bank = 'MyBank';
1988 $this->address = 'Rue de Paris';
1989 $this->owner_name = 'Owner';
1990 $this->owner_address = 'Owner address';
1991 $this->owner_zip = 'Owner zip';
1992 $this->owner_town = 'Owner town';
1993 $this->owner_country_id = 1;
1994 $this->country_id = 1;
1995
1996 return 1;
1997 }
1998
2007 public static function replaceThirdparty($dbs, $origin_id, $dest_id)
2008 {
2009 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type = 'company'";
2010
2011 if ($dbs->query($sql)) {
2012 return true;
2013 } else {
2014 //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.
2015 //$this->errors = $dbs->lasterror();
2016 return false;
2017 }
2018 }
2019
2027 public function getKanbanView($option = '', $arraydata = null)
2028 {
2029 global $langs;
2030
2031 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2032
2033 $return = '<div class="box-flex-item box-flex-grow-zero">';
2034 $return .= '<div class="info-box info-box-sm">';
2035 $return .= '<span class="info-box-icon bg-infobox-action">';
2036 $return .= img_picto('', $this->picto);
2037 $return .= '</span>';
2038 $return .= '<div class="info-box-content">';
2039 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
2040 if ($selected >= 0) {
2041 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2042 }
2043 if (property_exists($this, 'type_lib')) {
2044 $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
2045 }
2046 if (method_exists($this, 'solde')) {
2047 $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
2048 $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>';
2049 }
2050 if (method_exists($this, 'getLibStatut')) {
2051 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2052 }
2053 $return .= '</div>';
2054 $return .= '</div>';
2055 $return .= '</div>';
2056 return $return;
2057 }
2058}
2059
2060
2061require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
2062
2066class AccountLine extends CommonObjectLine
2067{
2071 public $db;
2072
2076 public $element = 'bank';
2077
2081 public $table_element = 'bank';
2082
2086 public $picto = 'accountline';
2087
2091 public $id;
2092
2096 public $ref;
2097
2103 public $datec;
2104
2110 public $dateo;
2111
2117 public $datev;
2118
2122 public $amount;
2123
2127 public $amount_main_currency;
2128
2132 public $fk_user_author;
2133
2137 public $fk_user_rappro;
2138
2142 public $fk_type;
2143
2147 public $fk_bordereau;
2148
2152 public $fk_account;
2153
2157 public $bank_account_ref;
2158
2162 public $bank_account_label;
2163
2167 public $numero_compte;
2168
2172 public $emetteur;
2173
2177 public $rappro;
2178
2182 public $num_releve;
2183
2187 public $num_chq;
2188
2192 public $bank_chq;
2193
2197 public $label;
2198
2202 public $note;
2203
2209 public $user_rappro;
2210
2211
2217 public function __construct(DoliDB $db)
2218 {
2219 $this->db = $db;
2220 }
2221
2230 public function fetch($rowid, $ref = '', $num = '')
2231 {
2232 // Check parameters
2233 if (empty($rowid) && empty($ref) && empty($num)) {
2234 return -1;
2235 }
2236
2237 $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2238 $sql .= " b.fk_user_author, b.fk_user_rappro,";
2239 $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2240 $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2241 $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2242 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2243 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2244 $sql .= " WHERE b.fk_account = ba.rowid";
2245 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2246 if ($num) {
2247 $sql .= " AND b.num_chq = '".$this->db->escape($num)."'";
2248 } elseif ($ref) {
2249 $sql .= " AND b.rowid = '".$this->db->escape($ref)."'";
2250 } else {
2251 $sql .= " AND b.rowid = ".((int) $rowid);
2252 }
2253
2254 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2255 $result = $this->db->query($sql);
2256 if ($result) {
2257 $ret = 0;
2258
2259 $obj = $this->db->fetch_object($result);
2260 if ($obj) {
2261 $this->id = $obj->rowid;
2262 $this->rowid = $obj->rowid;
2263 $this->ref = $obj->rowid;
2264
2265 $this->datec = $this->db->jdate($obj->datec);
2266 $this->datev = $this->db->jdate($obj->datev);
2267 $this->dateo = $this->db->jdate($obj->dateo);
2268 $this->amount = $obj->amount;
2269 $this->label = $obj->label;
2270 $this->note = $obj->note;
2271
2272 $this->fk_user_author = $obj->fk_user_author;
2273 $this->fk_user_rappro = $obj->fk_user_rappro;
2274
2275 $this->fk_type = $obj->fk_type; // Type of transaction
2276 $this->rappro = (int) $obj->rappro;
2277 $this->num_releve = $obj->num_releve;
2278
2279 $this->num_chq = $obj->num_chq;
2280 $this->bank_chq = $obj->banque;
2281 $this->fk_bordereau = $obj->fk_bordereau;
2282
2283 $this->fk_account = $obj->fk_account;
2284 $this->bank_account_ref = $obj->bank_account_ref;
2285 $this->bank_account_label = $obj->bank_account_label;
2286
2287 // Retrieve all extrafield
2288 // fetch optionals attributes and labels
2289 $this->fetch_optionals();
2290
2291 $ret = 1;
2292 }
2293 $this->db->free($result);
2294 return $ret;
2295 } else {
2296 return -1;
2297 }
2298 }
2299
2305 public function insert()
2306 {
2307 $error = 0;
2308
2309 $this->db->begin();
2310
2311 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2312 $sql .= "datec";
2313 $sql .= ", dateo";
2314 $sql .= ", datev";
2315 $sql .= ", label";
2316 $sql .= ", amount";
2317 $sql .= ", amount_main_currency";
2318 $sql .= ", fk_user_author";
2319 $sql .= ", num_chq";
2320 $sql .= ", fk_account";
2321 $sql .= ", fk_type";
2322 $sql .= ", emetteur,banque";
2323 $sql .= ", rappro";
2324 $sql .= ", numero_compte";
2325 $sql .= ", num_releve";
2326 $sql .= ", note";
2327 $sql .= ") VALUES (";
2328 $sql .= "'".$this->db->idate($this->datec)."'";
2329 $sql .= ", '".$this->db->idate($this->dateo)."'";
2330 $sql .= ", '".$this->db->idate($this->datev)."'";
2331 $sql .= ", '".$this->db->escape($this->label)."'";
2332 $sql .= ", ".price2num($this->amount);
2333 $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2334 $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2335 $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2336 $sql .= ", '".$this->db->escape((string) $this->fk_account)."'";
2337 $sql .= ", '".$this->db->escape($this->fk_type)."'";
2338 $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2339 $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2340 $sql .= ", ".(int) $this->rappro;
2341 $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2342 $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2343 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
2344 $sql .= ")";
2345
2346
2347 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2348 $resql = $this->db->query($sql);
2349 if ($resql) {
2350 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2351 // Actions on extra fields (by external module or standard code)
2352 $result = $this->insertExtraFields();
2353 if ($result < 0) {
2354 $error++;
2355 }
2356 } else {
2357 $error++;
2358 $this->error = $this->db->lasterror();
2359 dol_print_error($this->db);
2360 }
2361
2362 if (!$error) {
2363 $this->db->commit();
2364 return $this->id;
2365 } else {
2366 $this->db->rollback();
2367 return -1 * $error;
2368 }
2369 }
2370
2378 public function delete($user, $notrigger = 0)
2379 {
2380 $nbko = 0;
2381
2382 if ($this->rappro) {
2383 // Protection to avoid any delete of consolidated lines
2384 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2385 return -1;
2386 }
2387
2388 $this->db->begin();
2389
2390 if (!$notrigger) {
2391 // Call trigger
2392 $result = $this->call_trigger('BANKACCOUNTLINE_DELETE', $user);
2393 if ($result < 0) {
2394 $this->db->rollback();
2395 return -1;
2396 }
2397 // End call triggers
2398 }
2399
2400 // Protection to avoid any delete of accounted lines. Protection on by default
2401 if (!getDolGlobalString('BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING')) {
2402 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2403 $resql = $this->db->query($sql);
2404 if ($resql) {
2405 $obj = $this->db->fetch_object($resql);
2406 if ($obj && $obj->nb) {
2407 $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2408 $this->db->rollback();
2409 return -1;
2410 }
2411 } else {
2412 $this->error = $this->db->lasterror();
2413 $this->db->rollback();
2414 return -1;
2415 }
2416 }
2417
2418 // Delete urls
2419 $result = $this->delete_urls($user);
2420 if ($result < 0) {
2421 $nbko++;
2422 }
2423
2424 $sql = "DELETE FROM ".MAIN_DB_PREFIX."category_bankline WHERE lineid=".(int) $this->rowid;
2425 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2426 $result = $this->db->query($sql);
2427 if (!$result) {
2428 $nbko++;
2429 }
2430
2431 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2432 $result = $this->db->query($sql);
2433 if (!$result) {
2434 $nbko++;
2435 }
2436
2437 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2438 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2439 $result = $this->db->query($sql);
2440 if (!$result) {
2441 $nbko++;
2442 }
2443
2444 if (!$nbko) {
2445 $this->db->commit();
2446 return 1;
2447 } else {
2448 $this->db->rollback();
2449 return -$nbko;
2450 }
2451 }
2452
2453
2454 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2461 public function delete_urls($user = null)
2462 {
2463 // phpcs:enable
2464 $nbko = 0;
2465
2466 if ($this->rappro) {
2467 // Protection to avoid any delete of consolidated lines
2468 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2469 return -1;
2470 }
2471
2472 $this->db->begin();
2473
2474 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2475 dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2476 $result = $this->db->query($sql);
2477 if (!$result) {
2478 $nbko++;
2479 }
2480
2481 if (!$nbko) {
2482 $this->db->commit();
2483 return 1;
2484 } else {
2485 $this->db->rollback();
2486 return -$nbko;
2487 }
2488 }
2489
2490
2498 public function update(User $user, $notrigger = 0)
2499 {
2500 $this->db->begin();
2501
2502 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2503 $sql .= " amount = ".price2num($this->amount).",";
2504 $sql .= " datev='".$this->db->idate($this->datev)."',";
2505 $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2506 $sql .= " WHERE rowid = ".((int) $this->rowid);
2507
2508 dol_syslog(get_class($this)."::update", LOG_DEBUG);
2509 $resql = $this->db->query($sql);
2510 if ($resql) {
2511 $this->db->commit();
2512 return 1;
2513 } else {
2514 $this->db->rollback();
2515 $this->error = $this->db->error();
2516 return -1;
2517 }
2518 }
2519
2520
2526 public function updateLabel()
2527 {
2528 $this->db->begin();
2529
2530 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2531 $sql .= " label = '".$this->db->escape($this->label)."'";
2532 $sql .= " WHERE rowid = ".((int) $this->rowid);
2533
2534 dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
2535 $resql = $this->db->query($sql);
2536 if ($resql) {
2537 $this->db->commit();
2538 return 1;
2539 } else {
2540 $this->db->rollback();
2541 $this->error = $this->db->error();
2542 return -1;
2543 }
2544 }
2545
2546
2547 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2556 public function update_conciliation(User $user, $cat, $conciliated = 1)
2557 {
2558 // phpcs:enable
2559 global $conf, $langs;
2560
2561 $this->db->begin();
2562
2563 // Check statement field
2564 if (getDolGlobalString('BANK_STATEMENT_REGEX_RULE')) {
2565 if (!preg_match('/' . getDolGlobalString('BANK_STATEMENT_REGEX_RULE').'/', $this->num_releve)) {
2566 $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", getDolGlobalString('BANK_STATEMENT_REGEX_RULE'));
2567 return -1;
2568 }
2569 }
2570
2571 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2572 $sql .= " rappro = ".((int) $conciliated);
2573 $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2574 if ($conciliated) {
2575 $sql .= ", fk_user_rappro = ".((int) $user->id);
2576 }
2577 $sql .= " WHERE rowid = ".((int) $this->id);
2578
2579 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2580 $resql = $this->db->query($sql);
2581 if ($resql) {
2582 if (!empty($cat) && $cat > 0) {
2583 $sql = "INSERT INTO ".MAIN_DB_PREFIX."category_bankline (";
2584 $sql .= "lineid";
2585 $sql .= ", fk_categ";
2586 $sql .= ") VALUES (";
2587 $sql .= $this->id;
2588 $sql .= ", ".((int) $cat);
2589 $sql .= ")";
2590
2591 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2592 $this->db->query($sql);
2593
2594 // No error check. Can fail if category already affected
2595 // TODO Do no try the insert if link already exists
2596 }
2597
2598 $this->rappro = (int) $conciliated;
2599
2600 $this->db->commit();
2601 return 1;
2602 } else {
2603 $this->db->rollback();
2604 return -1;
2605 }
2606 }
2607
2608
2609 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2617 public function datev_change($rowid, $sign = 1)
2618 {
2619 // phpcs:enable
2620 $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2621 $resql = $this->db->query($sql);
2622 if ($resql) {
2623 $obj = $this->db->fetch_object($resql);
2624 $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2625
2626 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2627 $sql .= " datev = '".$this->db->idate($newdate)."'";
2628 $sql .= " WHERE rowid = ".((int) $rowid);
2629
2630 $result = $this->db->query($sql);
2631 if ($result) {
2632 if ($this->db->affected_rows($result)) {
2633 return 1;
2634 }
2635 } else {
2636 dol_print_error($this->db);
2637 return 0;
2638 }
2639 } else {
2640 dol_print_error($this->db);
2641 }
2642 return 0;
2643 }
2644
2645 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2652 public function datev_next($id)
2653 {
2654 // phpcs:enable
2655 return $this->datev_change($id, 1);
2656 }
2657
2658 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2665 public function datev_previous($id)
2666 {
2667 // phpcs:enable
2668 return $this->datev_change($id, -1);
2669 }
2670
2671
2672 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2680 public function dateo_change($rowid, $sign = 1)
2681 {
2682 // phpcs:enable
2683 $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2684 $resql = $this->db->query($sql);
2685 if ($resql) {
2686 $obj = $this->db->fetch_object($resql);
2687 $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2688
2689 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2690 $sql .= " dateo = '".$this->db->idate($newdate)."'";
2691 $sql .= " WHERE rowid = ".((int) $rowid);
2692
2693 $result = $this->db->query($sql);
2694 if ($result) {
2695 if ($this->db->affected_rows($result)) {
2696 return 1;
2697 }
2698 } else {
2699 dol_print_error($this->db);
2700 return 0;
2701 }
2702 } else {
2703 dol_print_error($this->db);
2704 }
2705 return 0;
2706 }
2707
2708 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2715 public function dateo_next($id)
2716 {
2717 // phpcs:enable
2718 return $this->dateo_change($id, 1);
2719 }
2720
2721 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2728 public function dateo_previous($id)
2729 {
2730 // phpcs:enable
2731 return $this->dateo_change($id, -1);
2732 }
2733
2734
2741 public function info($id)
2742 {
2743 $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2744 $sql .= ' b.fk_user_author, b.fk_user_rappro';
2745 $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2746 $sql .= ' WHERE b.rowid = '.((int) $id);
2747
2748 $result = $this->db->query($sql);
2749 if ($result) {
2750 if ($this->db->num_rows($result)) {
2751 $obj = $this->db->fetch_object($result);
2752
2753 $this->id = $obj->rowid;
2754
2755 $this->user_creation_id = $obj->fk_user_author;
2756 $this->user_rappro = $obj->fk_user_rappro;
2757 $this->date_creation = $this->db->jdate($obj->datec);
2758 $this->date_modification = $this->db->jdate($obj->datem);
2759 //$this->date_rappro = $obj->daterappro; // Not yet managed
2760 }
2761 $this->db->free($result);
2762 } else {
2763 dol_print_error($this->db);
2764 }
2765 }
2766
2767
2777 public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2778 {
2779 global $conf, $langs;
2780
2781 $result = '';
2782
2783 $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2784 $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2785 if ($this->amount) {
2786 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2787 }
2788
2789 $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">';
2790 $linkend = '</a>';
2791
2792 $result .= $linkstart;
2793 if ($withpicto) {
2794 $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);
2795 }
2796 if ($withpicto != 2) {
2797 $result .= ($this->ref ? $this->ref : $this->id);
2798 }
2799
2800 $result .= $linkend;
2801
2802 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2803 $result .= ' <span class="opacitymedium">(';
2804 }
2805 if ($option == 'showall') {
2806 $result .= $langs->trans("BankAccount").': ';
2807 $accountstatic = new Account($this->db);
2808 $accountstatic->id = $this->fk_account;
2809 $accountstatic->ref = $this->bank_account_ref;
2810 $accountstatic->label = $this->bank_account_label;
2811 $result .= $accountstatic->getNomUrl(0).', ';
2812 }
2813 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2814 $result .= $langs->trans("BankLineConciliated").': ';
2815 $result .= yn($this->rappro);
2816 }
2817 if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2818 $sql = "SELECT COUNT(rowid) as nb, MAX(piece_num) as banktransactionid FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2819 $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2820 $resql = $this->db->query($sql);
2821 if ($resql) {
2822 $obj = $this->db->fetch_object($resql);
2823 if ($obj && $obj->nb) {
2824 $result .= ' - '.$langs->trans("Accounted").': <span title="'.$langs->trans("TransactionNumShort").' '.$obj->banktransactionid.'">'.yn(1).'</span>';
2825 } else {
2826 $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2827 }
2828 }
2829 }
2830 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2831 $result .= ')</span>';
2832 }
2833
2834 return $result;
2835 }
2836
2837
2844 public function getLibStatut($mode = 0)
2845 {
2846 return $this->LibStatut($this->status, $mode);
2847 }
2848
2849 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2857 public function LibStatut($status, $mode = 0)
2858 {
2859 // phpcs:enable
2860 return '';
2861 }
2862
2869 public function getVentilExportCompta($mode = 0)
2870 {
2871 $alreadydispatched = 0;
2872
2873 $type = 'bank';
2874
2875 $sql = " SELECT ".($mode ? 'DISTINCT piece_num' : 'COUNT(ab.rowid)')." as nb";
2876 $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type = '".$this->db->escape($type)."' AND ab.fk_doc = ".((int) $this->id);
2877 $resql = $this->db->query($sql);
2878 if ($resql) {
2879 $obj = $this->db->fetch_object($resql);
2880 if ($obj) {
2881 $alreadydispatched = $obj->nb;
2882 }
2883 } else {
2884 $this->error = $this->db->lasterror();
2885 return -1;
2886 }
2887
2888 if ($alreadydispatched) {
2889 return $alreadydispatched;
2890 }
2891 return 0;
2892 }
2893}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
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:380
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition bank.lib.php:405
checkSwiftForAccount($account=null, $swift=null)
Check SWIFT information for a bank account.
Definition bank.lib.php:359
$object ref
Definition info.php:90
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.
addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur='', $banque='', $accountancycode='', $datev=null, $num_releve='', $amount_main_currency=null, $note_private='')
Add an entry into table llx_bank.
getBannerAddress($htmlkey, $object)
Return full address for banner.
error()
Return error.
info($id)
Load miscellaneous information for tab "Info".
const TYPE_CASH
Cash account.
update($user, $notrigger=0)
Update bank account card.
__toString()
Shows the account number in the appropriate format.
delete($user, $notrigger=0)
Delete bank account from database.
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.
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.
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
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
global $mysoc
dol_now($mode='gmt')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
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 '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
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_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.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
div refaddress div address
if(getDolGlobalString( 'TAKEPOS_SHOW_CUSTOMER')) print $langs trans('Date')." left Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:466
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:125