dolibarr 21.0.0-alpha
account.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
6 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2015-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
11 * Copyright (C) 2019 JC Prieto <jcprieto@virtual20.com><prietojc@gmail.com>
12 * Copyright (C) 2022-2024 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27 */
28
35require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
36
37
41class Account extends CommonObject
42{
46 public $element = 'bank_account';
47
51 public $table_element = 'bank_account';
52
56 public $picto = 'account';
57
63 public $rowid;
64
69 public $label;
70
77 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;
193 public $owner_country_id;
194 public $owner_country_code;
195
202 public $domiciliation;
203
208 public $address;
209 public $state_id;
210 public $state_code;
211 public $state;
212 public $country_id;
213
219 public $type_lib = array();
220
225 public $account_number;
226
230 public $fk_accountancy_journal;
231
235 public $accountancy_journal;
236
241 public $currency_code;
242
249 public $account_currency_code;
250
255 public $min_allowed;
256
261 public $min_desired;
262
267 public $comment;
268
273 public $date_solde;
274
281 public $solde;
282
287 public $balance;
288
293 public $ics;
294
299 public $ics_transfer;
300
304 public $oldref;
305
306
331 // BEGIN MODULEBUILDER PROPERTIES
335 public $fields = array(
336 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
337 'ref' => array('type' => 'varchar(12)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 25),
338 'label' => array('type' => 'varchar(30)', 'label' => 'Label', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 30),
339 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 35, 'index' => 1),
340 'bank' => array('type' => 'varchar(60)', 'label' => 'Bank', 'enabled' => 1, 'visible' => -1, 'position' => 40),
341 'code_banque' => array('type' => 'varchar(128)', 'label' => 'Code banque', 'enabled' => 1, 'visible' => -1, 'position' => 45),
342 'code_guichet' => array('type' => 'varchar(6)', 'label' => 'Code guichet', 'enabled' => 1, 'visible' => -1, 'position' => 50),
343 'number' => array('type' => 'varchar(255)', 'label' => 'Number', 'enabled' => 1, 'visible' => -1, 'position' => 55),
344 'cle_rib' => array('type' => 'varchar(5)', 'label' => 'Cle rib', 'enabled' => 1, 'visible' => -1, 'position' => 60),
345 'bic' => array('type' => 'varchar(11)', 'label' => 'Bic', 'enabled' => 1, 'visible' => -1, 'position' => 65),
346 'iban_prefix' => array('type' => 'varchar(34)', 'label' => 'Iban prefix', 'enabled' => 1, 'visible' => -1, 'position' => 70),
347 'country_iban' => array('type' => 'varchar(2)', 'label' => 'Country iban', 'enabled' => 1, 'visible' => -1, 'position' => 75),
348 'cle_iban' => array('type' => 'varchar(2)', 'label' => 'Cle iban', 'enabled' => 1, 'visible' => -1, 'position' => 80),
349 'domiciliation' => array('type' => 'varchar(255)', 'label' => 'Domiciliation', 'enabled' => 1, 'visible' => -1, 'position' => 85),
350 'state_id' => array('type' => 'integer', 'label' => 'StateId', 'enabled' => 1, 'visible' => -1, 'position' => 90),
351 'fk_pays' => array('type' => 'integer', 'label' => 'Country', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 95),
352 'proprio' => array('type' => 'varchar(60)', 'label' => 'Proprio', 'enabled' => 1, 'visible' => -1, 'position' => 100),
353 'owner_address' => array('type' => 'varchar(255)', 'label' => 'Owner address', 'enabled' => 1, 'visible' => -1, 'position' => 105),
354 'owner_zip' => array('type' => 'varchar(25)', 'label' => 'Owner zip', 'enabled' => 1, 'visible' => -1, 'position' => 106),
355 'owner_town' => array('type' => 'varchar(50)', 'label' => 'Owner town', 'enabled' => 1, 'visible' => -1, 'position' => 107),
356 'owner_country_id' => array('type' => 'integer', 'label' => 'Owner country', 'enabled' => 1, 'visible' => -1, 'position' => 108),
357 'courant' => array('type' => 'smallint(6)', 'label' => 'Courant', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 110),
358 'clos' => array('type' => 'smallint(6)', 'label' => 'Clos', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 115),
359 'rappro' => array('type' => 'smallint(6)', 'label' => 'Rappro', 'enabled' => 1, 'visible' => -1, 'position' => 120),
360 'url' => array('type' => 'varchar(128)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 125),
361 'account_number' => array('type' => 'varchar(32)', 'label' => 'Account number', 'enabled' => 1, 'visible' => -1, 'position' => 130),
362 'fk_accountancy_journal' => array('type' => 'integer', 'label' => 'Accountancy journal ID', 'enabled' => 1, 'visible' => -1, 'position' => 132),
363 'accountancy_journal' => array('type' => 'varchar(20)', 'label' => 'Accountancy journal', 'enabled' => 1, 'visible' => -1, 'position' => 135),
364 'currency_code' => array('type' => 'varchar(3)', 'label' => 'Currency code', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 140),
365 'min_allowed' => array('type' => 'integer', 'label' => 'Min allowed', 'enabled' => 1, 'visible' => -1, 'position' => 145),
366 'min_desired' => array('type' => 'integer', 'label' => 'Min desired', 'enabled' => 1, 'visible' => -1, 'position' => 150),
367 'comment' => array('type' => 'text', 'label' => 'Comment', 'enabled' => 1, 'visible' => -1, 'position' => 155),
368 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 156),
369 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 157),
370 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'Fk user author', 'enabled' => 1, 'visible' => -1, 'position' => 160),
371 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 165),
372 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 170),
373 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 175),
374 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 180),
375 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 185),
376 );
377 // END MODULEBUILDER PROPERTIES
378
382 const TYPE_CURRENT = 1;
386 const TYPE_CASH = 2;
390 const TYPE_SAVINGS = 0;
391
392
393 const STATUS_OPEN = 0;
394 const STATUS_CLOSED = 1;
395
396
402 public function __construct(DoliDB $db)
403 {
404 global $langs;
405
406 $this->db = $db;
407
408 $this->ismultientitymanaged = 1;
409
410 $this->balance = 0;
411
412 $this->type_lib = array(
413 self::TYPE_SAVINGS => $langs->transnoentitiesnoconv("BankType0"),
414 self::TYPE_CURRENT => $langs->transnoentitiesnoconv("BankType1"),
415 self::TYPE_CASH => $langs->transnoentitiesnoconv("BankType2"),
416 );
417
418 $this->labelStatus = array(
419 self::STATUS_OPEN => $langs->transnoentitiesnoconv("StatusAccountOpened"),
420 self::STATUS_CLOSED => $langs->transnoentitiesnoconv("StatusAccountClosed")
421 );
422 }
423
429 public function __toString()
430 {
431 $string = '';
432 foreach ($this->getFieldsToShow() as $val) {
433 if ($val == 'BankCode') {
434 $string .= $this->code_banque.' ';
435 } elseif ($val == 'BankAccountNumber') {
436 $string .= $this->number.' ';
437 } elseif ($val == 'DeskCode') {
438 $string .= $this->code_guichet.' ';
439 } elseif ($val == 'BankAccountNumberKey') {
440 $string .= $this->cle_rib.' ';
441 } elseif ($val == 'BIC') {
442 $string .= $this->bic.' ';
443 } elseif ($val == 'IBAN') {
444 $string .= $this->iban.' ';
445 }
446 }
447
448 return trim($string);
449 }
450
451
457 public function canBeConciliated()
458 {
459 global $conf;
460
461 if (empty($this->rappro)) {
462 return -1;
463 }
464 if ($this->type == Account::TYPE_CASH && !getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
465 return -2;
466 }
467 if ($this->status) {
468 return -3;
469 }
470 return 1;
471 }
472
473
474 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
485 public function add_url_line($line_id, $url_id, $url, $label, $type)
486 {
487 // phpcs:enable
488 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
489 $sql .= "fk_bank";
490 $sql .= ", url_id";
491 $sql .= ", url"; // deprecated
492 $sql .= ", label";
493 $sql .= ", type";
494 $sql .= ") VALUES (";
495 $sql .= ((int) $line_id);
496 $sql .= ", ".((int) $url_id);
497 $sql .= ", '".$this->db->escape($url)."'"; // deprecated
498 $sql .= ", '".$this->db->escape($label)."'";
499 $sql .= ", '".$this->db->escape($type)."'";
500 $sql .= ")";
501
502 dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
503 if ($this->db->query($sql)) {
504 $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
505 return $rowid;
506 } else {
507 $this->error = $this->db->lasterror();
508 return -1;
509 }
510 }
511
512 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
522 public function get_url($fk_bank = 0, $url_id = 0, $type = '')
523 {
524 // phpcs:enable
525 $lines = array();
526
527 // Check parameters
528 if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
529 $this->error = "ErrorBadParameter";
530 return -1;
531 }
532
533 $sql = "SELECT fk_bank, url_id, url, label, type";
534 $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
535 if ($fk_bank > 0) {
536 $sql .= " WHERE fk_bank = ".((int) $fk_bank);
537 } else {
538 $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
539 }
540 $sql .= " ORDER BY type, label";
541
542 dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
543 $result = $this->db->query($sql);
544 if ($result) {
545 $i = 0;
546 $num = $this->db->num_rows($result);
547 while ($i < $num) {
548 $obj = $this->db->fetch_object($result);
549 // Old links (for compatibility)
550 $lines[$i][0] = $obj->url;
551 $lines[$i][1] = $obj->url_id;
552 $lines[$i][2] = $obj->label;
553 $lines[$i][3] = $obj->type;
554 // New links
555 $lines[$i]['url'] = $obj->url;
556 $lines[$i]['url_id'] = $obj->url_id;
557 $lines[$i]['label'] = $obj->label;
558 $lines[$i]['type'] = $obj->type;
559 $lines[$i]['fk_bank'] = $obj->fk_bank;
560 $i++;
561 }
562 } else {
563 dol_print_error($this->db);
564 }
565
566 return $lines;
567 }
568
587 public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
588 {
589 global $langs;
590
591 // Deprecation warning
592 if (is_numeric($oper)) {
593 dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
594 }
595
596 if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
597 $this->id = $this->rowid;
598 }
599
600 // Clean parameters
601 $emetteur = trim($emetteur);
602 $banque = trim($banque);
603 $label = trim($label);
604
605 $now = dol_now();
606
607 if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
608 $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
609 $sql .= " WHERE id = ".((int) $oper);
610 $sql .= " AND entity IN (".getEntity('c_paiement').")";
611 $resql = $this->db->query($sql);
612 if ($resql) {
613 $obj = $this->db->fetch_object($resql);
614 $oper = $obj->code;
615 } else {
616 dol_print_error($this->db, 'Failed to get payment type code');
617 return -1;
618 }
619 }
620
621 // Check parameters
622 if (!$oper) {
623 $this->error = $langs->trans("OperNotDefined");
624 return -1;
625 }
626 if (!$this->id) {
627 $this->error = $langs->trans("ThisIdNotDefined");
628 return -2;
629 }
630 if ($this->type == Account::TYPE_CASH && $oper != 'LIQ') {
631 $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
632 return -3;
633 }
634
635 $this->db->begin();
636
637 if (is_null($datev) || empty($datev)) {
638 $datev = $date;
639 }
640
641 $accline = new AccountLine($this->db);
642 $accline->datec = $now;
643 $accline->dateo = $date;
644 $accline->datev = $datev;
645 $accline->label = $label;
646 $accline->amount = $amount;
647 $accline->amount_main_currency = $amount_main_currency;
648 $accline->fk_user_author = $user->id;
649 $accline->fk_account = $this->id;
650 $accline->fk_type = $oper;
651 $accline->numero_compte = $accountancycode;
652 $accline->num_releve = $num_releve;
653
654 if ($num_chq) {
655 $accline->num_chq = $num_chq;
656 }
657
658 if ($emetteur) {
659 $accline->emetteur = $emetteur;
660 }
661
662 if ($banque) {
663 $accline->bank_chq = $banque;
664 }
665
666 if ($accline->insert() > 0) {
667 if ($categorie > 0) {
668 $sql = "INSERT INTO ".MAIN_DB_PREFIX."category_bankline(";
669 $sql .= "lineid, fk_categ";
670 $sql .= ") VALUES (";
671 $sql .= ((int) $accline->id).", '".$this->db->escape($categorie)."'";
672 $sql .= ")";
673
674 $result = $this->db->query($sql);
675 if (!$result) {
676 $this->error = $this->db->lasterror();
677 $this->db->rollback();
678
679 return -4;
680 }
681 }
682
683 $this->db->commit();
684
685 return $accline->id;
686 } else {
687 $this->setErrorsFromObject($accline);
688 $this->db->rollback();
689
690 return -5;
691 }
692 }
693
701 public function create($user, $notrigger = 0)
702 {
703 global $langs, $conf;
704
705 $error = 0;
706
707 // Clean parameters
708 if (!$this->min_allowed) {
709 $this->min_allowed = 0;
710 }
711 if (!$this->min_desired) {
712 $this->min_desired = 0;
713 }
714
715 // Check parameters
716 if (empty($this->country_id)) {
717 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
718 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
719 return -1;
720 }
721 if (empty($this->ref)) {
722 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
723 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
724 return -1;
725 }
726 if (empty($this->date_solde)) {
727 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
728 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
729 return -1;
730 }
731
732 // Load libraries to check BAN
733 $balance = $this->balance;
734 if (empty($balance) && !empty($this->solde)) {
735 $balance = $this->solde;
736 }
737 if (empty($balance)) {
738 $balance = 0;
739 }
740 if (empty($this->address && !empty($this->domiciliation))) {
741 dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE);
742 $this->address = $this->domiciliation;
743 }
744 if (empty($this->status && !empty($this->clos))) {
745 dol_syslog(get_class($this)."::create clos is deprecated use status", LOG_NOTICE);
746 $this->status = $this->clos;
747 }
748
749 if (empty($this->address && !empty($this->domiciliation))) {
750 dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE);
751 $this->address = $this->domiciliation;
752 }
753
754 // Load the library to validate/check a BAN account
755 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
756
757 $now = dol_now();
758
759 $this->db->begin();
760
761 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
762 $sql .= "datec";
763 $sql .= ", ref";
764 $sql .= ", label";
765 $sql .= ", entity";
766 $sql .= ", account_number";
767 $sql .= ", fk_accountancy_journal";
768 $sql .= ", bank";
769 $sql .= ", code_banque";
770 $sql .= ", code_guichet";
771 $sql .= ", number";
772 $sql .= ", cle_rib";
773 $sql .= ", bic";
774 $sql .= ", iban_prefix";
775 $sql .= ", domiciliation";
776 $sql .= ", pti_in_ctti";
777 $sql .= ", proprio";
778 $sql .= ", owner_address";
779 $sql .= ", owner_zip";
780 $sql .= ", owner_town";
781 $sql .= ", owner_country_id";
782 $sql .= ", currency_code";
783 $sql .= ", rappro";
784 $sql .= ", min_allowed";
785 $sql .= ", min_desired";
786 $sql .= ", comment";
787 $sql .= ", state_id";
788 $sql .= ", fk_pays";
789 $sql .= ", ics";
790 $sql .= ", ics_transfer";
791 $sql .= ") VALUES (";
792 $sql .= "'".$this->db->idate($now)."'";
793 $sql .= ", '".$this->db->escape($this->ref)."'";
794 $sql .= ", '".$this->db->escape($this->label)."'";
795 $sql .= ", ".((int) $conf->entity);
796 $sql .= ", '".$this->db->escape($this->account_number)."'";
797 $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
798 $sql .= ", '".$this->db->escape($this->bank)."'";
799 $sql .= ", '".$this->db->escape($this->code_banque)."'";
800 $sql .= ", '".$this->db->escape($this->code_guichet)."'";
801 $sql .= ", '".$this->db->escape($this->number)."'";
802 $sql .= ", '".$this->db->escape($this->cle_rib)."'";
803 $sql .= ", '".$this->db->escape($this->bic)."'";
804 $sql .= ", '".$this->db->escape($this->iban)."'";
805 $sql .= ", '".$this->db->escape($this->address)."'";
806 $sql .= ", ".((int) $this->pti_in_ctti);
807 $sql .= ", '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'";
808 $sql .= ", '".$this->db->escape($this->owner_address)."'";
809 $sql .= ", '".$this->db->escape($this->owner_zip)."'";
810 $sql .= ", '".$this->db->escape($this->owner_town)."'";
811 $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
812 $sql .= ", '".$this->db->escape($this->currency_code)."'";
813 $sql .= ", ".((int) $this->rappro);
814 $sql .= ", ".price2num($this->min_allowed, 'MT');
815 $sql .= ", ".price2num($this->min_desired, 'MT');
816 $sql .= ", '".$this->db->escape($this->comment)."'";
817 $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
818 $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
819 $sql .= ", '".$this->db->escape($this->ics)."'";
820 $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
821 $sql .= ")";
822
823 dol_syslog(get_class($this)."::create", LOG_DEBUG);
824 $resql = $this->db->query($sql);
825 if ($resql) {
826 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
827
828 $result = $this->update($user, 1);
829 if ($result > 0) {
830 $accline = new AccountLine($this->db);
831 $accline->datec = $now;
832 $accline->label = '('.$langs->trans("InitialBankBalance").')';
833 $accline->amount = (float) price2num($balance);
834 $accline->fk_user_author = $user->id;
835 $accline->fk_account = $this->id;
836 $accline->datev = $this->date_solde;
837 $accline->dateo = $this->date_solde;
838 $accline->fk_type = 'SOLD';
839
840 if ($accline->insert() < 0) {
841 $error++;
842 $this->error = $accline->error;
843 $this->errors = $accline->errors;
844 }
845
846 if (!$error) {
847 $result = $this->insertExtraFields();
848 if ($result < 0) {
849 $error++;
850 }
851 }
852
853 if (!$error && !$notrigger) {
854 // Call trigger
855 $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
856 if ($result < 0) {
857 $error++;
858 }
859 // End call triggers
860 }
861 } else {
862 $error++;
863 }
864 } else {
865 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
866 $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
867 $error++;
868 } else {
869 $this->error = $this->db->error()." sql=".$sql;
870 $error++;
871 }
872 }
873
874 if (!$error) {
875 $this->db->commit();
876 return $this->id;
877 } else {
878 $this->db->rollback();
879 return -1 * $error;
880 }
881 }
882
890 public function update($user, $notrigger = 0)
891 {
892 global $langs, $conf;
893
894 $error = 0;
895
896 $this->db->begin();
897
898 // Check parameters
899 if (empty($this->country_id)) {
900 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
901 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
902 return -1;
903 }
904 if (empty($this->ref)) {
905 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
906 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
907 return -1;
908 }
909 if (!$this->label) {
910 $this->label = "???";
911 }
912
913 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
914 $sql .= " ref = '".$this->db->escape($this->ref)."'";
915 $sql .= ",label = '".$this->db->escape($this->label)."'";
916 $sql .= ",courant = ".((int) $this->type);
917 $sql .= ",clos = ".((int) $this->status);
918 $sql .= ",rappro = ".((int) $this->rappro);
919 $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
920 $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
921 $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
922 $sql .= ",bank = '".$this->db->escape($this->bank)."'";
923 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
924 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
925 $sql .= ",number='".$this->db->escape($this->number)."'";
926 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
927 $sql .= ",bic='".$this->db->escape($this->bic)."'";
928 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
929 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
930 $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
931 $sql .= ",proprio = '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'";
932 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
933 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
934 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
935 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
936
937 $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
938
939 $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
940 $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
941 $sql .= ",comment = '".$this->db->escape($this->comment)."'";
942
943 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
944 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
945 $sql .= ",ics = '".$this->db->escape($this->ics)."'";
946 $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
947
948 $sql .= " WHERE rowid = ".((int) $this->id);
949
950 dol_syslog(get_class($this)."::update", LOG_DEBUG);
951 $result = $this->db->query($sql);
952 if ($result) {
953 // Actions on extra fields (by external module or standard code)
954 if (!$error) {
955 $result = $this->insertExtraFields();
956 if ($result < 0) {
957 $error++;
958 }
959 }
960
961 if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
962 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
963 $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type='bank_account' and entity = ".((int) $conf->entity);
964 $resql = $this->db->query($sql);
965 if (!$resql) {
966 $error++;
967 $this->error = $this->db->lasterror();
968 }
969
970 // We rename directory in order not to lose the attachments
971 $oldref = dol_sanitizeFileName($this->oldref);
972 $newref = dol_sanitizeFileName($this->ref);
973 $dirsource = $conf->bank->dir_output.'/'.$oldref;
974 $dirdest = $conf->bank->dir_output.'/'.$newref;
975 if (file_exists($dirsource)) {
976 dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
977 if (@rename($dirsource, $dirdest)) {
978 dol_syslog("Rename ok", LOG_DEBUG);
979 }
980 }
981 }
982
983 if (!$error && !$notrigger) {
984 // Call trigger
985 $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
986 if ($result < 0) {
987 $error++;
988 }
989 // End call triggers
990 }
991 } else {
992 $error++;
993 $this->error = $this->db->lasterror();
994 dol_print_error($this->db);
995 }
996
997 if (!$error) {
998 $this->db->commit();
999 return $this->id;
1000 } else {
1001 $this->db->rollback();
1002 return -1 * $error;
1003 }
1004 }
1005
1006
1007 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1014 public function update_bban($user = null)
1015 {
1016 // phpcs:enable
1017 global $conf, $langs;
1018
1019 // Load library to get BAN control function
1020 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1021
1022 dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
1023
1024 // Check parameters
1025 if (!$this->ref) {
1026 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
1027 return -2;
1028 }
1029
1030 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
1031 $sql .= " bank = '".$this->db->escape($this->bank)."'";
1032 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1033 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1034 $sql .= ",number='".$this->db->escape($this->number)."'";
1035 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1036 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1037 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1038 $sql .= ",domiciliation='".$this->db->escape($this->address ? $this->address : $this->domiciliation)."'";
1039 $sql .= ",proprio = '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'";
1040 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1041 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1042 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1043 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1044 $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
1045 $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
1046 $sql .= " WHERE rowid = ".((int) $this->id);
1047 $sql .= " AND entity = ".((int) $conf->entity);
1048
1049 dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
1050
1051 $result = $this->db->query($sql);
1052 if ($result) {
1053 return 1;
1054 } else {
1055 $this->error = $this->db->lasterror();
1056 dol_print_error($this->db);
1057 return -1;
1058 }
1059 }
1060
1061
1069 public function fetch($id, $ref = '')
1070 {
1071 if (empty($id) && empty($ref)) {
1072 $this->error = "ErrorBadParameters";
1073 return -1;
1074 }
1075
1076 $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant as type, ba.clos as status, ba.rappro, ba.url,";
1077 $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1078 $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,";
1079 $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1080 $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1081 $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1082 $sql .= ' c.code as country_code, c.label as country,';
1083 $sql .= ' d.code_departement as state_code, d.nom as state,';
1084 $sql .= ' aj.code as accountancy_journal';
1085 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1086 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1087 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1088 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1089 $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1090 if ($id) {
1091 $sql .= " AND ba.rowid = ".((int) $id);
1092 }
1093 if ($ref) {
1094 $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1095 }
1096
1097 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1098 $result = $this->db->query($sql);
1099 if ($result) {
1100 if ($this->db->num_rows($result)) {
1101 $obj = $this->db->fetch_object($result);
1102
1103 $this->id = $obj->rowid;
1104 $this->rowid = $obj->rowid;
1105 $this->ref = $obj->ref;
1106 $this->label = $obj->label;
1107 $this->type = $obj->type;
1108 $this->courant = $obj->type;
1109 $this->bank = $obj->bank;
1110 $this->clos = $obj->status;
1111 $this->status = $obj->status;
1112 $this->rappro = $obj->rappro;
1113 $this->url = $obj->url;
1114
1115 $this->code_banque = $obj->code_banque;
1116 $this->code_guichet = $obj->code_guichet;
1117 $this->number = $obj->number;
1118 $this->cle_rib = $obj->cle_rib;
1119 $this->bic = $obj->bic;
1120 $this->iban = $obj->iban;
1121 $this->domiciliation = $obj->address;
1122 $this->address = $obj->address;
1123 $this->pti_in_ctti = $obj->pti_in_ctti;
1124 $this->proprio = $obj->owner_name;
1125 $this->owner_name = $obj->owner_name;
1126 $this->owner_address = $obj->owner_address;
1127 $this->owner_zip = $obj->owner_zip;
1128 $this->owner_town = $obj->owner_town;
1129 $this->owner_country_id = $obj->owner_country_id;
1130
1131 $this->state_id = $obj->state_id;
1132 $this->state_code = $obj->state_code;
1133 $this->state = $obj->state;
1134
1135 $this->country_id = $obj->country_id;
1136 $this->country_code = $obj->country_code;
1137 $this->country = $obj->country;
1138
1139 $this->account_number = $obj->account_number;
1140 $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1141 $this->accountancy_journal = $obj->accountancy_journal;
1142
1143 $this->currency_code = $obj->currency_code;
1144 $this->account_currency_code = $obj->currency_code;
1145 $this->min_allowed = $obj->min_allowed;
1146 $this->min_desired = $obj->min_desired;
1147 $this->comment = $obj->comment;
1148
1149 $this->date_creation = $this->db->jdate($obj->date_creation);
1150 $this->date_modification = $this->db->jdate($obj->date_modification);
1151
1152 $this->ics = $obj->ics;
1153 $this->ics_transfer = $obj->ics_transfer;
1154
1155 // Retrieve all extrafield
1156 // fetch optionals attributes and labels
1157 $this->fetch_optionals();
1158
1159 return 1;
1160 } else {
1161 return 0;
1162 }
1163 } else {
1164 $this->error = $this->db->lasterror();
1165 $this->errors[] = $this->error;
1166 return -1;
1167 }
1168 }
1169
1180 public function setCategories($categories)
1181 {
1182 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1183 return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1184 }
1185
1193 public function delete($user = null, $notrigger = 0)
1194 {
1195 $error = 0;
1196
1197 $this->db->begin();
1198
1199 // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1200
1201 // Delete link between tag and bank account
1202 if (!$error) {
1203 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1204 $sql .= " WHERE fk_account = ".((int) $this->id);
1205
1206 $resql = $this->db->query($sql);
1207 if (!$resql) {
1208 $error++;
1209 $this->error = "Error ".$this->db->lasterror();
1210 }
1211 }
1212
1213 if (!$error) {
1214 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1215 $sql .= " WHERE rowid = ".((int) $this->id);
1216
1217 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1218 $result = $this->db->query($sql);
1219 if ($result) {
1220 // Remove extrafields
1221 if (!$error) {
1222 $result = $this->deleteExtraFields();
1223 if ($result < 0) {
1224 $error++;
1225 dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1226 }
1227 }
1228 } else {
1229 $error++;
1230 $this->error = "Error ".$this->db->lasterror();
1231 }
1232 }
1233
1234 if (!$error) {
1235 $this->db->commit();
1236 return 1;
1237 } else {
1238 $this->db->rollback();
1239 return -1;
1240 }
1241 }
1242
1243
1250 public function getLibStatut($mode = 0)
1251 {
1252 return $this->LibStatut($this->status, $mode);
1253 }
1254
1255 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1263 public function LibStatut($status, $mode = 0)
1264 {
1265 // phpcs:enable
1266 global $langs;
1267 $langs->load('banks');
1268
1269 if ($status == self::STATUS_OPEN) {
1270 $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1271 $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1272 $statusType = 'status4';
1273 } else {
1274 $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1275 $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1276 $statusType = 'status5';
1277 }
1278
1279 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1280 }
1281
1282
1283 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1289 public function can_be_deleted()
1290 {
1291 // phpcs:enable
1292 $can_be_deleted = false;
1293
1294 $sql = "SELECT COUNT(rowid) as nb";
1295 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1296 $sql .= " WHERE fk_account = ".((int) $this->id);
1297
1298 $resql = $this->db->query($sql);
1299 if ($resql) {
1300 $obj = $this->db->fetch_object($resql);
1301 if ($obj->nb <= 1) {
1302 $can_be_deleted = true; // Juste le solde
1303 }
1304 } else {
1305 dol_print_error($this->db);
1306 }
1307 return $can_be_deleted;
1308 }
1309
1310
1316 public function error()
1317 {
1318 return $this->error;
1319 }
1320
1329 public function solde($option = 0, $date_end = '', $field = 'dateo')
1330 {
1331 $solde = 0;
1332
1333 $sql = "SELECT sum(amount) as amount";
1334 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1335 $sql .= " WHERE fk_account = ".((int) $this->id);
1336 if ($option == 1) {
1337 $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1338 }
1339
1340 $resql = $this->db->query($sql);
1341 if ($resql) {
1342 if ($this->db->num_rows($resql)) {
1343 $obj = $this->db->fetch_object($resql);
1344 $solde = $obj->amount;
1345 }
1346 $this->db->free($resql);
1347 } else {
1348 $this->errors[] = $this->db->lasterror;
1349 return -1;
1350 }
1351
1352 return (float) price2num($solde, 'MU');
1353 }
1354
1355 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1363 public function load_board(User $user, $filteraccountid = 0)
1364 {
1365 // phpcs:enable
1366 global $conf, $langs;
1367
1368 if ($user->socid) {
1369 return -1; // protection pour eviter appel par utilisateur externe
1370 }
1371
1372 $sql = "SELECT b.rowid, b.datev as datefin";
1373 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1374 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1375 $sql .= " WHERE b.rappro=0";
1376 $sql .= " AND b.fk_account = ba.rowid";
1377 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1378 $sql .= " AND (ba.rappro = 1 AND ba.courant != " . Account::TYPE_CASH . ")"; // Compte rapprochable
1379 $sql .= " AND clos = 0";
1380 if ($filteraccountid) {
1381 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1382 }
1383
1384 $resql = $this->db->query($sql);
1385 if ($resql) {
1386 $langs->load("banks");
1387 $now = dol_now();
1388
1389 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1390
1391 $response = new WorkboardResponse();
1392 $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1393 $response->label = $langs->trans("TransactionsToConciliate");
1394 $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1395 $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1396 $response->img = img_object('', "payment");
1397
1398 while ($obj = $this->db->fetch_object($resql)) {
1399 $response->nbtodo++;
1400 if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1401 $response->nbtodolate++;
1402 }
1403 }
1404
1405 return $response;
1406 } else {
1407 dol_print_error($this->db);
1408 $this->error = $this->db->error();
1409 return -1;
1410 }
1411 }
1412
1419 public function loadStateBoard($filteraccountid = 0)
1420 {
1421 global $user;
1422
1423 if ($user->socid) {
1424 return -1; // protection pour eviter appel par utilisateur externe
1425 }
1426
1427 $sql = "SELECT count(b.rowid) as nb";
1428 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1429 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1430 $sql .= " WHERE b.fk_account = ba.rowid";
1431 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1432 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1433 $sql .= " AND clos = 0";
1434 if ($filteraccountid) {
1435 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1436 }
1437
1438 $resql = $this->db->query($sql);
1439 if ($resql) {
1440 while ($obj = $this->db->fetch_object($resql)) {
1441 $this->nb["banklines"] = $obj->nb;
1442 }
1443 $this->db->free($resql);
1444 return 1;
1445 } else {
1446 dol_print_error($this->db);
1447 $this->error = $this->db->error();
1448 return -1;
1449 }
1450 }
1451
1452
1458 public function countAccountToReconcile()
1459 {
1460 global $user;
1461
1462 //Protection against external users
1463 if ($user->socid) {
1464 return 0;
1465 }
1466
1467 $nb = 0;
1468
1469 $sql = "SELECT COUNT(ba.rowid) as nb";
1470 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1471 $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1472 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1473 if (!getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
1474 $sql .= " AND ba.courant != " . Account::TYPE_CASH;
1475 }
1476
1477 $resql = $this->db->query($sql);
1478 if ($resql) {
1479 $obj = $this->db->fetch_object($resql);
1480 $nb = $obj->nb;
1481 } else {
1482 dol_print_error($this->db);
1483 }
1484
1485 return $nb;
1486 }
1487
1494 public function getTooltipContentArray($params)
1495 {
1496 global $langs;
1497 $langs->loadLangs(['banks', 'compta']);
1498 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1499
1500 $datas = array();
1501
1502 $nofetch = !empty($params['nofetch']);
1503 $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1504 if (isset($this->status)) {
1505 $pictos .= ' '.$this->getLibStatut(5);
1506 }
1507 $datas['picto'] = $pictos;
1508 $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1509 $datas['accountnumber'] = '<br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1510 $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1511 $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1512 $datas['accountcurrency'] = '<br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1513
1514 if (isModEnabled('accounting')) {
1515 include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1516 $langs->load("accountancy");
1517 $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1518 $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1519 }
1520 // show categories for this record only in ajax to not overload lists
1521 if (isModEnabled('category') && !$nofetch) {
1522 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1523 $form = new Form($this->db);
1524 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1525 }
1526
1527 return $datas;
1528 }
1529
1541 public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1542 {
1543 global $conf, $langs;
1544
1545 if (!empty($conf->dol_no_mouse_hover)) {
1546 $notooltip = 1; // Force disable tooltips
1547 }
1548
1549 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1550
1551 $result = '';
1552 $classfortooltip = 'classfortooltip';
1553 $dataparams = '';
1554 $params = [
1555 'id' => $this->id,
1556 'objecttype' => $this->element,
1557 'option' => $option,
1558 'nofetch' => 1,
1559 ];
1560 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1561 $classfortooltip = 'classforajaxtooltip';
1562 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1563 $label = '';
1564 } else {
1565 $label = implode($this->getTooltipContentArray($params));
1566 }
1567
1568 $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1569 if ($mode == 'transactions') {
1570 $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1571 } elseif ($mode == 'receipts') {
1572 $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1573 }
1574
1575 if ($option != 'nolink') {
1576 // Add param to save lastsearch_values or not
1577 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1578 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1579 $add_save_lastsearch_values = 1;
1580 }
1581 if ($add_save_lastsearch_values) {
1582 $url .= '&save_lastsearch_values=1';
1583 }
1584 }
1585
1586 $linkclose = '';
1587 if (empty($notooltip)) {
1588 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1589 $label = $langs->trans("BankAccount");
1590 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1591 }
1592 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1593 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1594 } else {
1595 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1596 }
1597
1598 if ($option == 'nolink' || empty($url)) {
1599 $linkstart = '<span';
1600 } else {
1601 $linkstart = '<a href="'.$url.'"';
1602 }
1603 $linkstart .= $linkclose.'>';
1604 if ($option == 'nolink' || empty($url)) {
1605 $linkend = '</span>';
1606 } else {
1607 $linkend = '</a>';
1608 }
1609
1610 $result .= $linkstart;
1611
1612 if ($withpicto) {
1613 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1614 }
1615 if ($withpicto != 2) {
1616 $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1617 }
1618 $result .= $linkend;
1619
1620 return $result;
1621 }
1622
1623
1624 // Method after here are common to Account and CompanyBankAccount
1625
1626
1632 public function verif()
1633 {
1634 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1635
1636 $error = 0;
1637
1638 // Call functions to check BAN
1639 if (!checkIbanForAccount($this)) {
1640 $error++;
1641 $this->error = 'IBANNotValid';
1642 }
1643 // Call function to check Swift/BIC.
1644 // A non valid BIC/Swift is a problem if: it is not empty or always a problem if WITHDRAWAL_WITHOUT_BIC is not set).
1645 if (!checkSwiftForAccount($this) && (!empty($this->bic) || !getDolGlobalInt('WITHDRAWAL_WITHOUT_BIC'))) {
1646 $error++;
1647 $this->error = 'SwiftNotValid';
1648 }
1649
1650 if (! $error) {
1651 return 1;
1652 } else {
1653 return 0;
1654 }
1655 }
1656
1662 public function getCountryCode()
1663 {
1664 global $mysoc;
1665
1666 // We return country code of bank account
1667 if (!empty($this->country_code)) {
1668 return $this->country_code;
1669 }
1670
1671 // For backward compatibility, we try to guess country from other information
1672 if (!empty($this->iban)) {
1673 // If IBAN defined, we can know country of account from it
1674 $reg = array();
1675 if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1676 return $reg[1];
1677 }
1678 }
1679
1680 // If this class is linked to a third party
1681 if (!empty($this->socid)) {
1682 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1683 $company = new Societe($this->db);
1684 $result = $company->fetch($this->socid);
1685 if (!empty($company->country_code)) {
1686 return $company->country_code;
1687 }
1688 }
1689
1690 // We return country code of managed company
1691 if (!empty($mysoc->country_code)) {
1692 return $mysoc->country_code;
1693 }
1694
1695 return '';
1696 }
1697
1705 public function getBannerAddress($htmlkey, $object)
1706 {
1707 global $conf, $langs;
1708
1709 $out = '';
1710
1711 $outdone = 0;
1712 $coords = $this->getFullAddress(1, ', ', getDolGlobalInt('MAIN_SHOW_REGION_IN_STATE_SELECT'));
1713 if ($coords) {
1714 if (!empty($conf->use_javascript_ajax)) {
1715 // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
1716 $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
1717 $out .= img_picto($langs->trans("Address"), 'map-marker-alt');
1718 $out .= '</a> ';
1719 }
1720 $address = dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
1721 if ($address) {
1722 $out .= $address;
1723 $outdone++;
1724 }
1725 $outdone++;
1726 }
1727
1728 return $out;
1729 }
1730
1731
1740 public function useDetailedBBAN()
1741 {
1742 $country_code = $this->getCountryCode();
1743
1744 if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1745 return 1; // France, Spain, Gabon, ... - Not valid for CH
1746 }
1747 if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1748 return 2; // Australia, England...
1749 }
1750 return 0;
1751 }
1752
1758 public function needIBAN()
1759 {
1760 global $conf;
1761
1762 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1763 return 0;
1764 }
1765
1766 $country_code = $this->getCountryCode();
1767
1768 $country_code_in_EEC = array(
1769 'AT', // Austria
1770 'BE', // Belgium
1771 'BG', // Bulgaria
1772 'CY', // Cyprus
1773 'CZ', // Czech republic
1774 'DE', // Germany
1775 'DK', // Danemark
1776 'EE', // Estonia
1777 'ES', // Spain
1778 'FI', // Finland
1779 'FR', // France
1780 'GB', // United Kingdom
1781 'GR', // Greece
1782 'HR', // Croatia
1783 'NL', // Holland
1784 'HU', // Hungary
1785 'IE', // Ireland
1786 'IM', // Isle of Man - Included in UK
1787 'IT', // Italy
1788 'LT', // Lithuania
1789 'LU', // Luxembourg
1790 'LV', // Latvia
1791 'MC', // Monaco - Included in France
1792 'MT', // Malta
1793 //'NO', // Norway
1794 'PL', // Poland
1795 'PT', // Portugal
1796 'RO', // Romania
1797 'SE', // Sweden
1798 'SK', // Slovakia
1799 'SI', // Slovenia
1800 'UK', // United Kingdom
1801 //'CH', // Switzerland - No. Swizerland in not in EEC
1802 );
1803
1804 if (in_array($country_code, $country_code_in_EEC)) {
1805 return 1; // France, Spain, ...
1806 }
1807 return 0;
1808 }
1809
1815 public function needBIC()
1816 {
1817 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1818 return 0;
1819 }
1820
1821 $country_code = $this->getCountryCode();
1822
1823 $country_code_in_EEC = array(
1824 'AD', // Andorra
1825 'BH', // Bahrein
1826 'DK', // Denmark
1827 'FR', // France
1828 'GH', // Ghana
1829 'HU', // Hungary
1830 'JP', // Japan
1831 'LV', // Latvia
1832 'SE', // Sweden
1833 );
1834
1835 if (in_array($country_code, $country_code_in_EEC)) {
1836 return 1; // Andorra, Bahrein, ...
1837 }
1838 return 0;
1839 }
1840
1847 public function info($id)
1848 {
1849 }
1850
1865 public function getFieldsToShow($includeibanbic = 0)
1866 {
1867 //Get the required properties depending on the country
1868 $detailedBBAN = $this->useDetailedBBAN();
1869
1870 if ($detailedBBAN == 0) {
1871 $fieldarray = array(
1872 'BankAccountNumber'
1873 );
1874 } elseif ($detailedBBAN == 2) {
1875 $fieldarray = array(
1876 'BankCode',
1877 'BankAccountNumber'
1878 );
1879 } else {
1880 $fieldarray = self::getAccountNumberOrder();
1881 }
1882
1883 //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1884 if ($includeibanbic) {
1885 $fieldarray[] = 'IBAN';
1886 $fieldarray[] = 'BIC';
1887 }
1888 //}
1889
1890 //Get the order the properties are shown
1891 return $fieldarray;
1892 }
1893
1904 public static function getAccountNumberOrder()
1905 {
1906 global $conf;
1907
1908 $fieldlists = array(
1909 'BankCode',
1910 'DeskCode',
1911 'BankAccountNumber',
1912 'BankAccountNumberKey'
1913 );
1914
1915 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION')) {
1916 if (is_numeric(getDolGlobalString('BANK_SHOW_ORDER_OPTION'))) {
1917 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION') == '1') {
1918 $fieldlists = array(
1919 'BankCode',
1920 'DeskCode',
1921 'BankAccountNumberKey',
1922 'BankAccountNumber'
1923 );
1924 }
1925 } else {
1926 //Replace the old AccountNumber key with the new BankAccountNumber key
1927 $fieldlists = explode(
1928 ' ',
1929 preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1930 );
1931 }
1932 }
1933
1934 return $fieldlists;
1935 }
1936
1937
1945 public function initAsSpecimen()
1946 {
1947 // Example of IBAN FR7630001007941234567890185
1948 $this->specimen = 1;
1949 $this->ref = 'MBA';
1950 $this->label = 'My Big Company Bank account';
1951 $this->courant = Account::TYPE_CURRENT;
1952 $this->clos = Account::STATUS_OPEN;
1953 $this->type = Account::TYPE_CURRENT;
1954 $this->status = Account::STATUS_OPEN;
1955 $this->code_banque = '30001';
1956 $this->code_guichet = '00794';
1957 $this->number = '12345678901';
1958 $this->cle_rib = '85';
1959 $this->bic = 'AA12';
1960 $this->iban = 'FR7630001007941234567890185';
1961
1962 $this->bank = 'MyBank';
1963 $this->address = 'Rue de Paris';
1964 $this->proprio = 'Owner';
1965 $this->owner_name = 'Owner';
1966 $this->owner_address = 'Owner address';
1967 $this->owner_zip = 'Owner zip';
1968 $this->owner_town = 'Owner town';
1969 $this->owner_country_id = 'Owner country_id';
1970 $this->country_id = 1;
1971
1972 return 1;
1973 }
1974
1983 public static function replaceThirdparty($dbs, $origin_id, $dest_id)
1984 {
1985 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'";
1986
1987 if ($dbs->query($sql)) {
1988 return true;
1989 } else {
1990 //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.
1991 //$this->errors = $dbs->lasterror();
1992 return false;
1993 }
1994 }
1995
2003 public function getKanbanView($option = '', $arraydata = null)
2004 {
2005 global $langs;
2006
2007 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2008
2009 $return = '<div class="box-flex-item box-flex-grow-zero">';
2010 $return .= '<div class="info-box info-box-sm">';
2011 $return .= '<span class="info-box-icon bg-infobox-action">';
2012 $return .= img_picto('', $this->picto);
2013 $return .= '</span>';
2014 $return .= '<div class="info-box-content">';
2015 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
2016 if ($selected >= 0) {
2017 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2018 }
2019 if (property_exists($this, 'type_lib')) {
2020 $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
2021 }
2022 if (method_exists($this, 'solde')) {
2023 $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
2024 $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>';
2025 }
2026 if (method_exists($this, 'getLibStatut')) {
2027 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2028 }
2029 $return .= '</div>';
2030 $return .= '</div>';
2031 $return .= '</div>';
2032 return $return;
2033 }
2034}
2035
2036
2037require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
2038
2042class AccountLine extends CommonObjectLine
2043{
2047 public $db;
2048
2052 public $element = 'bank';
2053
2057 public $table_element = 'bank';
2058
2062 public $picto = 'accountline';
2063
2067 public $id;
2068
2072 public $ref;
2073
2079 public $datec;
2080
2086 public $dateo;
2087
2093 public $datev;
2094
2098 public $amount;
2099
2103 public $amount_main_currency;
2104
2108 public $fk_user_author;
2109
2113 public $fk_user_rappro;
2114
2118 public $fk_type;
2119
2123 public $fk_bordereau;
2124
2128 public $fk_account;
2129
2133 public $bank_account_ref;
2134
2138 public $bank_account_label;
2139
2143 public $numero_compte;
2144
2148 public $emetteur;
2149
2153 public $rappro;
2154
2158 public $num_releve;
2159
2163 public $num_chq;
2164
2168 public $bank_chq;
2169
2173 public $label;
2174
2178 public $note;
2179
2184 public $user_rappro;
2185
2186
2192 public function __construct(DoliDB $db)
2193 {
2194 $this->db = $db;
2195 }
2196
2205 public function fetch($rowid, $ref = '', $num = '')
2206 {
2207 // Check parameters
2208 if (empty($rowid) && empty($ref) && empty($num)) {
2209 return -1;
2210 }
2211
2212 $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2213 $sql .= " b.fk_user_author, b.fk_user_rappro,";
2214 $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2215 $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2216 $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2217 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2218 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2219 $sql .= " WHERE b.fk_account = ba.rowid";
2220 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2221 if ($num) {
2222 $sql .= " AND b.num_chq = '".$this->db->escape($num)."'";
2223 } elseif ($ref) {
2224 $sql .= " AND b.rowid = '".$this->db->escape($ref)."'";
2225 } else {
2226 $sql .= " AND b.rowid = ".((int) $rowid);
2227 }
2228
2229 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2230 $result = $this->db->query($sql);
2231 if ($result) {
2232 $ret = 0;
2233
2234 $obj = $this->db->fetch_object($result);
2235 if ($obj) {
2236 $this->id = $obj->rowid;
2237 $this->rowid = $obj->rowid;
2238 $this->ref = $obj->rowid;
2239
2240 $this->datec = $this->db->jdate($obj->datec);
2241 $this->datev = $this->db->jdate($obj->datev);
2242 $this->dateo = $this->db->jdate($obj->dateo);
2243 $this->amount = $obj->amount;
2244 $this->label = $obj->label;
2245 $this->note = $obj->note;
2246
2247 $this->fk_user_author = $obj->fk_user_author;
2248 $this->fk_user_rappro = $obj->fk_user_rappro;
2249
2250 $this->fk_type = $obj->fk_type; // Type of transaction
2251 $this->rappro = (int) $obj->rappro;
2252 $this->num_releve = $obj->num_releve;
2253
2254 $this->num_chq = $obj->num_chq;
2255 $this->bank_chq = $obj->banque;
2256 $this->fk_bordereau = $obj->fk_bordereau;
2257
2258 $this->fk_account = $obj->fk_account;
2259 $this->bank_account_ref = $obj->bank_account_ref;
2260 $this->bank_account_label = $obj->bank_account_label;
2261
2262 // Retrieve all extrafield
2263 // fetch optionals attributes and labels
2264 $this->fetch_optionals();
2265
2266 $ret = 1;
2267 }
2268 $this->db->free($result);
2269 return $ret;
2270 } else {
2271 return -1;
2272 }
2273 }
2274
2280 public function insert()
2281 {
2282 $error = 0;
2283
2284 $this->db->begin();
2285
2286 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2287 $sql .= "datec";
2288 $sql .= ", dateo";
2289 $sql .= ", datev";
2290 $sql .= ", label";
2291 $sql .= ", amount";
2292 $sql .= ", amount_main_currency";
2293 $sql .= ", fk_user_author";
2294 $sql .= ", num_chq";
2295 $sql .= ", fk_account";
2296 $sql .= ", fk_type";
2297 $sql .= ", emetteur,banque";
2298 $sql .= ", rappro";
2299 $sql .= ", numero_compte";
2300 $sql .= ", num_releve";
2301 $sql .= ") VALUES (";
2302 $sql .= "'".$this->db->idate($this->datec)."'";
2303 $sql .= ", '".$this->db->idate($this->dateo)."'";
2304 $sql .= ", '".$this->db->idate($this->datev)."'";
2305 $sql .= ", '".$this->db->escape($this->label)."'";
2306 $sql .= ", ".price2num($this->amount);
2307 $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2308 $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2309 $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2310 $sql .= ", '".$this->db->escape($this->fk_account)."'";
2311 $sql .= ", '".$this->db->escape($this->fk_type)."'";
2312 $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2313 $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2314 $sql .= ", ".(int) $this->rappro;
2315 $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2316 $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2317 $sql .= ")";
2318
2319
2320 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2321 $resql = $this->db->query($sql);
2322 if ($resql) {
2323 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2324 // Actions on extra fields (by external module or standard code)
2325 $result = $this->insertExtraFields();
2326 if ($result < 0) {
2327 $error++;
2328 }
2329 } else {
2330 $error++;
2331 $this->error = $this->db->lasterror();
2332 dol_print_error($this->db);
2333 }
2334
2335 if (!$error) {
2336 $this->db->commit();
2337 return $this->id;
2338 } else {
2339 $this->db->rollback();
2340 return -1 * $error;
2341 }
2342 }
2343
2351 public function delete($user = null, $notrigger = 0)
2352 {
2353 $nbko = 0;
2354
2355 if ($this->rappro) {
2356 // Protection to avoid any delete of consolidated lines
2357 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2358 return -1;
2359 }
2360
2361 $this->db->begin();
2362
2363 if (!$notrigger) {
2364 // Call trigger
2365 $result = $this->call_trigger('BANKACCOUNTLINE_DELETE', $user);
2366 if ($result < 0) {
2367 $this->db->rollback();
2368 return -1;
2369 }
2370 // End call triggers
2371 }
2372
2373 // Protection to avoid any delete of accounted lines. Protection on by default
2374 if (!getDolGlobalString('BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING')) {
2375 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2376 $resql = $this->db->query($sql);
2377 if ($resql) {
2378 $obj = $this->db->fetch_object($resql);
2379 if ($obj && $obj->nb) {
2380 $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2381 $this->db->rollback();
2382 return -1;
2383 }
2384 } else {
2385 $this->error = $this->db->lasterror();
2386 $this->db->rollback();
2387 return -1;
2388 }
2389 }
2390
2391 // Delete urls
2392 $result = $this->delete_urls($user);
2393 if ($result < 0) {
2394 $nbko++;
2395 }
2396
2397 $sql = "DELETE FROM ".MAIN_DB_PREFIX."category_bankline WHERE lineid=".(int) $this->rowid;
2398 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2399 $result = $this->db->query($sql);
2400 if (!$result) {
2401 $nbko++;
2402 }
2403
2404 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2405 $result = $this->db->query($sql);
2406 if (!$result) {
2407 $nbko++;
2408 }
2409
2410 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2411 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2412 $result = $this->db->query($sql);
2413 if (!$result) {
2414 $nbko++;
2415 }
2416
2417 if (!$nbko) {
2418 $this->db->commit();
2419 return 1;
2420 } else {
2421 $this->db->rollback();
2422 return -$nbko;
2423 }
2424 }
2425
2426
2427 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2434 public function delete_urls($user = null)
2435 {
2436 // phpcs:enable
2437 $nbko = 0;
2438
2439 if ($this->rappro) {
2440 // Protection to avoid any delete of consolidated lines
2441 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2442 return -1;
2443 }
2444
2445 $this->db->begin();
2446
2447 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2448 dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2449 $result = $this->db->query($sql);
2450 if (!$result) {
2451 $nbko++;
2452 }
2453
2454 if (!$nbko) {
2455 $this->db->commit();
2456 return 1;
2457 } else {
2458 $this->db->rollback();
2459 return -$nbko;
2460 }
2461 }
2462
2463
2471 public function update(User $user, $notrigger = 0)
2472 {
2473 $this->db->begin();
2474
2475 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2476 $sql .= " amount = ".price2num($this->amount).",";
2477 $sql .= " datev='".$this->db->idate($this->datev)."',";
2478 $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2479 $sql .= " WHERE rowid = ".((int) $this->rowid);
2480
2481 dol_syslog(get_class($this)."::update", LOG_DEBUG);
2482 $resql = $this->db->query($sql);
2483 if ($resql) {
2484 $this->db->commit();
2485 return 1;
2486 } else {
2487 $this->db->rollback();
2488 $this->error = $this->db->error();
2489 return -1;
2490 }
2491 }
2492
2493
2499 public function updateLabel()
2500 {
2501 $this->db->begin();
2502
2503 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2504 $sql .= " label = '".$this->db->escape($this->label)."'";
2505 $sql .= " WHERE rowid = ".((int) $this->rowid);
2506
2507 dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
2508 $resql = $this->db->query($sql);
2509 if ($resql) {
2510 $this->db->commit();
2511 return 1;
2512 } else {
2513 $this->db->rollback();
2514 $this->error = $this->db->error();
2515 return -1;
2516 }
2517 }
2518
2519
2520 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2529 public function update_conciliation(User $user, $cat, $conciliated = 1)
2530 {
2531 // phpcs:enable
2532 global $conf, $langs;
2533
2534 $this->db->begin();
2535
2536 // Check statement field
2537 if (getDolGlobalString('BANK_STATEMENT_REGEX_RULE')) {
2538 if (!preg_match('/' . getDolGlobalString('BANK_STATEMENT_REGEX_RULE').'/', $this->num_releve)) {
2539 $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", getDolGlobalString('BANK_STATEMENT_REGEX_RULE'));
2540 return -1;
2541 }
2542 }
2543
2544 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2545 $sql .= " rappro = ".((int) $conciliated);
2546 $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2547 if ($conciliated) {
2548 $sql .= ", fk_user_rappro = ".$user->id;
2549 }
2550 $sql .= " WHERE rowid = ".((int) $this->id);
2551
2552 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2553 $resql = $this->db->query($sql);
2554 if ($resql) {
2555 if (!empty($cat) && $cat > 0) {
2556 $sql = "INSERT INTO ".MAIN_DB_PREFIX."category_bankline (";
2557 $sql .= "lineid";
2558 $sql .= ", fk_categ";
2559 $sql .= ") VALUES (";
2560 $sql .= $this->id;
2561 $sql .= ", ".((int) $cat);
2562 $sql .= ")";
2563
2564 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2565 $this->db->query($sql);
2566
2567 // No error check. Can fail if category already affected
2568 // TODO Do no try the insert if link already exists
2569 }
2570
2571 $this->rappro = (int) $conciliated;
2572
2573 $this->db->commit();
2574 return 1;
2575 } else {
2576 $this->db->rollback();
2577 return -1;
2578 }
2579 }
2580
2581
2582 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2590 public function datev_change($rowid, $sign = 1)
2591 {
2592 // phpcs:enable
2593 $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2594 $resql = $this->db->query($sql);
2595 if ($resql) {
2596 $obj = $this->db->fetch_object($resql);
2597 $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2598
2599 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2600 $sql .= " datev = '".$this->db->idate($newdate)."'";
2601 $sql .= " WHERE rowid = ".((int) $rowid);
2602
2603 $result = $this->db->query($sql);
2604 if ($result) {
2605 if ($this->db->affected_rows($result)) {
2606 return 1;
2607 }
2608 } else {
2609 dol_print_error($this->db);
2610 return 0;
2611 }
2612 } else {
2613 dol_print_error($this->db);
2614 }
2615 return 0;
2616 }
2617
2618 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2625 public function datev_next($id)
2626 {
2627 // phpcs:enable
2628 return $this->datev_change($id, 1);
2629 }
2630
2631 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2638 public function datev_previous($id)
2639 {
2640 // phpcs:enable
2641 return $this->datev_change($id, -1);
2642 }
2643
2644
2645 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2653 public function dateo_change($rowid, $sign = 1)
2654 {
2655 // phpcs:enable
2656 $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2657 $resql = $this->db->query($sql);
2658 if ($resql) {
2659 $obj = $this->db->fetch_object($resql);
2660 $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2661
2662 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2663 $sql .= " dateo = '".$this->db->idate($newdate)."'";
2664 $sql .= " WHERE rowid = ".((int) $rowid);
2665
2666 $result = $this->db->query($sql);
2667 if ($result) {
2668 if ($this->db->affected_rows($result)) {
2669 return 1;
2670 }
2671 } else {
2672 dol_print_error($this->db);
2673 return 0;
2674 }
2675 } else {
2676 dol_print_error($this->db);
2677 }
2678 return 0;
2679 }
2680
2681 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2688 public function dateo_next($id)
2689 {
2690 // phpcs:enable
2691 return $this->dateo_change($id, 1);
2692 }
2693
2694 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2701 public function dateo_previous($id)
2702 {
2703 // phpcs:enable
2704 return $this->dateo_change($id, -1);
2705 }
2706
2707
2714 public function info($id)
2715 {
2716 $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2717 $sql .= ' b.fk_user_author, b.fk_user_rappro';
2718 $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2719 $sql .= ' WHERE b.rowid = '.((int) $id);
2720
2721 $result = $this->db->query($sql);
2722 if ($result) {
2723 if ($this->db->num_rows($result)) {
2724 $obj = $this->db->fetch_object($result);
2725
2726 $this->id = $obj->rowid;
2727
2728 $this->user_creation_id = $obj->fk_user_author;
2729 $this->user_rappro = $obj->fk_user_rappro;
2730 $this->date_creation = $this->db->jdate($obj->datec);
2731 $this->date_modification = $this->db->jdate($obj->datem);
2732 //$this->date_rappro = $obj->daterappro; // Not yet managed
2733 }
2734 $this->db->free($result);
2735 } else {
2736 dol_print_error($this->db);
2737 }
2738 }
2739
2740
2750 public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2751 {
2752 global $conf, $langs;
2753
2754 $result = '';
2755
2756 $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2757 $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2758 if ($this->amount) {
2759 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2760 }
2761
2762 $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">';
2763 $linkend = '</a>';
2764
2765 $result .= $linkstart;
2766 if ($withpicto) {
2767 $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);
2768 }
2769 if ($withpicto != 2) {
2770 $result .= ($this->ref ? $this->ref : $this->id);
2771 }
2772
2773 $result .= $linkend;
2774
2775 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2776 $result .= ' <span class="opacitymedium">(';
2777 }
2778 if ($option == 'showall') {
2779 $result .= $langs->trans("BankAccount").': ';
2780 $accountstatic = new Account($this->db);
2781 $accountstatic->id = $this->fk_account;
2782 $accountstatic->ref = $this->bank_account_ref;
2783 $accountstatic->label = $this->bank_account_label;
2784 $result .= $accountstatic->getNomUrl(0).', ';
2785 }
2786 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2787 $result .= $langs->trans("BankLineConciliated").': ';
2788 $result .= yn($this->rappro);
2789 }
2790 if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2791 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2792 $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2793 $resql = $this->db->query($sql);
2794 if ($resql) {
2795 $obj = $this->db->fetch_object($resql);
2796 if ($obj && $obj->nb) {
2797 $result .= ' - '.$langs->trans("Accounted").': '.yn(1);
2798 } else {
2799 $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2800 }
2801 }
2802 }
2803 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2804 $result .= ')</span>';
2805 }
2806
2807 return $result;
2808 }
2809
2810
2817 public function getLibStatut($mode = 0)
2818 {
2819 return $this->LibStatut($this->status, $mode);
2820 }
2821
2822 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2830 public function LibStatut($status, $mode = 0)
2831 {
2832 // phpcs:enable
2833 return '';
2834 }
2835
2841 public function getVentilExportCompta()
2842 {
2843 $alreadydispatched = 0;
2844
2845 $type = 'bank';
2846
2847 $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);
2848 $resql = $this->db->query($sql);
2849 if ($resql) {
2850 $obj = $this->db->fetch_object($resql);
2851 if ($obj) {
2852 $alreadydispatched = $obj->nb;
2853 }
2854 } else {
2855 $this->error = $this->db->lasterror();
2856 return -1;
2857 }
2858
2859 if ($alreadydispatched) {
2860 return 1;
2861 }
2862 return 0;
2863 }
2864}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:640
checkIbanForAccount($account=null, $ibantocheck=null)
Check IBAN number information for a bank account.
Definition bank.lib.php:305
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition bank.lib.php:330
checkSwiftForAccount($account=null, $swift=null)
Check SWIFT information for a bank account.
Definition bank.lib.php:284
$object ref
Definition info.php:79
Class to manage bank accounts.
solde($option=0, $date_end='', $field='dateo')
Return current balance.
fetch($id, $ref='')
Load a bank account into memory from database.
__construct(DoliDB $db)
Constructor.
getNomUrl($withpicto=0, $mode='', $option='', $save_lastsearch_value=-1, $notooltip=0, $morecss='')
Return 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.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_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.
table table fiche title col title div col center btnTitle icon
Automatically calls the icon named with the corresponding "object_" prefix.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
div refaddress div address
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:137
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e rowid
Definition invoice.php:2002