dolibarr 20.0.5
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 // Avoid uk_bank_url collision when the same target (line_id, url_id, type) is linked twice
489 // e.g. two distinct credit transfers for the same employee dispatched on the same bank line.
490 $sqlcheck = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank_url";
491 $sqlcheck .= " WHERE fk_bank = ".((int) $line_id);
492 $sqlcheck .= " AND url_id = ".((int) $url_id);
493 $sqlcheck .= " AND type = '".$this->db->escape($type)."'";
494 $resqlcheck = $this->db->query($sqlcheck);
495 if ($resqlcheck) {
496 $obj = $this->db->fetch_object($resqlcheck);
497 if ($obj) {
498 $this->db->free($resqlcheck);
499 return (int) $obj->rowid;
500 }
501 $this->db->free($resqlcheck);
502 }
503
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 // Anciens liens (pour compatibilite)
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 // Nouveaux liens
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
603 public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
604 {
605 global $langs;
606
607 // Deprecation warning
608 if (is_numeric($oper)) {
609 dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
610 }
611
612 if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
613 $this->id = $this->rowid;
614 }
615
616 // Clean parameters
617 $emetteur = trim($emetteur);
618 $banque = trim($banque);
619 $label = trim($label);
620
621 $now = dol_now();
622
623 if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
624 $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
625 $sql .= " WHERE id = ".((int) $oper);
626 $sql .= " AND entity IN (".getEntity('c_paiement').")";
627 $resql = $this->db->query($sql);
628 if ($resql) {
629 $obj = $this->db->fetch_object($resql);
630 $oper = $obj->code;
631 } else {
632 dol_print_error($this->db, 'Failed to get payment type code');
633 return -1;
634 }
635 }
636
637 // Check parameters
638 if (!$oper) {
639 $this->error = $langs->trans("OperNotDefined");
640 return -1;
641 }
642 if (!$this->id) {
643 $this->error = $langs->trans("ThisIdNotDefined");
644 return -2;
645 }
646 if ($this->type == Account::TYPE_CASH && $oper != 'LIQ') {
647 $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
648 return -3;
649 }
650
651 $this->db->begin();
652
653 if (is_null($datev) || empty($datev)) {
654 $datev = $date;
655 }
656
657 $accline = new AccountLine($this->db);
658 $accline->datec = $now;
659 $accline->dateo = $date;
660 $accline->datev = $datev;
661 $accline->label = $label;
662 $accline->amount = $amount;
663 $accline->amount_main_currency = $amount_main_currency;
664 $accline->fk_user_author = $user->id;
665 $accline->fk_account = $this->id;
666 $accline->fk_type = $oper;
667 $accline->numero_compte = $accountancycode;
668 $accline->num_releve = $num_releve;
669
670 if ($num_chq) {
671 $accline->num_chq = $num_chq;
672 }
673
674 if ($emetteur) {
675 $accline->emetteur = $emetteur;
676 }
677
678 if ($banque) {
679 $accline->bank_chq = $banque;
680 }
681
682 if ($accline->insert() > 0) {
683 if ($categorie > 0) {
684 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class(";
685 $sql .= "lineid, fk_categ";
686 $sql .= ") VALUES (";
687 $sql .= ((int) $accline->id).", '".$this->db->escape($categorie)."'";
688 $sql .= ")";
689
690 $result = $this->db->query($sql);
691 if (!$result) {
692 $this->error = $this->db->lasterror();
693 $this->db->rollback();
694
695 return -4;
696 }
697 }
698
699 $this->db->commit();
700
701 return $accline->id;
702 } else {
703 $this->setErrorsFromObject($accline);
704 $this->db->rollback();
705
706 return -5;
707 }
708 }
709
717 public function create(User $user, $notrigger = 0)
718 {
719 global $langs, $conf;
720
721 $error = 0;
722
723 // Clean parameters
724 if (!$this->min_allowed) {
725 $this->min_allowed = 0;
726 }
727 if (!$this->min_desired) {
728 $this->min_desired = 0;
729 }
730
731 // Check parameters
732 if (empty($this->country_id)) {
733 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
734 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
735 return -1;
736 }
737 if (empty($this->ref)) {
738 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
739 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
740 return -1;
741 }
742 if (empty($this->date_solde)) {
743 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
744 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
745 return -1;
746 }
747
748 // Load libraries to check BAN
749 $balance = $this->balance;
750 if (empty($balance) && !empty($this->solde)) {
751 $balance = $this->solde;
752 }
753 if (empty($balance)) {
754 $balance = 0;
755 }
756 if (empty($this->address && !empty($this->domiciliation))) {
757 dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE);
758 $this->address = $this->domiciliation;
759 }
760 if (empty($this->status && !empty($this->clos))) {
761 dol_syslog(get_class($this)."::create clos is deprecated use status", LOG_NOTICE);
762 $this->status = $this->clos;
763 }
764
765 if (empty($this->address && !empty($this->domiciliation))) {
766 dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE);
767 $this->address = $this->domiciliation;
768 }
769
770 // Load the library to validate/check a BAN account
771 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
772
773 $now = dol_now();
774
775 $this->db->begin();
776
777 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
778 $sql .= "datec";
779 $sql .= ", ref";
780 $sql .= ", label";
781 $sql .= ", entity";
782 $sql .= ", account_number";
783 $sql .= ", fk_accountancy_journal";
784 $sql .= ", bank";
785 $sql .= ", code_banque";
786 $sql .= ", code_guichet";
787 $sql .= ", number";
788 $sql .= ", cle_rib";
789 $sql .= ", bic";
790 $sql .= ", iban_prefix";
791 $sql .= ", domiciliation";
792 $sql .= ", pti_in_ctti";
793 $sql .= ", proprio";
794 $sql .= ", owner_address";
795 $sql .= ", owner_zip";
796 $sql .= ", owner_town";
797 $sql .= ", owner_country_id";
798 $sql .= ", currency_code";
799 $sql .= ", rappro";
800 $sql .= ", min_allowed";
801 $sql .= ", min_desired";
802 $sql .= ", comment";
803 $sql .= ", state_id";
804 $sql .= ", fk_pays";
805 $sql .= ", ics";
806 $sql .= ", ics_transfer";
807 $sql .= ") VALUES (";
808 $sql .= "'".$this->db->idate($now)."'";
809 $sql .= ", '".$this->db->escape($this->ref)."'";
810 $sql .= ", '".$this->db->escape($this->label)."'";
811 $sql .= ", ".((int) $conf->entity);
812 $sql .= ", '".$this->db->escape($this->account_number)."'";
813 $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
814 $sql .= ", '".$this->db->escape($this->bank)."'";
815 $sql .= ", '".$this->db->escape($this->code_banque)."'";
816 $sql .= ", '".$this->db->escape($this->code_guichet)."'";
817 $sql .= ", '".$this->db->escape($this->number)."'";
818 $sql .= ", '".$this->db->escape($this->cle_rib)."'";
819 $sql .= ", '".$this->db->escape($this->bic)."'";
820 $sql .= ", '".$this->db->escape($this->iban)."'";
821 $sql .= ", '".$this->db->escape($this->address)."'";
822 $sql .= ", ".((int) $this->pti_in_ctti);
823 $sql .= ", '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'";
824 $sql .= ", '".$this->db->escape($this->owner_address)."'";
825 $sql .= ", '".$this->db->escape($this->owner_zip)."'";
826 $sql .= ", '".$this->db->escape($this->owner_town)."'";
827 $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
828 $sql .= ", '".$this->db->escape($this->currency_code)."'";
829 $sql .= ", ".((int) $this->rappro);
830 $sql .= ", ".price2num($this->min_allowed, 'MT');
831 $sql .= ", ".price2num($this->min_desired, 'MT');
832 $sql .= ", '".$this->db->escape($this->comment)."'";
833 $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
834 $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
835 $sql .= ", '".$this->db->escape($this->ics)."'";
836 $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
837 $sql .= ")";
838
839 dol_syslog(get_class($this)."::create", LOG_DEBUG);
840 $resql = $this->db->query($sql);
841 if ($resql) {
842 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
843
844 $result = $this->update($user, 1);
845 if ($result > 0) {
846 $accline = new AccountLine($this->db);
847 $accline->datec = $now;
848 $accline->label = '('.$langs->trans("InitialBankBalance").')';
849 $accline->amount = (float) price2num($balance);
850 $accline->fk_user_author = $user->id;
851 $accline->fk_account = $this->id;
852 $accline->datev = $this->date_solde;
853 $accline->dateo = $this->date_solde;
854 $accline->fk_type = 'SOLD';
855
856 if ($accline->insert() < 0) {
857 $error++;
858 $this->error = $accline->error;
859 $this->errors = $accline->errors;
860 }
861
862 if (!$error) {
863 $result = $this->insertExtraFields();
864 if ($result < 0) {
865 $error++;
866 }
867 }
868
869 if (!$error && !$notrigger) {
870 // Call trigger
871 $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
872 if ($result < 0) {
873 $error++;
874 }
875 // End call triggers
876 }
877 } else {
878 $error++;
879 }
880 } else {
881 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
882 $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
883 $error++;
884 } else {
885 $this->error = $this->db->error()." sql=".$sql;
886 $error++;
887 }
888 }
889
890 if (!$error) {
891 $this->db->commit();
892 return $this->id;
893 } else {
894 $this->db->rollback();
895 return -1 * $error;
896 }
897 }
898
906 public function update(User $user, $notrigger = 0)
907 {
908 global $langs, $conf;
909
910 $error = 0;
911
912 $this->db->begin();
913
914 // Check parameters
915 if (empty($this->country_id)) {
916 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
917 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
918 return -1;
919 }
920 if (empty($this->ref)) {
921 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
922 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
923 return -1;
924 }
925 if (!$this->label) {
926 $this->label = "???";
927 }
928
929 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
930 $sql .= " ref = '".$this->db->escape($this->ref)."'";
931 $sql .= ",label = '".$this->db->escape($this->label)."'";
932 $sql .= ",courant = ".((int) $this->type);
933 $sql .= ",clos = ".((int) $this->status);
934 $sql .= ",rappro = ".((int) $this->rappro);
935 $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
936 $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
937 $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
938 $sql .= ",bank = '".$this->db->escape($this->bank)."'";
939 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
940 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
941 $sql .= ",number='".$this->db->escape($this->number)."'";
942 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
943 $sql .= ",bic='".$this->db->escape($this->bic)."'";
944 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
945 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
946 $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
947 $sql .= ",proprio = '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'";
948 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
949 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
950 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
951 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
952
953 $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
954
955 $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
956 $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
957 $sql .= ",comment = '".$this->db->escape($this->comment)."'";
958
959 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
960 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
961 $sql .= ",ics = '".$this->db->escape($this->ics)."'";
962 $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
963
964 $sql .= " WHERE rowid = ".((int) $this->id);
965
966 dol_syslog(get_class($this)."::update", LOG_DEBUG);
967 $result = $this->db->query($sql);
968 if ($result) {
969 // Actions on extra fields (by external module or standard code)
970 if (!$error) {
971 $result = $this->insertExtraFields();
972 if ($result < 0) {
973 $error++;
974 }
975 }
976
977 if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
978 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
979 $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type='bank_account' and entity = ".((int) $conf->entity);
980 $resql = $this->db->query($sql);
981 if (!$resql) {
982 $error++;
983 $this->error = $this->db->lasterror();
984 }
985
986 // We rename directory in order not to lose the attachments
987 $oldref = dol_sanitizeFileName($this->oldref);
988 $newref = dol_sanitizeFileName($this->ref);
989 $dirsource = $conf->bank->dir_output.'/'.$oldref;
990 $dirdest = $conf->bank->dir_output.'/'.$newref;
991 if (file_exists($dirsource)) {
992 dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
993 if (@rename($dirsource, $dirdest)) {
994 dol_syslog("Rename ok", LOG_DEBUG);
995 }
996 }
997 }
998
999 if (!$error && !$notrigger) {
1000 // Call trigger
1001 $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
1002 if ($result < 0) {
1003 $error++;
1004 }
1005 // End call triggers
1006 }
1007 } else {
1008 $error++;
1009 $this->error = $this->db->lasterror();
1010 dol_print_error($this->db);
1011 }
1012
1013 if (!$error) {
1014 $this->db->commit();
1015 return $this->id;
1016 } else {
1017 $this->db->rollback();
1018 return -1 * $error;
1019 }
1020 }
1021
1022
1023 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1030 public function update_bban(User $user = null)
1031 {
1032 // phpcs:enable
1033 global $conf, $langs;
1034
1035 // Load library to get BAN control function
1036 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1037
1038 dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
1039
1040 // Check parameters
1041 if (!$this->ref) {
1042 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
1043 return -2;
1044 }
1045
1046 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
1047 $sql .= " bank = '".$this->db->escape($this->bank)."'";
1048 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1049 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1050 $sql .= ",number='".$this->db->escape($this->number)."'";
1051 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1052 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1053 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1054 $sql .= ",domiciliation='".$this->db->escape($this->address ? $this->address : $this->domiciliation)."'";
1055 $sql .= ",proprio = '".$this->db->escape($this->owner_name ? $this->owner_name : $this->proprio)."'";
1056 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1057 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1058 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1059 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1060 $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
1061 $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
1062 $sql .= " WHERE rowid = ".((int) $this->id);
1063 $sql .= " AND entity = ".((int) $conf->entity);
1064
1065 dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
1066
1067 $result = $this->db->query($sql);
1068 if ($result) {
1069 return 1;
1070 } else {
1071 $this->error = $this->db->lasterror();
1072 dol_print_error($this->db);
1073 return -1;
1074 }
1075 }
1076
1077
1085 public function fetch($id, $ref = '')
1086 {
1087 if (empty($id) && empty($ref)) {
1088 $this->error = "ErrorBadParameters";
1089 return -1;
1090 }
1091
1092 $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant as type, ba.clos as status, ba.rappro, ba.url,";
1093 $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1094 $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,";
1095 $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1096 $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1097 $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1098 $sql .= ' c.code as country_code, c.label as country,';
1099 $sql .= ' d.code_departement as state_code, d.nom as state,';
1100 $sql .= ' aj.code as accountancy_journal';
1101 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1102 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1103 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1104 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1105 $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1106 if ($id) {
1107 $sql .= " AND ba.rowid = ".((int) $id);
1108 }
1109 if ($ref) {
1110 $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1111 }
1112
1113 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1114 $result = $this->db->query($sql);
1115 if ($result) {
1116 if ($this->db->num_rows($result)) {
1117 $obj = $this->db->fetch_object($result);
1118
1119 $this->id = $obj->rowid;
1120 $this->rowid = $obj->rowid;
1121 $this->ref = $obj->ref;
1122 $this->label = $obj->label;
1123 $this->type = $obj->type;
1124 $this->courant = $obj->type;
1125 $this->bank = $obj->bank;
1126 $this->clos = $obj->status;
1127 $this->status = $obj->status;
1128 $this->rappro = $obj->rappro;
1129 $this->url = $obj->url;
1130
1131 $this->code_banque = $obj->code_banque;
1132 $this->code_guichet = $obj->code_guichet;
1133 $this->number = $obj->number;
1134 $this->cle_rib = $obj->cle_rib;
1135 $this->bic = $obj->bic;
1136 $this->iban = $obj->iban;
1137 $this->domiciliation = $obj->address;
1138 $this->address = $obj->address;
1139 $this->pti_in_ctti = $obj->pti_in_ctti;
1140 $this->proprio = $obj->owner_name;
1141 $this->owner_name = $obj->owner_name;
1142 $this->owner_address = $obj->owner_address;
1143 $this->owner_zip = $obj->owner_zip;
1144 $this->owner_town = $obj->owner_town;
1145 $this->owner_country_id = $obj->owner_country_id;
1146
1147 $this->state_id = $obj->state_id;
1148 $this->state_code = $obj->state_code;
1149 $this->state = $obj->state;
1150
1151 $this->country_id = $obj->country_id;
1152 $this->country_code = $obj->country_code;
1153 $this->country = $obj->country;
1154
1155 $this->account_number = $obj->account_number;
1156 $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1157 $this->accountancy_journal = $obj->accountancy_journal;
1158
1159 $this->currency_code = $obj->currency_code;
1160 $this->account_currency_code = $obj->currency_code;
1161 $this->min_allowed = $obj->min_allowed;
1162 $this->min_desired = $obj->min_desired;
1163 $this->comment = $obj->comment;
1164
1165 $this->date_creation = $this->db->jdate($obj->date_creation);
1166 $this->date_modification = $this->db->jdate($obj->date_modification);
1167
1168 $this->ics = $obj->ics;
1169 $this->ics_transfer = $obj->ics_transfer;
1170
1171 // Retrieve all extrafield
1172 // fetch optionals attributes and labels
1173 $this->fetch_optionals();
1174
1175 return 1;
1176 } else {
1177 return 0;
1178 }
1179 } else {
1180 $this->error = $this->db->lasterror();
1181 $this->errors[] = $this->error;
1182 return -1;
1183 }
1184 }
1185
1196 public function setCategories($categories)
1197 {
1198 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1199 return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1200 }
1201
1209 public function delete(User $user = null, $notrigger = 0)
1210 {
1211 $error = 0;
1212
1213 $this->db->begin();
1214
1215 // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1216
1217 // Delete link between tag and bank account
1218 if (!$error) {
1219 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1220 $sql .= " WHERE fk_account = ".((int) $this->id);
1221
1222 $resql = $this->db->query($sql);
1223 if (!$resql) {
1224 $error++;
1225 $this->error = "Error ".$this->db->lasterror();
1226 }
1227 }
1228
1229 if (!$error) {
1230 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1231 $sql .= " WHERE rowid = ".((int) $this->id);
1232
1233 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1234 $result = $this->db->query($sql);
1235 if ($result) {
1236 // Remove extrafields
1237 if (!$error) {
1238 $result = $this->deleteExtraFields();
1239 if ($result < 0) {
1240 $error++;
1241 dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1242 }
1243 }
1244 } else {
1245 $error++;
1246 $this->error = "Error ".$this->db->lasterror();
1247 }
1248 }
1249
1250 if (!$error) {
1251 $this->db->commit();
1252 return 1;
1253 } else {
1254 $this->db->rollback();
1255 return -1;
1256 }
1257 }
1258
1259
1266 public function getLibStatut($mode = 0)
1267 {
1268 return $this->LibStatut($this->status, $mode);
1269 }
1270
1271 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1279 public function LibStatut($status, $mode = 0)
1280 {
1281 // phpcs:enable
1282 global $langs;
1283 $langs->load('banks');
1284
1285 if ($status == self::STATUS_OPEN) {
1286 $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1287 $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1288 $statusType = 'status4';
1289 } else {
1290 $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1291 $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1292 $statusType = 'status5';
1293 }
1294
1295 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1296 }
1297
1298
1299 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1305 public function can_be_deleted()
1306 {
1307 // phpcs:enable
1308 $can_be_deleted = false;
1309
1310 $sql = "SELECT COUNT(rowid) as nb";
1311 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1312 $sql .= " WHERE fk_account = ".((int) $this->id);
1313
1314 $resql = $this->db->query($sql);
1315 if ($resql) {
1316 $obj = $this->db->fetch_object($resql);
1317 if ($obj->nb <= 1) {
1318 $can_be_deleted = true; // Juste le solde
1319 }
1320 } else {
1321 dol_print_error($this->db);
1322 }
1323 return $can_be_deleted;
1324 }
1325
1326
1332 public function error()
1333 {
1334 return $this->error;
1335 }
1336
1345 public function solde($option = 0, $date_end = '', $field = 'dateo')
1346 {
1347 $solde = 0;
1348
1349 $sql = "SELECT sum(amount) as amount";
1350 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1351 $sql .= " WHERE fk_account = ".((int) $this->id);
1352 if ($option == 1) {
1353 $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1354 }
1355
1356 $resql = $this->db->query($sql);
1357 if ($resql) {
1358 if ($this->db->num_rows($resql)) {
1359 $obj = $this->db->fetch_object($resql);
1360 $solde = $obj->amount;
1361 }
1362 $this->db->free($resql);
1363 } else {
1364 $this->errors[] = $this->db->lasterror;
1365 return -1;
1366 }
1367
1368 return (float) price2num($solde, 'MU');
1369 }
1370
1371 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1379 public function load_board(User $user, $filteraccountid = 0)
1380 {
1381 // phpcs:enable
1382 global $conf, $langs;
1383
1384 if ($user->socid) {
1385 return -1; // protection pour eviter appel par utilisateur externe
1386 }
1387
1388 $sql = "SELECT b.rowid, b.datev as datefin";
1389 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1390 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1391 $sql .= " WHERE b.rappro=0";
1392 $sql .= " AND b.fk_account = ba.rowid";
1393 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1394 $sql .= " AND (ba.rappro = 1 AND ba.courant != " . Account::TYPE_CASH . ")"; // Compte rapprochable
1395 $sql .= " AND clos = 0";
1396 if ($filteraccountid) {
1397 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1398 }
1399
1400 $resql = $this->db->query($sql);
1401 if ($resql) {
1402 $langs->load("banks");
1403 $now = dol_now();
1404
1405 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1406
1407 $response = new WorkboardResponse();
1408 $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1409 $response->label = $langs->trans("TransactionsToConciliate");
1410 $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1411 $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1412 $response->img = img_object('', "payment");
1413
1414 while ($obj = $this->db->fetch_object($resql)) {
1415 $response->nbtodo++;
1416 if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1417 $response->nbtodolate++;
1418 }
1419 }
1420
1421 return $response;
1422 } else {
1423 dol_print_error($this->db);
1424 $this->error = $this->db->error();
1425 return -1;
1426 }
1427 }
1428
1435 public function loadStateBoard($filteraccountid = 0)
1436 {
1437 global $user;
1438
1439 if ($user->socid) {
1440 return -1; // protection pour eviter appel par utilisateur externe
1441 }
1442
1443 $sql = "SELECT count(b.rowid) as nb";
1444 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1445 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1446 $sql .= " WHERE b.fk_account = ba.rowid";
1447 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1448 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1449 $sql .= " AND clos = 0";
1450 if ($filteraccountid) {
1451 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1452 }
1453
1454 $resql = $this->db->query($sql);
1455 if ($resql) {
1456 while ($obj = $this->db->fetch_object($resql)) {
1457 $this->nb["banklines"] = $obj->nb;
1458 }
1459 $this->db->free($resql);
1460 return 1;
1461 } else {
1462 dol_print_error($this->db);
1463 $this->error = $this->db->error();
1464 return -1;
1465 }
1466 }
1467
1468
1474 public function countAccountToReconcile()
1475 {
1476 global $user;
1477
1478 //Protection against external users
1479 if ($user->socid) {
1480 return 0;
1481 }
1482
1483 $nb = 0;
1484
1485 $sql = "SELECT COUNT(ba.rowid) as nb";
1486 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1487 $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1488 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1489 if (!getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
1490 $sql .= " AND ba.courant != " . Account::TYPE_CASH;
1491 }
1492
1493 $resql = $this->db->query($sql);
1494 if ($resql) {
1495 $obj = $this->db->fetch_object($resql);
1496 $nb = $obj->nb;
1497 } else {
1498 dol_print_error($this->db);
1499 }
1500
1501 return $nb;
1502 }
1503
1511 public function getTooltipContentArray($params)
1512 {
1513 global $langs;
1514 $langs->loadLangs(['banks', 'compta']);
1515 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1516
1517 $datas = array();
1518
1519 $nofetch = !empty($params['nofetch']);
1520 $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1521 if (isset($this->status)) {
1522 $pictos .= ' '.$this->getLibStatut(5);
1523 }
1524 $datas['picto'] = $pictos;
1525 $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1526 $datas['accountnumber'] = '<br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1527 $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1528 $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1529 $datas['accountcurrency'] = '<br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1530
1531 if (isModEnabled('accounting')) {
1532 include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1533 $langs->load("accountancy");
1534 $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1535 $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1536 }
1537 // show categories for this record only in ajax to not overload lists
1538 if (isModEnabled('category') && !$nofetch) {
1539 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1540 $form = new Form($this->db);
1541 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1542 }
1543
1544 return $datas;
1545 }
1546
1558 public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1559 {
1560 global $conf, $langs;
1561
1562 if (!empty($conf->dol_no_mouse_hover)) {
1563 $notooltip = 1; // Force disable tooltips
1564 }
1565
1566 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1567
1568 $result = '';
1569 $classfortooltip = 'classfortooltip';
1570 $dataparams = '';
1571 $params = [
1572 'id' => $this->id,
1573 'objecttype' => $this->element,
1574 'option' => $option,
1575 'nofetch' => 1,
1576 ];
1577 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1578 $classfortooltip = 'classforajaxtooltip';
1579 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1580 $label = '';
1581 } else {
1582 $label = implode($this->getTooltipContentArray($params));
1583 }
1584
1585 $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1586 if ($mode == 'transactions') {
1587 $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1588 } elseif ($mode == 'receipts') {
1589 $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1590 }
1591
1592 if ($option != 'nolink') {
1593 // Add param to save lastsearch_values or not
1594 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1595 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1596 $add_save_lastsearch_values = 1;
1597 }
1598 if ($add_save_lastsearch_values) {
1599 $url .= '&save_lastsearch_values=1';
1600 }
1601 }
1602
1603 $linkclose = '';
1604 if (empty($notooltip)) {
1605 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1606 $label = $langs->trans("BankAccount");
1607 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1608 }
1609 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1610 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1611 } else {
1612 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1613 }
1614
1615 if ($option == 'nolink' || empty($url)) {
1616 $linkstart = '<span';
1617 } else {
1618 $linkstart = '<a href="'.$url.'"';
1619 }
1620 $linkstart .= $linkclose.'>';
1621 if ($option == 'nolink' || empty($url)) {
1622 $linkend = '</span>';
1623 } else {
1624 $linkend = '</a>';
1625 }
1626
1627 $result .= $linkstart;
1628
1629 if ($withpicto) {
1630 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1631 }
1632 if ($withpicto != 2) {
1633 $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1634 }
1635 $result .= $linkend;
1636
1637 return $result;
1638 }
1639
1640
1641 // Method after here are common to Account and CompanyBankAccount
1642
1643
1649 public function verif()
1650 {
1651 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1652
1653 $error = 0;
1654
1655 // Call functions to check BAN
1656 if (!checkIbanForAccount($this)) {
1657 $error++;
1658 $this->error = 'IBANNotValid';
1659 }
1660 if (!checkSwiftForAccount($this)) {
1661 $error++;
1662 $this->error = 'SwiftNotValid';
1663 }
1664
1665 if (! $error) {
1666 return 1;
1667 } else {
1668 return 0;
1669 }
1670 }
1671
1677 public function getCountryCode()
1678 {
1679 global $mysoc;
1680
1681 // We return country code of bank account
1682 if (!empty($this->country_code)) {
1683 return $this->country_code;
1684 }
1685
1686 // For backward compatibility, we try to guess country from other information
1687 if (!empty($this->iban)) {
1688 // If IBAN defined, we can know country of account from it
1689 $reg = array();
1690 if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1691 return $reg[1];
1692 }
1693 }
1694
1695 // If this class is linked to a third party
1696 if (!empty($this->socid)) {
1697 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1698 $company = new Societe($this->db);
1699 $result = $company->fetch($this->socid);
1700 if (!empty($company->country_code)) {
1701 return $company->country_code;
1702 }
1703 }
1704
1705 // We return country code of managed company
1706 if (!empty($mysoc->country_code)) {
1707 return $mysoc->country_code;
1708 }
1709
1710 return '';
1711 }
1712
1720 public function getBannerAddress($htmlkey, $object)
1721 {
1722 global $conf, $langs;
1723
1724 $out = '';
1725
1726 $outdone = 0;
1727 $coords = $this->getFullAddress(1, ', ', getDolGlobalInt('MAIN_SHOW_REGION_IN_STATE_SELECT'));
1728 if ($coords) {
1729 if (!empty($conf->use_javascript_ajax)) {
1730 // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
1731 $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
1732 $out .= img_picto($langs->trans("Address"), 'map-marker-alt');
1733 $out .= '</a> ';
1734 }
1735 $address = dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
1736 if ($address) {
1737 $out .= $address;
1738 $outdone++;
1739 }
1740 $outdone++;
1741 }
1742
1743 return $out;
1744 }
1745
1746
1755 public function useDetailedBBAN()
1756 {
1757 $country_code = $this->getCountryCode();
1758
1759 if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1760 return 1; // France, Spain, Gabon, ... - Not valid for CH
1761 }
1762 if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1763 return 2; // Australia, England...
1764 }
1765 return 0;
1766 }
1767
1773 public function needIBAN()
1774 {
1775 global $conf;
1776
1777 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1778 return 0;
1779 }
1780
1781 $country_code = $this->getCountryCode();
1782
1783 $country_code_in_EEC = array(
1784 'AT', // Austria
1785 'BE', // Belgium
1786 'BG', // Bulgaria
1787 'CY', // Cyprus
1788 'CZ', // Czech republic
1789 'DE', // Germany
1790 'DK', // Danemark
1791 'EE', // Estonia
1792 'ES', // Spain
1793 'FI', // Finland
1794 'FR', // France
1795 'GB', // United Kingdom
1796 'GR', // Greece
1797 'HR', // Croatia
1798 'NL', // Holland
1799 'HU', // Hungary
1800 'IE', // Ireland
1801 'IM', // Isle of Man - Included in UK
1802 'IT', // Italy
1803 'LT', // Lithuania
1804 'LU', // Luxembourg
1805 'LV', // Latvia
1806 'MC', // Monaco - Included in France
1807 'MT', // Malta
1808 //'NO', // Norway
1809 'PL', // Poland
1810 'PT', // Portugal
1811 'RO', // Romania
1812 'SE', // Sweden
1813 'SK', // Slovakia
1814 'SI', // Slovenia
1815 'UK', // United Kingdom
1816 //'CH', // Switzerland - No. Swizerland in not in EEC
1817 );
1818
1819 if (in_array($country_code, $country_code_in_EEC)) {
1820 return 1; // France, Spain, ...
1821 }
1822 return 0;
1823 }
1824
1831 public function info($id)
1832 {
1833 }
1834
1849 public function getFieldsToShow($includeibanbic = 0)
1850 {
1851 //Get the required properties depending on the country
1852 $detailedBBAN = $this->useDetailedBBAN();
1853
1854 if ($detailedBBAN == 0) {
1855 $fieldarray = array(
1856 'BankAccountNumber'
1857 );
1858 } elseif ($detailedBBAN == 2) {
1859 $fieldarray = array(
1860 'BankCode',
1861 'BankAccountNumber'
1862 );
1863 } else {
1864 $fieldarray = self::getAccountNumberOrder();
1865 }
1866
1867 //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1868 if ($includeibanbic) {
1869 $fieldarray[] = 'IBAN';
1870 $fieldarray[] = 'BIC';
1871 }
1872 //}
1873
1874 //Get the order the properties are shown
1875 return $fieldarray;
1876 }
1877
1888 public static function getAccountNumberOrder()
1889 {
1890 global $conf;
1891
1892 $fieldlists = array(
1893 'BankCode',
1894 'DeskCode',
1895 'BankAccountNumber',
1896 'BankAccountNumberKey'
1897 );
1898
1899 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION')) {
1900 if (is_numeric(getDolGlobalString('BANK_SHOW_ORDER_OPTION'))) {
1901 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION') == '1') {
1902 $fieldlists = array(
1903 'BankCode',
1904 'DeskCode',
1905 'BankAccountNumberKey',
1906 'BankAccountNumber'
1907 );
1908 }
1909 } else {
1910 //Replace the old AccountNumber key with the new BankAccountNumber key
1911 $fieldlists = explode(
1912 ' ',
1913 preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1914 );
1915 }
1916 }
1917
1918 return $fieldlists;
1919 }
1920
1921
1929 public function initAsSpecimen()
1930 {
1931 // Example of IBAN FR7630001007941234567890185
1932 $this->specimen = 1;
1933 $this->ref = 'MBA';
1934 $this->label = 'My Big Company Bank account';
1935 $this->courant = Account::TYPE_CURRENT;
1936 $this->clos = Account::STATUS_OPEN;
1937 $this->type = Account::TYPE_CURRENT;
1938 $this->status = Account::STATUS_OPEN;
1939 $this->code_banque = '30001';
1940 $this->code_guichet = '00794';
1941 $this->number = '12345678901';
1942 $this->cle_rib = '85';
1943 $this->bic = 'AA12';
1944 $this->iban = 'FR7630001007941234567890185';
1945
1946 $this->bank = 'MyBank';
1947 $this->address = 'Rue de Paris';
1948 $this->proprio = 'Owner';
1949 $this->owner_name = 'Owner';
1950 $this->owner_address = 'Owner address';
1951 $this->owner_zip = 'Owner zip';
1952 $this->owner_town = 'Owner town';
1953 $this->owner_country_id = 'Owner country_id';
1954 $this->country_id = 1;
1955
1956 return 1;
1957 }
1958
1967 public static function replaceThirdparty($dbs, $origin_id, $dest_id)
1968 {
1969 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'";
1970
1971 if ($dbs->query($sql)) {
1972 return true;
1973 } else {
1974 //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.
1975 //$this->errors = $dbs->lasterror();
1976 return false;
1977 }
1978 }
1979
1987 public function getKanbanView($option = '', $arraydata = null)
1988 {
1989 global $langs;
1990
1991 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1992
1993 $return = '<div class="box-flex-item box-flex-grow-zero">';
1994 $return .= '<div class="info-box info-box-sm">';
1995 $return .= '<span class="info-box-icon bg-infobox-action">';
1996 $return .= img_picto('', $this->picto);
1997 $return .= '</span>';
1998 $return .= '<div class="info-box-content">';
1999 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
2000 if ($selected >= 0) {
2001 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2002 }
2003 if (property_exists($this, 'type_lib')) {
2004 $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
2005 }
2006 if (method_exists($this, 'solde')) {
2007 $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
2008 $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>';
2009 }
2010 if (method_exists($this, 'getLibStatut')) {
2011 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2012 }
2013 $return .= '</div>';
2014 $return .= '</div>';
2015 $return .= '</div>';
2016 return $return;
2017 }
2018}
2019
2020
2021require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
2022
2026class AccountLine extends CommonObjectLine
2027{
2031 public $db;
2032
2036 public $element = 'bank';
2037
2041 public $table_element = 'bank';
2042
2046 public $picto = 'accountline';
2047
2051 public $id;
2052
2056 public $ref;
2057
2063 public $datec;
2064
2070 public $dateo;
2071
2077 public $datev;
2078
2082 public $amount;
2083
2087 public $amount_main_currency;
2088
2092 public $fk_user_author;
2093
2097 public $fk_user_rappro;
2098
2102 public $fk_type;
2103
2107 public $fk_bordereau;
2108
2112 public $fk_account;
2113
2117 public $bank_account_ref;
2118
2122 public $bank_account_label;
2123
2127 public $numero_compte;
2128
2132 public $emetteur;
2133
2137 public $rappro;
2138
2142 public $num_releve;
2143
2147 public $num_chq;
2148
2152 public $bank_chq;
2153
2157 public $label;
2158
2162 public $note;
2163
2168 public $user_rappro;
2169
2170
2176 public function __construct(DoliDB $db)
2177 {
2178 $this->db = $db;
2179 }
2180
2189 public function fetch($rowid, $ref = '', $num = '')
2190 {
2191 // Check parameters
2192 if (empty($rowid) && empty($ref) && empty($num)) {
2193 return -1;
2194 }
2195
2196 $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2197 $sql .= " b.fk_user_author, b.fk_user_rappro,";
2198 $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2199 $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2200 $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2201 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2202 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2203 $sql .= " WHERE b.fk_account = ba.rowid";
2204 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2205 if ($num) {
2206 $sql .= " AND b.num_chq = '".$this->db->escape($num)."'";
2207 } elseif ($ref) {
2208 $sql .= " AND b.rowid = '".$this->db->escape($ref)."'";
2209 } else {
2210 $sql .= " AND b.rowid = ".((int) $rowid);
2211 }
2212
2213 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2214 $result = $this->db->query($sql);
2215 if ($result) {
2216 $ret = 0;
2217
2218 $obj = $this->db->fetch_object($result);
2219 if ($obj) {
2220 $this->id = $obj->rowid;
2221 $this->rowid = $obj->rowid;
2222 $this->ref = $obj->rowid;
2223
2224 $this->datec = $this->db->jdate($obj->datec);
2225 $this->datev = $this->db->jdate($obj->datev);
2226 $this->dateo = $this->db->jdate($obj->dateo);
2227 $this->amount = $obj->amount;
2228 $this->label = $obj->label;
2229 $this->note = $obj->note;
2230
2231 $this->fk_user_author = $obj->fk_user_author;
2232 $this->fk_user_rappro = $obj->fk_user_rappro;
2233
2234 $this->fk_type = $obj->fk_type; // Type of transaction
2235 $this->rappro = (int) $obj->rappro;
2236 $this->num_releve = $obj->num_releve;
2237
2238 $this->num_chq = $obj->num_chq;
2239 $this->bank_chq = $obj->banque;
2240 $this->fk_bordereau = $obj->fk_bordereau;
2241
2242 $this->fk_account = $obj->fk_account;
2243 $this->bank_account_ref = $obj->bank_account_ref;
2244 $this->bank_account_label = $obj->bank_account_label;
2245
2246 // Retrieve all extrafield
2247 // fetch optionals attributes and labels
2248 $this->fetch_optionals();
2249
2250 $ret = 1;
2251 }
2252 $this->db->free($result);
2253 return $ret;
2254 } else {
2255 return -1;
2256 }
2257 }
2258
2264 public function insert()
2265 {
2266 $error = 0;
2267
2268 $this->db->begin();
2269
2270 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2271 $sql .= "datec";
2272 $sql .= ", dateo";
2273 $sql .= ", datev";
2274 $sql .= ", label";
2275 $sql .= ", amount";
2276 $sql .= ", amount_main_currency";
2277 $sql .= ", fk_user_author";
2278 $sql .= ", num_chq";
2279 $sql .= ", fk_account";
2280 $sql .= ", fk_type";
2281 $sql .= ", emetteur,banque";
2282 $sql .= ", rappro";
2283 $sql .= ", numero_compte";
2284 $sql .= ", num_releve";
2285 $sql .= ") VALUES (";
2286 $sql .= "'".$this->db->idate($this->datec)."'";
2287 $sql .= ", '".$this->db->idate($this->dateo)."'";
2288 $sql .= ", '".$this->db->idate($this->datev)."'";
2289 $sql .= ", '".$this->db->escape($this->label)."'";
2290 $sql .= ", ".price2num($this->amount);
2291 $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2292 $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2293 $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2294 $sql .= ", '".$this->db->escape($this->fk_account)."'";
2295 $sql .= ", '".$this->db->escape($this->fk_type)."'";
2296 $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2297 $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2298 $sql .= ", ".(int) $this->rappro;
2299 $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2300 $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2301 $sql .= ")";
2302
2303
2304 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2305 $resql = $this->db->query($sql);
2306 if ($resql) {
2307 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2308 // Actions on extra fields (by external module or standard code)
2309 $result = $this->insertExtraFields();
2310 if ($result < 0) {
2311 $error++;
2312 }
2313 } else {
2314 $error++;
2315 $this->error = $this->db->lasterror();
2316 dol_print_error($this->db);
2317 }
2318
2319 if (!$error) {
2320 $this->db->commit();
2321 return $this->id;
2322 } else {
2323 $this->db->rollback();
2324 return -1 * $error;
2325 }
2326 }
2327
2335 public function delete(User $user = null, $notrigger = 0)
2336 {
2337 $nbko = 0;
2338
2339 if ($this->rappro) {
2340 // Protection to avoid any delete of consolidated lines
2341 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2342 return -1;
2343 }
2344
2345 $this->db->begin();
2346
2347 if (!$notrigger) {
2348 // Call trigger
2349 $result = $this->call_trigger('BANKACCOUNTLINE_DELETE', $user);
2350 if ($result < 0) {
2351 $this->db->rollback();
2352 return -1;
2353 }
2354 // End call triggers
2355 }
2356
2357 // Protection to avoid any delete of accounted lines. Protection on by default
2358 if (!getDolGlobalString('BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING')) {
2359 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2360 $resql = $this->db->query($sql);
2361 if ($resql) {
2362 $obj = $this->db->fetch_object($resql);
2363 if ($obj && $obj->nb) {
2364 $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2365 $this->db->rollback();
2366 return -1;
2367 }
2368 } else {
2369 $this->error = $this->db->lasterror();
2370 $this->db->rollback();
2371 return -1;
2372 }
2373 }
2374
2375 // Delete urls
2376 $result = $this->delete_urls($user);
2377 if ($result < 0) {
2378 $nbko++;
2379 }
2380
2381 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid=".(int) $this->rowid;
2382 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2383 $result = $this->db->query($sql);
2384 if (!$result) {
2385 $nbko++;
2386 }
2387
2388 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2389 $result = $this->db->query($sql);
2390 if (!$result) {
2391 $nbko++;
2392 }
2393
2394 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2395 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2396 $result = $this->db->query($sql);
2397 if (!$result) {
2398 $nbko++;
2399 }
2400
2401 if (!$nbko) {
2402 $this->db->commit();
2403 return 1;
2404 } else {
2405 $this->db->rollback();
2406 return -$nbko;
2407 }
2408 }
2409
2410
2411 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2418 public function delete_urls(User $user = null)
2419 {
2420 // phpcs:enable
2421 $nbko = 0;
2422
2423 if ($this->rappro) {
2424 // Protection to avoid any delete of consolidated lines
2425 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2426 return -1;
2427 }
2428
2429 $this->db->begin();
2430
2431 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2432 dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2433 $result = $this->db->query($sql);
2434 if (!$result) {
2435 $nbko++;
2436 }
2437
2438 if (!$nbko) {
2439 $this->db->commit();
2440 return 1;
2441 } else {
2442 $this->db->rollback();
2443 return -$nbko;
2444 }
2445 }
2446
2447
2455 public function update(User $user, $notrigger = 0)
2456 {
2457 $this->db->begin();
2458
2459 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2460 $sql .= " amount = ".price2num($this->amount).",";
2461 $sql .= " datev='".$this->db->idate($this->datev)."',";
2462 $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2463 $sql .= " WHERE rowid = ".((int) $this->rowid);
2464
2465 dol_syslog(get_class($this)."::update", LOG_DEBUG);
2466 $resql = $this->db->query($sql);
2467 if ($resql) {
2468 $this->db->commit();
2469 return 1;
2470 } else {
2471 $this->db->rollback();
2472 $this->error = $this->db->error();
2473 return -1;
2474 }
2475 }
2476
2477
2483 public function updateLabel()
2484 {
2485 $this->db->begin();
2486
2487 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2488 $sql .= " label = '".$this->db->escape($this->label)."'";
2489 $sql .= " WHERE rowid = ".((int) $this->rowid);
2490
2491 dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
2492 $resql = $this->db->query($sql);
2493 if ($resql) {
2494 $this->db->commit();
2495 return 1;
2496 } else {
2497 $this->db->rollback();
2498 $this->error = $this->db->error();
2499 return -1;
2500 }
2501 }
2502
2503
2504 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2513 public function update_conciliation(User $user, $cat, $conciliated = 1)
2514 {
2515 // phpcs:enable
2516 global $conf, $langs;
2517
2518 $this->db->begin();
2519
2520 // Check statement field
2521 if (getDolGlobalString('BANK_STATEMENT_REGEX_RULE')) {
2522 if (!preg_match('/' . getDolGlobalString('BANK_STATEMENT_REGEX_RULE').'/', $this->num_releve)) {
2523 $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", getDolGlobalString('BANK_STATEMENT_REGEX_RULE'));
2524 return -1;
2525 }
2526 }
2527
2528 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2529 $sql .= " rappro = ".((int) $conciliated);
2530 $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2531 if ($conciliated) {
2532 $sql .= ", fk_user_rappro = ".$user->id;
2533 }
2534 $sql .= " WHERE rowid = ".((int) $this->id);
2535
2536 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2537 $resql = $this->db->query($sql);
2538 if ($resql) {
2539 if (!empty($cat) && $cat > 0) {
2540 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
2541 $sql .= "lineid";
2542 $sql .= ", fk_categ";
2543 $sql .= ") VALUES (";
2544 $sql .= $this->id;
2545 $sql .= ", ".((int) $cat);
2546 $sql .= ")";
2547
2548 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2549 $this->db->query($sql);
2550
2551 // No error check. Can fail if category already affected
2552 // TODO Do no try the insert if link already exists
2553 }
2554
2555 $this->rappro = (int) $conciliated;
2556
2557 $this->db->commit();
2558 return 1;
2559 } else {
2560 $this->db->rollback();
2561 return -1;
2562 }
2563 }
2564
2565
2566 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2574 public function datev_change($rowid, $sign = 1)
2575 {
2576 // phpcs:enable
2577 $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2578 $resql = $this->db->query($sql);
2579 if ($resql) {
2580 $obj = $this->db->fetch_object($resql);
2581 $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2582
2583 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2584 $sql .= " datev = '".$this->db->idate($newdate)."'";
2585 $sql .= " WHERE rowid = ".((int) $rowid);
2586
2587 $result = $this->db->query($sql);
2588 if ($result) {
2589 if ($this->db->affected_rows($result)) {
2590 return 1;
2591 }
2592 } else {
2593 dol_print_error($this->db);
2594 return 0;
2595 }
2596 } else {
2597 dol_print_error($this->db);
2598 }
2599 return 0;
2600 }
2601
2602 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2609 public function datev_next($id)
2610 {
2611 // phpcs:enable
2612 return $this->datev_change($id, 1);
2613 }
2614
2615 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2622 public function datev_previous($id)
2623 {
2624 // phpcs:enable
2625 return $this->datev_change($id, -1);
2626 }
2627
2628
2629 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2637 public function dateo_change($rowid, $sign = 1)
2638 {
2639 // phpcs:enable
2640 $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2641 $resql = $this->db->query($sql);
2642 if ($resql) {
2643 $obj = $this->db->fetch_object($resql);
2644 $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2645
2646 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2647 $sql .= " dateo = '".$this->db->idate($newdate)."'";
2648 $sql .= " WHERE rowid = ".((int) $rowid);
2649
2650 $result = $this->db->query($sql);
2651 if ($result) {
2652 if ($this->db->affected_rows($result)) {
2653 return 1;
2654 }
2655 } else {
2656 dol_print_error($this->db);
2657 return 0;
2658 }
2659 } else {
2660 dol_print_error($this->db);
2661 }
2662 return 0;
2663 }
2664
2665 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2672 public function dateo_next($id)
2673 {
2674 // phpcs:enable
2675 return $this->dateo_change($id, 1);
2676 }
2677
2678 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2685 public function dateo_previous($id)
2686 {
2687 // phpcs:enable
2688 return $this->dateo_change($id, -1);
2689 }
2690
2691
2698 public function info($id)
2699 {
2700 $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2701 $sql .= ' b.fk_user_author, b.fk_user_rappro';
2702 $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2703 $sql .= ' WHERE b.rowid = '.((int) $id);
2704
2705 $result = $this->db->query($sql);
2706 if ($result) {
2707 if ($this->db->num_rows($result)) {
2708 $obj = $this->db->fetch_object($result);
2709
2710 $this->id = $obj->rowid;
2711
2712 $this->user_creation_id = $obj->fk_user_author;
2713 $this->user_rappro = $obj->fk_user_rappro;
2714 $this->date_creation = $this->db->jdate($obj->datec);
2715 $this->date_modification = $this->db->jdate($obj->datem);
2716 //$this->date_rappro = $obj->daterappro; // Not yet managed
2717 }
2718 $this->db->free($result);
2719 } else {
2720 dol_print_error($this->db);
2721 }
2722 }
2723
2724
2734 public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2735 {
2736 global $conf, $langs;
2737
2738 $result = '';
2739
2740 $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2741 $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2742 if ($this->amount) {
2743 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2744 }
2745
2746 $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">';
2747 $linkend = '</a>';
2748
2749 $result .= $linkstart;
2750 if ($withpicto) {
2751 $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);
2752 }
2753 if ($withpicto != 2) {
2754 $result .= ($this->ref ? $this->ref : $this->id);
2755 }
2756
2757 $result .= $linkend;
2758
2759 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2760 $result .= ' <span class="opacitymedium">(';
2761 }
2762 if ($option == 'showall') {
2763 $result .= $langs->trans("BankAccount").': ';
2764 $accountstatic = new Account($this->db);
2765 $accountstatic->id = $this->fk_account;
2766 $accountstatic->ref = $this->bank_account_ref;
2767 $accountstatic->label = $this->bank_account_label;
2768 $result .= $accountstatic->getNomUrl(0).', ';
2769 }
2770 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2771 $result .= $langs->trans("BankLineConciliated").': ';
2772 $result .= yn($this->rappro);
2773 }
2774 if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2775 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2776 $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2777 $resql = $this->db->query($sql);
2778 if ($resql) {
2779 $obj = $this->db->fetch_object($resql);
2780 if ($obj && $obj->nb) {
2781 $result .= ' - '.$langs->trans("Accounted").': '.yn(1);
2782 } else {
2783 $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2784 }
2785 }
2786 }
2787 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2788 $result .= ')</span>';
2789 }
2790
2791 return $result;
2792 }
2793
2794
2801 public function getLibStatut($mode = 0)
2802 {
2803 return $this->LibStatut($this->status, $mode);
2804 }
2805
2806 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2814 public function LibStatut($status, $mode = 0)
2815 {
2816 // phpcs:enable
2817 return '';
2818 }
2819
2825 public function getVentilExportCompta()
2826 {
2827 $alreadydispatched = 0;
2828
2829 $type = 'bank';
2830
2831 $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);
2832 $resql = $this->db->query($sql);
2833 if ($resql) {
2834 $obj = $this->db->fetch_object($resql);
2835 if ($obj) {
2836 $alreadydispatched = $obj->nb;
2837 }
2838 } else {
2839 $this->error = $this->db->lasterror();
2840 return -1;
2841 }
2842
2843 if ($alreadydispatched) {
2844 return 1;
2845 }
2846 return 0;
2847 }
2848}
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:637
checkSwiftForAccount(Account $account=null, $swift=null)
Check SWIFT information for a bank account.
Definition bank.lib.php:284
checkIbanForAccount(Account $account=null, $ibantocheck=null)
Check IBAN number information for a bank account.
Definition bank.lib.php:305
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition bank.lib.php:330
$object ref
Definition info.php:79
Class to manage bank accounts.
solde($option=0, $date_end='', $field='dateo')
Return current balance.
fetch($id, $ref='')
Load a bank account into memory from database.
__construct(DoliDB $db)
Constructor.
getNomUrl($withpicto=0, $mode='', $option='', $save_lastsearch_value=-1, $notooltip=0, $morecss='')
Return clicable name (with picto eventually)
add_url_line($line_id, $url_id, $url, $label, $type)
Add a link between bank line record and its source.
loadStateBoard($filteraccountid=0)
Load the indicators this->nb for the state board.
update(User $user, $notrigger=0)
Update bank account card.
getCountryCode()
Return account country code.
getLibStatut($mode=0)
Return label of object status.
delete(User $user=null, $notrigger=0)
Delete bank account from database.
getBannerAddress($htmlkey, $object)
Return full address for banner.
error()
Return error.
info($id)
Load miscellaneous information for tab "Info".
const TYPE_CASH
Cash account.
__toString()
Shows the account number in the appropriate format.
const TYPE_SAVINGS
Savings account.
getTooltipContentArray($params)
getTooltipContentArray
canBeConciliated()
Return if a bank account need to be conciliated.
create(User $user, $notrigger=0)
Create bank account into database.
can_be_deleted()
Indicates if an account can be deleted or not (without movements)
update_bban(User $user=null)
Update BBAN (RIB) account fields.
const TYPE_CURRENT
Current account.
setCategories($categories)
Sets object to supplied categories.
countAccountToReconcile()
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
verif()
Return if an account has valid information for Direct debit payment.
getFieldsToShow($includeibanbic=0)
Returns the fields in order that this bank account should show to the user Will return an array with ...
load_board(User $user, $filteraccountid=0)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
get_url($fk_bank=0, $url_id=0, $type='')
TODO Move this into AccountLine Return array with links from llx_bank_url.
addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur='', $banque='', $accountancycode='', $datev=null, $num_releve='', $amount_main_currency=null)
Add an entry into table ".MAIN_DB_PREFIX."bank.
LibStatut($status, $mode=0)
Return label of given object status.
Class to manage bank transaction lines.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
setErrorsFromObject($object)
setErrorsFromObject
getFullAddress($withcountry=0, $sep="\n", $withregion=0, $extralangcode='')
Return full address of contact.
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class to manage generation of HTML components Only common components must be here.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_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 dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
table table fiche title col title div col center btnTitle icon
Automatically calls the icon named with the corresponding "object_" prefix.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php: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:2051