dolibarr  18.0.6
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-2023 Frédéric France <frederic.france@netlogic.fr>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program. If not, see <https://www.gnu.org/licenses/>.
26  */
27 
34 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
35 
36 
40 class Account extends CommonObject
41 {
45  public $element = 'bank_account';
46 
50  public $table_element = 'bank_account';
51 
56  public $ismultientitymanaged = 1;
57 
61  public $picto = 'account';
62 
68  public $rowid;
69 
74  public $label;
75 
80  public $courant;
81 
86  public $type;
87 
92  public $bank;
93 
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 
166  public $proprio;
167 
172  public $owner_address;
173  public $owner_zip;
174  public $owner_town;
175  public $owner_country_id;
176  public $owner_country_code;
177 
182  public $domiciliation; // deprecated, use now address
183  public $address;
184  public $state_id;
185  public $state_code;
186  public $state;
187 
193  public $type_lib = array();
194 
200  public $status = array();
201 
206  public $account_number;
207 
211  public $fk_accountancy_journal;
215  public $accountancy_journal;
216 
221  public $currency_code;
222 
228  public $account_currency_code;
229 
234  public $min_allowed;
235 
240  public $min_desired;
241 
246  public $comment;
247 
252  public $date_solde;
253 
260  public $solde;
261 
266  public $balance;
267 
272  public $ics;
273 
278  public $ics_transfer;
279 
280 
281 
306  // BEGIN MODULEBUILDER PROPERTIES
310  public $fields = array(
311  'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
312  'ref' =>array('type'=>'varchar(12)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>25),
313  'label' =>array('type'=>'varchar(30)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>30),
314  'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>35, 'index'=>1),
315  'bank' =>array('type'=>'varchar(60)', 'label'=>'Bank', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
316  'code_banque' =>array('type'=>'varchar(128)', 'label'=>'Code banque', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
317  'code_guichet' =>array('type'=>'varchar(6)', 'label'=>'Code guichet', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
318  'number' =>array('type'=>'varchar(255)', 'label'=>'Number', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
319  'cle_rib' =>array('type'=>'varchar(5)', 'label'=>'Cle rib', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
320  'bic' =>array('type'=>'varchar(11)', 'label'=>'Bic', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
321  'iban_prefix' =>array('type'=>'varchar(34)', 'label'=>'Iban prefix', 'enabled'=>1, 'visible'=>-1, 'position'=>70),
322  'country_iban' =>array('type'=>'varchar(2)', 'label'=>'Country iban', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
323  'cle_iban' =>array('type'=>'varchar(2)', 'label'=>'Cle iban', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
324  'domiciliation' =>array('type'=>'varchar(255)', 'label'=>'Domiciliation', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
325  'state_id' =>array('type'=>'integer', 'label'=>'StateId', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
326  'fk_pays' =>array('type'=>'integer', 'label'=>'Country', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>95),
327  'proprio' =>array('type'=>'varchar(60)', 'label'=>'Proprio', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
328  'owner_address' =>array('type'=>'varchar(255)', 'label'=>'Owner address', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
329  'owner_zip' =>array('type'=>'varchar(25)', 'label'=>'Owner zip', 'enabled'=>1, 'visible'=>-1, 'position'=>106),
330  'owner_town' =>array('type'=>'varchar(50)', 'label'=>'Owner town', 'enabled'=>1, 'visible'=>-1, 'position'=>107),
331  'owner_country_id' =>array('type'=>'integer', 'label'=>'Owner country', 'enabled'=>1, 'visible'=>-1, 'position'=>108),
332  'courant' =>array('type'=>'smallint(6)', 'label'=>'Courant', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>110),
333  'clos' =>array('type'=>'smallint(6)', 'label'=>'Clos', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>115),
334  'rappro' =>array('type'=>'smallint(6)', 'label'=>'Rappro', 'enabled'=>1, 'visible'=>-1, 'position'=>120),
335  'url' =>array('type'=>'varchar(128)', 'label'=>'Url', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
336  'account_number' =>array('type'=>'varchar(32)', 'label'=>'Account number', 'enabled'=>1, 'visible'=>-1, 'position'=>130),
337  'fk_accountancy_journal' =>array('type'=>'integer', 'label'=>'Accountancy journal ID', 'enabled'=>1, 'visible'=>-1, 'position'=>132),
338  'accountancy_journal' =>array('type'=>'varchar(20)', 'label'=>'Accountancy journal', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
339  'currency_code' =>array('type'=>'varchar(3)', 'label'=>'Currency code', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>140),
340  'min_allowed' =>array('type'=>'integer', 'label'=>'Min allowed', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
341  'min_desired' =>array('type'=>'integer', 'label'=>'Min desired', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
342  'comment' =>array('type'=>'text', 'label'=>'Comment', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
343  'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>156),
344  'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>157),
345  'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>160),
346  'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>165),
347  'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170),
348  'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>175),
349  'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>180),
350  'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
351  );
352  // END MODULEBUILDER PROPERTIES
353 
357  const TYPE_CURRENT = 1;
361  const TYPE_CASH = 2;
365  const TYPE_SAVINGS = 0;
366 
367 
368  const STATUS_OPEN = 0;
369  const STATUS_CLOSED = 1;
370 
371 
377  public function __construct(DoliDB $db)
378  {
379  global $langs;
380 
381  $this->db = $db;
382 
383  $this->solde = 0;
384 
385  $this->type_lib = array(
386  self::TYPE_SAVINGS => $langs->trans("BankType0"),
387  self::TYPE_CURRENT => $langs->trans("BankType1"),
388  self::TYPE_CASH => $langs->trans("BankType2"),
389  );
390 
391  $this->status = array(
392  self::STATUS_OPEN => $langs->trans("StatusAccountOpened"),
393  self::STATUS_CLOSED => $langs->trans("StatusAccountClosed")
394  );
395  }
396 
402  public function __toString()
403  {
404  $string = '';
405  foreach ($this->getFieldsToShow() as $val) {
406  if ($val == 'BankCode') {
407  $string .= $this->code_banque.' ';
408  } elseif ($val == 'BankAccountNumber') {
409  $string .= $this->number.' ';
410  } elseif ($val == 'DeskCode') {
411  $string .= $this->code_guichet.' ';
412  } elseif ($val == 'BankAccountNumberKey') {
413  $string .= $this->cle_rib.' ';
414  } elseif ($val == 'BIC') {
415  $string .= $this->bic.' ';
416  } elseif ($val == 'IBAN') {
417  $string .= $this->iban.' ';
418  }
419  }
420 
421  return trim($string);
422  }
423 
424 
430  public function canBeConciliated()
431  {
432  global $conf;
433 
434  if (empty($this->rappro)) {
435  return -1;
436  }
437  if ($this->courant == Account::TYPE_CASH && empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) {
438  return -2;
439  }
440  if ($this->clos) {
441  return -3;
442  }
443  return 1;
444  }
445 
446 
447  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
458  public function add_url_line($line_id, $url_id, $url, $label, $type)
459  {
460  // phpcs:enable
461  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
462  $sql .= "fk_bank";
463  $sql .= ", url_id";
464  $sql .= ", url"; // deprecated
465  $sql .= ", label";
466  $sql .= ", type";
467  $sql .= ") VALUES (";
468  $sql .= " ".((int) $line_id);
469  $sql .= ", ".((int) $url_id);
470  $sql .= ", '".$this->db->escape($url)."'"; // dperecated
471  $sql .= ", '".$this->db->escape($label)."'";
472  $sql .= ", '".$this->db->escape($type)."'";
473  $sql .= ")";
474 
475  dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
476  if ($this->db->query($sql)) {
477  $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
478  return $rowid;
479  } else {
480  $this->error = $this->db->lasterror();
481  return -1;
482  }
483  }
484 
485  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
495  public function get_url($fk_bank = '', $url_id = '', $type = '')
496  {
497  // phpcs:enable
498  $lines = array();
499 
500  // Check parameters
501  if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
502  $this->error = "ErrorBadParameter";
503  return -1;
504  }
505 
506  $sql = "SELECT fk_bank, url_id, url, label, type";
507  $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
508  if ($fk_bank > 0) {
509  $sql .= " WHERE fk_bank = ".((int) $fk_bank);
510  } else {
511  $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
512  }
513  $sql .= " ORDER BY type, label";
514 
515  dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
516  $result = $this->db->query($sql);
517  if ($result) {
518  $i = 0;
519  $num = $this->db->num_rows($result);
520  while ($i < $num) {
521  $obj = $this->db->fetch_object($result);
522  // Anciens liens (pour compatibilite)
523  $lines[$i][0] = $obj->url;
524  $lines[$i][1] = $obj->url_id;
525  $lines[$i][2] = $obj->label;
526  $lines[$i][3] = $obj->type;
527  // Nouveaux liens
528  $lines[$i]['url'] = $obj->url;
529  $lines[$i]['url_id'] = $obj->url_id;
530  $lines[$i]['label'] = $obj->label;
531  $lines[$i]['type'] = $obj->type;
532  $lines[$i]['fk_bank'] = $obj->fk_bank;
533  $i++;
534  }
535  } else {
536  dol_print_error($this->db);
537  }
538 
539  return $lines;
540  }
541 
560  public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
561  {
562  global $langs;
563 
564  // Deprecation warning
565  if (is_numeric($oper)) {
566  dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
567  }
568 
569  if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
570  $this->id = $this->rowid;
571  }
572 
573  // Clean parameters
574  $emetteur = trim($emetteur);
575  $banque = trim($banque);
576  $label = trim($label);
577 
578  $now = dol_now();
579 
580  if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
581  $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
582  $sql .= " WHERE id = ".((int) $oper);
583  $sql .= " AND entity IN (".getEntity('c_paiement').")";
584  $resql = $this->db->query($sql);
585  if ($resql) {
586  $obj = $this->db->fetch_object($resql);
587  $oper = $obj->code;
588  } else {
589  dol_print_error($this->db, 'Failed to get payment type code');
590  return -1;
591  }
592  }
593 
594  // Check parameters
595  if (!$oper) {
596  $this->error = $langs->trans("OperNotDefined");
597  return -1;
598  }
599  if (!$this->id) {
600  $this->error = $langs->trans("ThisIdNotDefined");
601  return -2;
602  }
603  if ($this->courant == Account::TYPE_CASH && $oper != 'LIQ') {
604  $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
605  return -3;
606  }
607 
608  $this->db->begin();
609 
610  if (is_null($datev) || empty($datev)) {
611  $datev = $date;
612  }
613 
614  $accline = new AccountLine($this->db);
615  $accline->datec = $now;
616  $accline->dateo = $date;
617  $accline->datev = $datev;
618  $accline->label = $label;
619  $accline->amount = $amount;
620  $accline->amount_main_currency = $amount_main_currency;
621  $accline->fk_user_author = $user->id;
622  $accline->fk_account = $this->id;
623  $accline->fk_type = $oper;
624  $accline->numero_compte = $accountancycode;
625  $accline->num_releve = $num_releve;
626 
627  if ($num_chq) {
628  $accline->num_chq = $num_chq;
629  }
630 
631  if ($emetteur) {
632  $accline->emetteur = $emetteur;
633  }
634 
635  if ($banque) {
636  $accline->bank_chq = $banque;
637  }
638 
639  if ($accline->insert() > 0) {
640  if ($categorie > 0) {
641  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class(";
642  $sql .= "lineid, fk_categ";
643  $sql .= ") VALUES (";
644  $sql .= ((int) $accline->id).", '".$this->db->escape($categorie)."'";
645  $sql .= ")";
646 
647  $result = $this->db->query($sql);
648  if (!$result) {
649  $this->error = $this->db->lasterror();
650  $this->db->rollback();
651 
652  return -4;
653  }
654  }
655 
656  $this->db->commit();
657 
658  return $accline->id;
659  } else {
660  $this->error = $accline->error;
661  $this->errors = $accline->errors;
662  $this->db->rollback();
663 
664  return -5;
665  }
666  }
667 
675  public function create(User $user, $notrigger = 0)
676  {
677  global $langs, $conf;
678 
679  $error = 0;
680 
681  // Clean parameters
682  if (!$this->min_allowed) {
683  $this->min_allowed = 0;
684  }
685  if (!$this->min_desired) {
686  $this->min_desired = 0;
687  }
688 
689  // Check parameters
690  if (empty($this->country_id)) {
691  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
692  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
693  return -1;
694  }
695  if (empty($this->ref)) {
696  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
697  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
698  return -1;
699  }
700  if (empty($this->date_solde)) {
701  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
702  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
703  return -1;
704  }
705 
706  $balance = $this->balance;
707  if (empty($balance) && !empty($this->solde)) {
708  $balance = $this->solde;
709  }
710  if (empty($balance)) {
711  $balance = 0;
712  }
713 
714  // Chargement librairie pour acces fonction controle RIB
715  require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
716 
717  $now = dol_now();
718 
719  $this->db->begin();
720 
721  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
722  $sql .= "datec";
723  $sql .= ", ref";
724  $sql .= ", label";
725  $sql .= ", entity";
726  $sql .= ", account_number";
727  $sql .= ", fk_accountancy_journal";
728  $sql .= ", bank";
729  $sql .= ", code_banque";
730  $sql .= ", code_guichet";
731  $sql .= ", number";
732  $sql .= ", cle_rib";
733  $sql .= ", bic";
734  $sql .= ", iban_prefix";
735  $sql .= ", domiciliation";
736  $sql .= ", pti_in_ctti";
737  $sql .= ", proprio";
738  $sql .= ", owner_address";
739  $sql .= ", owner_zip";
740  $sql .= ", owner_town";
741  $sql .= ", owner_country_id";
742  $sql .= ", currency_code";
743  $sql .= ", rappro";
744  $sql .= ", min_allowed";
745  $sql .= ", min_desired";
746  $sql .= ", comment";
747  $sql .= ", state_id";
748  $sql .= ", fk_pays";
749  $sql .= ", ics";
750  $sql .= ", ics_transfer";
751  $sql .= ") VALUES (";
752  $sql .= "'".$this->db->idate($now)."'";
753  $sql .= ", '".$this->db->escape($this->ref)."'";
754  $sql .= ", '".$this->db->escape($this->label)."'";
755  $sql .= ", ".((int) $conf->entity);
756  $sql .= ", '".$this->db->escape($this->account_number)."'";
757  $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
758  $sql .= ", '".$this->db->escape($this->bank)."'";
759  $sql .= ", '".$this->db->escape($this->code_banque)."'";
760  $sql .= ", '".$this->db->escape($this->code_guichet)."'";
761  $sql .= ", '".$this->db->escape($this->number)."'";
762  $sql .= ", '".$this->db->escape($this->cle_rib)."'";
763  $sql .= ", '".$this->db->escape($this->bic)."'";
764  $sql .= ", '".$this->db->escape($this->iban)."'";
765  $sql .= ", '".$this->db->escape($this->domiciliation)."'";
766  $sql .= ", ".((int) $this->pti_in_ctti);
767  $sql .= ", '".$this->db->escape($this->proprio)."'";
768  $sql .= ", '".$this->db->escape($this->owner_address)."'";
769  $sql .= ", '".$this->db->escape($this->owner_zip)."'";
770  $sql .= ", '".$this->db->escape($this->owner_town)."'";
771  $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
772  $sql .= ", '".$this->db->escape($this->currency_code)."'";
773  $sql .= ", ".((int) $this->rappro);
774  $sql .= ", ".price2num($this->min_allowed, 'MT');
775  $sql .= ", ".price2num($this->min_desired, 'MT');
776  $sql .= ", '".$this->db->escape($this->comment)."'";
777  $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
778  $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
779  $sql .= ", '".$this->db->escape($this->ics)."'";
780  $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
781  $sql .= ")";
782 
783  dol_syslog(get_class($this)."::create", LOG_DEBUG);
784  $resql = $this->db->query($sql);
785  if ($resql) {
786  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
787 
788  $result = $this->update($user, 1);
789  if ($result > 0) {
790  $accline = new AccountLine($this->db);
791  $accline->datec = $this->db->idate($now);
792  $accline->label = '('.$langs->trans("InitialBankBalance").')';
793  $accline->amount = price2num($balance);
794  $accline->fk_user_author = $user->id;
795  $accline->fk_account = $this->id;
796  $accline->datev = $this->db->idate($this->date_solde);
797  $accline->dateo = $this->db->idate($this->date_solde);
798  $accline->fk_type = 'SOLD';
799 
800  if ($accline->insert() < 0) {
801  $error++;
802  $this->error = $accline->error;
803  $this->errors = $accline->errors;
804  }
805 
806  if (!$error) {
807  $result = $this->insertExtraFields();
808  if ($result < 0) {
809  $error++;
810  }
811  }
812 
813  if (!$error && !$notrigger) {
814  // Call trigger
815  $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
816  if ($result < 0) {
817  $error++;
818  }
819  // End call triggers
820  }
821  } else {
822  $error++;
823  }
824  } else {
825  if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
826  $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
827  $error++;
828  } else {
829  $this->error = $this->db->error()." sql=".$sql;
830  $error++;
831  }
832  }
833 
834  if (!$error) {
835  $this->db->commit();
836  return $this->id;
837  } else {
838  $this->db->rollback();
839  return -1 * $error;
840  }
841  }
842 
850  public function update(User $user, $notrigger = 0)
851  {
852  global $langs, $conf;
853 
854  $error = 0;
855 
856  $this->db->begin();
857 
858  // Check parameters
859  if (empty($this->country_id)) {
860  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
861  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
862  return -1;
863  }
864  if (empty($this->ref)) {
865  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
866  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
867  return -1;
868  }
869  if (!$this->label) {
870  $this->label = "???";
871  }
872 
873  $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
874 
875  $sql .= " ref = '".$this->db->escape($this->ref)."'";
876  $sql .= ",label = '".$this->db->escape($this->label)."'";
877 
878  $sql .= ",courant = ".((int) $this->courant);
879  $sql .= ",clos = ".((int) $this->clos);
880  $sql .= ",rappro = ".((int) $this->rappro);
881  $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
882  $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
883  $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
884  $sql .= ",bank = '".$this->db->escape($this->bank)."'";
885  $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
886  $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
887  $sql .= ",number='".$this->db->escape($this->number)."'";
888  $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
889  $sql .= ",bic='".$this->db->escape($this->bic)."'";
890  $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
891  $sql .= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
892  $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
893  $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
894  $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
895  $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
896  $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
897  $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
898 
899  $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
900 
901  $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
902  $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
903  $sql .= ",comment = '".$this->db->escape($this->comment)."'";
904 
905  $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
906  $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
907  $sql .= ",ics = '".$this->db->escape($this->ics)."'";
908  $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
909 
910  $sql .= " WHERE rowid = ".((int) $this->id);
911 
912  dol_syslog(get_class($this)."::update", LOG_DEBUG);
913  $result = $this->db->query($sql);
914  if ($result) {
915  // Actions on extra fields (by external module or standard code)
916  if (!$error) {
917  $result = $this->insertExtraFields();
918  if ($result < 0) {
919  $error++;
920  }
921  }
922 
923  if (!$error && !$notrigger) {
924  // Call trigger
925  $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
926  if ($result < 0) {
927  $error++;
928  }
929  // End call triggers
930  }
931  } else {
932  $error++;
933  $this->error = $this->db->lasterror();
934  dol_print_error($this->db);
935  }
936 
937  if (!$error) {
938  $this->db->commit();
939  return $this->id;
940  } else {
941  $this->db->rollback();
942  return -1 * $error;
943  }
944  }
945 
946 
947  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
954  public function update_bban(User $user = null)
955  {
956  // phpcs:enable
957  global $conf, $langs;
958 
959  // Load library to get BAN control function
960  require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
961 
962  dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
963 
964  // Check parameters
965  if (!$this->ref) {
966  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
967  return -2;
968  }
969 
970  $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
971  $sql .= " bank = '".$this->db->escape($this->bank)."'";
972  $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
973  $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
974  $sql .= ",number='".$this->db->escape($this->number)."'";
975  $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
976  $sql .= ",bic='".$this->db->escape($this->bic)."'";
977  $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
978  $sql .= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
979  $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
980  $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
981  $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
982  $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
983  $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
984  $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
985  $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
986  $sql .= " WHERE rowid = ".((int) $this->id);
987  $sql .= " AND entity = ".((int) $conf->entity);
988 
989  dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
990 
991  $result = $this->db->query($sql);
992  if ($result) {
993  return 1;
994  } else {
995  $this->error = $this->db->lasterror();
996  dol_print_error($this->db);
997  return -1;
998  }
999  }
1000 
1001 
1009  public function fetch($id, $ref = '')
1010  {
1011  if (empty($id) && empty($ref)) {
1012  $this->error = "ErrorBadParameters";
1013  return -1;
1014  }
1015 
1016  $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant, ba.clos, ba.rappro, ba.url,";
1017  $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1018  $sql .= " ba.domiciliation as address, ba.pti_in_ctti, ba.proprio, ba.owner_address, ba.owner_zip, ba.owner_town, ba.owner_country_id, ba.state_id, ba.fk_pays as country_id,";
1019  $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1020  $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1021  $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1022  $sql .= ' c.code as country_code, c.label as country,';
1023  $sql .= ' d.code_departement as state_code, d.nom as state,';
1024  $sql .= ' aj.code as accountancy_journal';
1025  $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1026  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1027  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1028  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1029  $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1030  if ($id) {
1031  $sql .= " AND ba.rowid = ".((int) $id);
1032  }
1033  if ($ref) {
1034  $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1035  }
1036 
1037  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1038  $result = $this->db->query($sql);
1039  if ($result) {
1040  if ($this->db->num_rows($result)) {
1041  $obj = $this->db->fetch_object($result);
1042 
1043  $this->id = $obj->rowid;
1044  $this->rowid = $obj->rowid;
1045  $this->ref = $obj->ref;
1046  $this->label = $obj->label;
1047  $this->type = $obj->courant;
1048  $this->courant = $obj->courant;
1049  $this->bank = $obj->bank;
1050  $this->clos = $obj->clos;
1051  $this->rappro = $obj->rappro;
1052  $this->url = $obj->url;
1053 
1054  $this->code_banque = $obj->code_banque;
1055  $this->code_guichet = $obj->code_guichet;
1056  $this->number = $obj->number;
1057  $this->cle_rib = $obj->cle_rib;
1058  $this->bic = $obj->bic;
1059  $this->iban = $obj->iban;
1060  $this->domiciliation = $obj->address;
1061  $this->address = $obj->address;
1062  $this->pti_in_ctti = $obj->pti_in_ctti;
1063  $this->proprio = $obj->proprio;
1064  $this->owner_address = $obj->owner_address;
1065  $this->owner_zip = $obj->owner_zip;
1066  $this->owner_town = $obj->owner_town;
1067  $this->owner_country_id = $obj->owner_country_id;
1068 
1069  $this->state_id = $obj->state_id;
1070  $this->state_code = $obj->state_code;
1071  $this->state = $obj->state;
1072 
1073  $this->country_id = $obj->country_id;
1074  $this->country_code = $obj->country_code;
1075  $this->country = $obj->country;
1076 
1077  $this->account_number = $obj->account_number;
1078  $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1079  $this->accountancy_journal = $obj->accountancy_journal;
1080 
1081  $this->currency_code = $obj->currency_code;
1082  $this->account_currency_code = $obj->currency_code;
1083  $this->min_allowed = $obj->min_allowed;
1084  $this->min_desired = $obj->min_desired;
1085  $this->comment = $obj->comment;
1086 
1087  $this->date_creation = $this->db->jdate($obj->date_creation);
1088  $this->date_modification = $this->db->jdate($obj->date_modification);
1089  $this->date_update = $this->date_modification; // For compatibility
1090 
1091  $this->ics = $obj->ics;
1092  $this->ics_transfer = $obj->ics_transfer;
1093 
1094  // Retrieve all extrafield
1095  // fetch optionals attributes and labels
1096  $this->fetch_optionals();
1097 
1098  return 1;
1099  } else {
1100  return 0;
1101  }
1102  } else {
1103  $this->error = $this->db->lasterror();
1104  $this->errors[] = $this->error;
1105  return -1;
1106  }
1107  }
1108 
1119  public function setCategories($categories)
1120  {
1121  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1122  return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1123  }
1124 
1131  public function delete(User $user = null)
1132  {
1133  $error = 0;
1134 
1135  $this->db->begin();
1136 
1137  // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1138 
1139  // Delete link between tag and bank account
1140  if (!$error) {
1141  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1142  $sql .= " WHERE fk_account = ".((int) $this->id);
1143 
1144  $resql = $this->db->query($sql);
1145  if (!$resql) {
1146  $error++;
1147  $this->error = "Error ".$this->db->lasterror();
1148  }
1149  }
1150 
1151  if (!$error) {
1152  $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1153  $sql .= " WHERE rowid = ".((int) $this->id);
1154 
1155  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1156  $result = $this->db->query($sql);
1157  if ($result) {
1158  // Remove extrafields
1159  if (!$error) {
1160  $result = $this->deleteExtraFields();
1161  if ($result < 0) {
1162  $error++;
1163  dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1164  }
1165  }
1166  } else {
1167  $error++;
1168  $this->error = "Error ".$this->db->lasterror();
1169  }
1170  }
1171 
1172  if (!$error) {
1173  $this->db->commit();
1174  return 1;
1175  } else {
1176  $this->db->rollback();
1177  return -1;
1178  }
1179  }
1180 
1181 
1188  public function getLibStatut($mode = 0)
1189  {
1190  return $this->LibStatut($this->clos, $mode);
1191  }
1192 
1193  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1201  public function LibStatut($status, $mode = 0)
1202  {
1203  // phpcs:enable
1204  global $langs;
1205  $langs->load('banks');
1206 
1207  if ($status == self::STATUS_OPEN) {
1208  $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1209  $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1210  $statusType = 'status4';
1211  } else {
1212  $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1213  $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1214  $statusType = 'status5';
1215  }
1216 
1217  return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1218  }
1219 
1220 
1221  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1227  public function can_be_deleted()
1228  {
1229  // phpcs:enable
1230  $can_be_deleted = false;
1231 
1232  $sql = "SELECT COUNT(rowid) as nb";
1233  $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1234  $sql .= " WHERE fk_account = ".((int) $this->id);
1235 
1236  $resql = $this->db->query($sql);
1237  if ($resql) {
1238  $obj = $this->db->fetch_object($resql);
1239  if ($obj->nb <= 1) {
1240  $can_be_deleted = true; // Juste le solde
1241  }
1242  } else {
1243  dol_print_error($this->db);
1244  }
1245  return $can_be_deleted;
1246  }
1247 
1248 
1254  public function error()
1255  {
1256  return $this->error;
1257  }
1258 
1267  public function solde($option = 0, $date_end = '', $field = 'dateo')
1268  {
1269  $solde = 0;
1270 
1271  $sql = "SELECT sum(amount) as amount";
1272  $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1273  $sql .= " WHERE fk_account = ".((int) $this->id);
1274  if ($option == 1) {
1275  $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1276  }
1277 
1278  $resql = $this->db->query($sql);
1279  if ($resql) {
1280  if ($this->db->num_rows($resql)) {
1281  $obj = $this->db->fetch_object($resql);
1282  $solde = $obj->amount;
1283  }
1284  $this->db->free($resql);
1285  } else {
1286  $this->errors[] = $this->db->lasterror;
1287  return -1;
1288  }
1289 
1290  return price2num($solde, 'MU');
1291  }
1292 
1293  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1301  public function load_board(User $user, $filteraccountid = 0)
1302  {
1303  // phpcs:enable
1304  global $conf, $langs;
1305 
1306  if ($user->socid) {
1307  return -1; // protection pour eviter appel par utilisateur externe
1308  }
1309 
1310  $sql = "SELECT b.rowid, b.datev as datefin";
1311  $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1312  $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1313  $sql .= " WHERE b.rappro=0";
1314  $sql .= " AND b.fk_account = ba.rowid";
1315  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1316  $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1317  $sql .= " AND clos = 0";
1318  if ($filteraccountid) {
1319  $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1320  }
1321 
1322  $resql = $this->db->query($sql);
1323  if ($resql) {
1324  $langs->load("banks");
1325  $now = dol_now();
1326 
1327  require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1328 
1329  $response = new WorkboardResponse();
1330  $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1331  $response->label = $langs->trans("TransactionsToConciliate");
1332  $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1333  $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1334  $response->img = img_object('', "payment");
1335 
1336  while ($obj = $this->db->fetch_object($resql)) {
1337  $response->nbtodo++;
1338  if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1339  $response->nbtodolate++;
1340  }
1341  }
1342 
1343  return $response;
1344  } else {
1345  dol_print_error($this->db);
1346  $this->error = $this->db->error();
1347  return -1;
1348  }
1349  }
1350 
1351  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1358  public function load_state_board($filteraccountid = 0)
1359  {
1360  // phpcs:enable
1361  global $user;
1362 
1363  if ($user->socid) {
1364  return -1; // protection pour eviter appel par utilisateur externe
1365  }
1366 
1367  $sql = "SELECT count(b.rowid) as nb";
1368  $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1369  $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1370  $sql .= " WHERE b.fk_account = ba.rowid";
1371  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1372  $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1373  $sql .= " AND clos = 0";
1374  if ($filteraccountid) {
1375  $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1376  }
1377 
1378  $resql = $this->db->query($sql);
1379  if ($resql) {
1380  while ($obj = $this->db->fetch_object($resql)) {
1381  $this->nb["banklines"] = $obj->nb;
1382  }
1383  $this->db->free($resql);
1384  return 1;
1385  } else {
1386  dol_print_error($this->db);
1387  $this->error = $this->db->error();
1388  return -1;
1389  }
1390  }
1391 
1392 
1398  public function countAccountToReconcile()
1399  {
1400  global $db, $conf, $user;
1401 
1402  //Protection against external users
1403  if ($user->socid) {
1404  return 0;
1405  }
1406 
1407  $nb = 0;
1408 
1409  $sql = "SELECT COUNT(ba.rowid) as nb";
1410  $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1411  $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1412  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1413  if (empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) {
1414  $sql .= " AND ba.courant != 2";
1415  }
1416  $resql = $this->db->query($sql);
1417  if ($resql) {
1418  $obj = $this->db->fetch_object($resql);
1419  $nb = $obj->nb;
1420  } else {
1421  dol_print_error($this->db);
1422  }
1423 
1424  return $nb;
1425  }
1426 
1434  public function getTooltipContentArray($params)
1435  {
1436  global $langs;
1437  $langs->loadLangs(['banks', 'compta']);
1438  include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1439 
1440  $datas = array();
1441 
1442  $nofetch = !empty($params['nofetch']);
1443  $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1444  if (isset($this->status)) {
1445  $pictos .= ' '.$this->getLibStatut(5);
1446  }
1447  $datas['picto'] = $pictos;
1448  $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1449  $datas['accountnumber'] = '<br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1450  $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1451  $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1452  $datas['accountcurrency'] = '<br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1453 
1454  if (isModEnabled('accounting')) {
1455  include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1456  $langs->load("accountancy");
1457  $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1458  $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1459  }
1460  // show categories for this record only in ajax to not overload lists
1461  if (isModEnabled('categorie') && !$nofetch) {
1462  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1463  $form = new Form($this->db);
1464  $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1465  }
1466 
1467  return $datas;
1468  }
1469 
1481  public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1482  {
1483  global $conf, $langs;
1484 
1485  if (!empty($conf->dol_no_mouse_hover)) {
1486  $notooltip = 1; // Force disable tooltips
1487  }
1488 
1489  include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1490 
1491  $result = '';
1492  $classfortooltip = 'classfortooltip';
1493  $dataparams = '';
1494  $params = [
1495  'id' => $this->id,
1496  'objecttype' => $this->element,
1497  'option' => $option,
1498  'nofetch' => 1,
1499  ];
1500  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1501  $classfortooltip = 'classforajaxtooltip';
1502  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1503  $label = '';
1504  } else {
1505  $label = implode($this->getTooltipContentArray($params));
1506  }
1507 
1508  $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1509  if ($mode == 'transactions') {
1510  $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1511  } elseif ($mode == 'receipts') {
1512  $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1513  }
1514 
1515  if ($option != 'nolink') {
1516  // Add param to save lastsearch_values or not
1517  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1518  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1519  $add_save_lastsearch_values = 1;
1520  }
1521  if ($add_save_lastsearch_values) {
1522  $url .= '&save_lastsearch_values=1';
1523  }
1524  }
1525 
1526  $linkclose = '';
1527  if (empty($notooltip)) {
1528  if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1529  $label = $langs->trans("BankAccount");
1530  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1531  }
1532  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1533  $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1534  } else {
1535  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1536  }
1537 
1538  if ($option == 'nolink' || empty($url)) {
1539  $linkstart = '<span';
1540  } else {
1541  $linkstart = '<a href="'.$url.'"';
1542  }
1543  $linkstart .= $linkclose.'>';
1544  if ($option == 'nolink' || empty($url)) {
1545  $linkend = '</span>';
1546  } else {
1547  $linkend = '</a>';
1548  }
1549 
1550  $result .= $linkstart;
1551 
1552  if ($withpicto) {
1553  $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1554  }
1555  if ($withpicto != 2) {
1556  $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1557  }
1558  $result .= $linkend;
1559 
1560  return $result;
1561  }
1562 
1563 
1564  // Method after here are common to Account and CompanyBankAccount
1565 
1566 
1572  public function verif()
1573  {
1574  require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1575 
1576  $this->error_number = 0;
1577 
1578  // Call function to check BAN
1579 
1580  if (!checkIbanForAccount($this)) {
1581  $this->error_number = 12;
1582  $this->error_message = 'IBANNotValid';
1583  }
1584  if (!checkSwiftForAccount($this)) {
1585  $this->error_number = 12;
1586  $this->error_message = 'SwiftNotValid';
1587  }
1588  /*if (! checkBanForAccount($this))
1589  {
1590  $this->error_number = 12;
1591  $this->error_message = 'BANControlError';
1592  }*/
1593 
1594  if ($this->error_number == 0) {
1595  return 1;
1596  } else {
1597  return 0;
1598  }
1599  }
1600 
1606  public function getCountryCode()
1607  {
1608  global $mysoc;
1609 
1610  // We return country code of bank account
1611  if (!empty($this->country_code)) {
1612  return $this->country_code;
1613  }
1614 
1615  // For backward compatibility, we try to guess country from other information
1616  if (!empty($this->iban)) {
1617  // If IBAN defined, we can know country of account from it
1618  $reg = array();
1619  if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1620  return $reg[1];
1621  }
1622  }
1623 
1624  // If this class is linked to a third party
1625  if (!empty($this->socid)) {
1626  require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1627  $company = new Societe($this->db);
1628  $result = $company->fetch($this->socid);
1629  if (!empty($company->country_code)) {
1630  return $company->country_code;
1631  }
1632  }
1633 
1634  // We return country code of managed company
1635  if (!empty($mysoc->country_code)) {
1636  return $mysoc->country_code;
1637  }
1638 
1639  return '';
1640  }
1641 
1650  public function useDetailedBBAN()
1651  {
1652  $country_code = $this->getCountryCode();
1653 
1654  if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1655  return 1; // France, Spain, Gabon, ... - Not valid for CH
1656  }
1657  if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1658  return 2; // Australia, England...
1659  }
1660  return 0;
1661  }
1662 
1668  public function needIBAN()
1669  {
1670  global $conf;
1671 
1672  if (!empty($conf->global->MAIN_IBAN_IS_NEVER_MANDATORY)) {
1673  return 0;
1674  }
1675 
1676  $country_code = $this->getCountryCode();
1677 
1678  $country_code_in_EEC = array(
1679  'AT', // Austria
1680  'BE', // Belgium
1681  'BG', // Bulgaria
1682  'CY', // Cyprus
1683  'CZ', // Czech republic
1684  'DE', // Germany
1685  'DK', // Danemark
1686  'EE', // Estonia
1687  'ES', // Spain
1688  'FI', // Finland
1689  'FR', // France
1690  'GB', // United Kingdom
1691  'GR', // Greece
1692  'HR', // Croatia
1693  'NL', // Holland
1694  'HU', // Hungary
1695  'IE', // Ireland
1696  'IM', // Isle of Man - Included in UK
1697  'IT', // Italy
1698  'LT', // Lithuania
1699  'LU', // Luxembourg
1700  'LV', // Latvia
1701  'MC', // Monaco - Included in France
1702  'MT', // Malta
1703  //'NO', // Norway
1704  'PL', // Poland
1705  'PT', // Portugal
1706  'RO', // Romania
1707  'SE', // Sweden
1708  'SK', // Slovakia
1709  'SI', // Slovenia
1710  'UK', // United Kingdom
1711  //'CH', // Switzerland - No. Swizerland in not in EEC
1712  );
1713 
1714  if (in_array($country_code, $country_code_in_EEC)) {
1715  return 1; // France, Spain, ...
1716  }
1717  return 0;
1718  }
1719 
1726  public function info($id)
1727  {
1728  }
1729 
1744  public function getFieldsToShow($includeibanbic = 0)
1745  {
1746  //Get the required properties depending on the country
1747  $detailedBBAN = $this->useDetailedBBAN();
1748 
1749  if ($detailedBBAN == 0) {
1750  $fieldarray = array(
1751  'BankAccountNumber'
1752  );
1753  } elseif ($detailedBBAN == 2) {
1754  $fieldarray = array(
1755  'BankCode',
1756  'BankAccountNumber'
1757  );
1758  } else {
1759  $fieldarray = self::getAccountNumberOrder();
1760  }
1761 
1762  //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1763  if ($includeibanbic) {
1764  $fieldarray[] = 'IBAN';
1765  $fieldarray[] = 'BIC';
1766  }
1767  //}
1768 
1769  //Get the order the properties are shown
1770  return $fieldarray;
1771  }
1772 
1783  public static function getAccountNumberOrder()
1784  {
1785  global $conf;
1786 
1787  $fieldlists = array(
1788  'BankCode',
1789  'DeskCode',
1790  'BankAccountNumber',
1791  'BankAccountNumberKey'
1792  );
1793 
1794  if (!empty($conf->global->BANK_SHOW_ORDER_OPTION)) {
1795  if (is_numeric($conf->global->BANK_SHOW_ORDER_OPTION)) {
1796  if ($conf->global->BANK_SHOW_ORDER_OPTION == '1') {
1797  $fieldlists = array(
1798  'BankCode',
1799  'DeskCode',
1800  'BankAccountNumberKey',
1801  'BankAccountNumber'
1802  );
1803  }
1804  } else {
1805  //Replace the old AccountNumber key with the new BankAccountNumber key
1806  $fieldlists = explode(
1807  ' ',
1808  preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1809  );
1810  }
1811  }
1812 
1813  return $fieldlists;
1814  }
1815 
1816 
1824  public function initAsSpecimen()
1825  {
1826  // Example of IBAN FR7630001007941234567890185
1827  $this->specimen = 1;
1828  $this->ref = 'MBA';
1829  $this->label = 'My Big Company Bank account';
1830  $this->bank = 'MyBank';
1831  $this->courant = Account::TYPE_CURRENT;
1832  $this->clos = Account::STATUS_OPEN;
1833  $this->code_banque = '30001';
1834  $this->code_guichet = '00794';
1835  $this->number = '12345678901';
1836  $this->cle_rib = '85';
1837  $this->bic = 'AA12';
1838  $this->iban = 'FR7630001007941234567890185';
1839  $this->domiciliation = 'Banque de France';
1840  $this->proprio = 'Owner';
1841  $this->owner_address = 'Owner address';
1842  $this->owner_zip = 'Owner zip';
1843  $this->owner_town = 'Owner town';
1844  $this->owner_country_id = 'Owner country_id';
1845  $this->country_id = 1;
1846  }
1847 
1856  public static function replaceThirdparty($dbs, $origin_id, $dest_id)
1857  {
1858  $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'";
1859 
1860  if ($dbs->query($sql)) {
1861  return true;
1862  } else {
1863  //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.
1864  //$this->errors = $dbs->lasterror();
1865  return false;
1866  }
1867  }
1868 
1876  public function getKanbanView($option = '', $arraydata = null)
1877  {
1878  global $langs;
1879 
1880  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1881 
1882  $return = '<div class="box-flex-item box-flex-grow-zero">';
1883  $return .= '<div class="info-box info-box-sm">';
1884  $return .= '<span class="info-box-icon bg-infobox-action">';
1885  $return .= img_picto('', $this->picto);
1886  $return .= '</span>';
1887  $return .= '<div class="info-box-content">';
1888  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1889  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1890 
1891  if (property_exists($this, 'type_lib')) {
1892  $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
1893  }
1894  if (method_exists($this, 'solde')) {
1895  $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
1896  $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>';
1897  }
1898  if (method_exists($this, 'getLibStatut')) {
1899  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
1900  }
1901  $return .= '</div>';
1902  $return .= '</div>';
1903  $return .= '</div>';
1904  return $return;
1905  }
1906 }
1907 
1908 
1909 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1910 
1915 {
1919  public $error = '';
1920 
1924  public $db;
1925 
1929  public $element = 'bank';
1930 
1934  public $table_element = 'bank';
1935 
1939  public $picto = 'accountline';
1940 
1944  public $id;
1945 
1949  public $ref;
1950 
1956  public $datec;
1957 
1963  public $dateo;
1964 
1970  public $datev;
1971 
1972  public $amount; /* Amount of payment in the bank account currency */
1973  public $amount_main_currency; /* Amount in the currency of company if bank account use another currency */
1974 
1978  public $fk_user_author;
1979 
1983  public $fk_user_rappro;
1984 
1988  public $fk_type;
1989 
1993  public $fk_bordereau;
1994 
1998  public $fk_account;
1999 
2003  public $bank_account_ref;
2004 
2008  public $bank_account_label;
2009 
2013  public $numero_compte;
2014 
2018  public $emetteur;
2019 
2020  public $rappro; // Is it conciliated
2021  public $num_releve; // If conciliated, what is bank statement
2022  public $num_chq; // Num of cheque
2023  public $bank_chq; // Bank of cheque
2024 
2028  public $label;
2029 
2030  public $note;
2031 
2032 
2033 
2039  public function __construct(DoliDB $db)
2040  {
2041  $this->db = $db;
2042  }
2043 
2052  public function fetch($rowid, $ref = '', $num = '')
2053  {
2054  global $conf;
2055 
2056  // Check parameters
2057  if (empty($rowid) && empty($ref) && empty($num)) {
2058  return -1;
2059  }
2060 
2061  $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2062  $sql .= " b.fk_user_author, b.fk_user_rappro,";
2063  $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2064  $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2065  $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2066  $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2067  $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2068  $sql .= " WHERE b.fk_account = ba.rowid";
2069  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2070  if ($num) {
2071  $sql .= " AND b.num_chq='".$this->db->escape($num)."'";
2072  } elseif ($ref) {
2073  $sql .= " AND b.rowid='".$this->db->escape($ref)."'";
2074  } else {
2075  $sql .= " AND b.rowid = ".((int) $rowid);
2076  }
2077 
2078  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2079  $result = $this->db->query($sql);
2080  if ($result) {
2081  $ret = 0;
2082 
2083  $obj = $this->db->fetch_object($result);
2084  if ($obj) {
2085  $this->id = $obj->rowid;
2086  $this->rowid = $obj->rowid;
2087  $this->ref = $obj->rowid;
2088 
2089  $this->datec = $obj->datec;
2090  $this->datev = $obj->datev;
2091  $this->dateo = $obj->dateo;
2092  $this->amount = $obj->amount;
2093  $this->label = $obj->label;
2094  $this->note = $obj->note;
2095 
2096  $this->fk_user_author = $obj->fk_user_author;
2097  $this->fk_user_rappro = $obj->fk_user_rappro;
2098 
2099  $this->fk_type = $obj->fk_type; // Type of transaction
2100  $this->rappro = $obj->rappro;
2101  $this->num_releve = $obj->num_releve;
2102 
2103  $this->num_chq = $obj->num_chq;
2104  $this->bank_chq = $obj->banque;
2105  $this->fk_bordereau = $obj->fk_bordereau;
2106 
2107  $this->fk_account = $obj->fk_account;
2108  $this->bank_account_ref = $obj->bank_account_ref;
2109  $this->bank_account_label = $obj->bank_account_label;
2110 
2111  // Retrieve all extrafield
2112  // fetch optionals attributes and labels
2113  $this->fetch_optionals();
2114 
2115  $ret = 1;
2116  }
2117  $this->db->free($result);
2118  return $ret;
2119  } else {
2120  return -1;
2121  }
2122  }
2123 
2129  public function insert()
2130  {
2131  $error = 0;
2132 
2133  $this->db->begin();
2134 
2135  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2136  $sql .= "datec";
2137  $sql .= ", dateo";
2138  $sql .= ", datev";
2139  $sql .= ", label";
2140  $sql .= ", amount";
2141  $sql .= ", amount_main_currency";
2142  $sql .= ", fk_user_author";
2143  $sql .= ", num_chq";
2144  $sql .= ", fk_account";
2145  $sql .= ", fk_type";
2146  $sql .= ", emetteur,banque";
2147  $sql .= ", rappro";
2148  $sql .= ", numero_compte";
2149  $sql .= ", num_releve";
2150  $sql .= ") VALUES (";
2151  $sql .= "'".$this->db->idate($this->datec)."'";
2152  $sql .= ", '".$this->db->idate($this->dateo)."'";
2153  $sql .= ", '".$this->db->idate($this->datev)."'";
2154  $sql .= ", '".$this->db->escape($this->label)."'";
2155  $sql .= ", ".price2num($this->amount);
2156  $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2157  $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2158  $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2159  $sql .= ", '".$this->db->escape($this->fk_account)."'";
2160  $sql .= ", '".$this->db->escape($this->fk_type)."'";
2161  $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2162  $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2163  $sql .= ", ".(int) $this->rappro;
2164  $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2165  $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2166  $sql .= ")";
2167 
2168  dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2169  $resql = $this->db->query($sql);
2170  if ($resql) {
2171  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2172  // Actions on extra fields (by external module or standard code)
2173  $result = $this->insertExtraFields();
2174  if ($result < 0) {
2175  $error++;
2176  }
2177  } else {
2178  $error++;
2179  $this->error = $this->db->lasterror();
2180  dol_print_error($this->db);
2181  }
2182 
2183  if (!$error) {
2184  $this->db->commit();
2185  return $this->id;
2186  } else {
2187  $this->db->rollback();
2188  return -1 * $error;
2189  }
2190  }
2191 
2198  public function delete(User $user = null)
2199  {
2200  global $conf;
2201 
2202  $nbko = 0;
2203 
2204  if ($this->rappro) {
2205  // Protection to avoid any delete of consolidated lines
2206  $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2207  return -1;
2208  }
2209 
2210  $this->db->begin();
2211 
2212  // Protection to avoid any delete of accounted lines. Protection on by default
2213  if (empty($conf->global->BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING)) {
2214  $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2215  $resql = $this->db->query($sql);
2216  if ($resql) {
2217  $obj = $this->db->fetch_object($resql);
2218  if ($obj && $obj->nb) {
2219  $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2220  $this->db->rollback();
2221  return -1;
2222  }
2223  } else {
2224  $this->error = $this->db->lasterror();
2225  $this->db->rollback();
2226  return -1;
2227  }
2228  }
2229 
2230  // Delete urls
2231  $result = $this->delete_urls($user);
2232  if ($result < 0) {
2233  $nbko++;
2234  }
2235 
2236  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid=".(int) $this->rowid;
2237  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2238  $result = $this->db->query($sql);
2239  if (!$result) {
2240  $nbko++;
2241  }
2242 
2243  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2244  $result = $this->db->query($sql);
2245  if (!$result) {
2246  $nbko++;
2247  }
2248 
2249  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2250  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2251  $result = $this->db->query($sql);
2252  if (!$result) {
2253  $nbko++;
2254  }
2255 
2256  if (!$nbko) {
2257  $this->db->commit();
2258  return 1;
2259  } else {
2260  $this->db->rollback();
2261  return -$nbko;
2262  }
2263  }
2264 
2265 
2266  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2273  public function delete_urls(User $user = null)
2274  {
2275  // phpcs:enable
2276  $nbko = 0;
2277 
2278  if ($this->rappro) {
2279  // Protection to avoid any delete of consolidated lines
2280  $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2281  return -1;
2282  }
2283 
2284  $this->db->begin();
2285 
2286  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2287  dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2288  $result = $this->db->query($sql);
2289  if (!$result) {
2290  $nbko++;
2291  }
2292 
2293  if (!$nbko) {
2294  $this->db->commit();
2295  return 1;
2296  } else {
2297  $this->db->rollback();
2298  return -$nbko;
2299  }
2300  }
2301 
2302 
2310  public function update(User $user, $notrigger = 0)
2311  {
2312  $this->db->begin();
2313 
2314  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2315  $sql .= " amount = ".price2num($this->amount).",";
2316  $sql .= " datev='".$this->db->idate($this->datev)."',";
2317  $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2318  $sql .= " WHERE rowid = ".((int) $this->rowid);
2319 
2320  dol_syslog(get_class($this)."::update", LOG_DEBUG);
2321  $resql = $this->db->query($sql);
2322  if ($resql) {
2323  $this->db->commit();
2324  return 1;
2325  } else {
2326  $this->db->rollback();
2327  $this->error = $this->db->error();
2328  return -1;
2329  }
2330  }
2331 
2332 
2333  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2342  public function update_conciliation(User $user, $cat, $conciliated = 1)
2343  {
2344  // phpcs:enable
2345  global $conf, $langs;
2346 
2347  $this->db->begin();
2348 
2349  // Check statement field
2350  if (!empty($conf->global->BANK_STATEMENT_REGEX_RULE)) {
2351  if (!preg_match('/'.$conf->global->BANK_STATEMENT_REGEX_RULE.'/', $this->num_releve)) {
2352  $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", $conf->global->BANK_STATEMENT_REGEX_RULE);
2353  return -1;
2354  }
2355  }
2356 
2357  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2358  $sql .= " rappro = ".((int) $conciliated);
2359  $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2360  if ($conciliated) {
2361  $sql .= ", fk_user_rappro = ".$user->id;
2362  }
2363  $sql .= " WHERE rowid = ".((int) $this->id);
2364 
2365  dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2366  $resql = $this->db->query($sql);
2367  if ($resql) {
2368  if (!empty($cat) && $cat > 0) {
2369  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
2370  $sql .= "lineid";
2371  $sql .= ", fk_categ";
2372  $sql .= ") VALUES (";
2373  $sql .= $this->id;
2374  $sql .= ", ".((int) $cat);
2375  $sql .= ")";
2376 
2377  dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2378  $this->db->query($sql);
2379 
2380  // No error check. Can fail if category already affected
2381  // TODO Do no try the insert if link already exists
2382  }
2383 
2384  $this->rappro = 1;
2385 
2386  $this->db->commit();
2387  return 1;
2388  } else {
2389  $this->db->rollback();
2390  return -1;
2391  }
2392  }
2393 
2394 
2395  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2403  public function datev_change($rowid, $sign = 1)
2404  {
2405  // phpcs:enable
2406  $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2407  $resql = $this->db->query($sql);
2408  if ($resql) {
2409  $obj = $this->db->fetch_object($resql);
2410  $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2411 
2412  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2413  $sql .= " datev = '".$this->db->idate($newdate)."'";
2414  $sql .= " WHERE rowid = ".((int) $rowid);
2415 
2416  $result = $this->db->query($sql);
2417  if ($result) {
2418  if ($this->db->affected_rows($result)) {
2419  return 1;
2420  }
2421  } else {
2422  dol_print_error($this->db);
2423  return 0;
2424  }
2425  } else {
2426  dol_print_error($this->db);
2427  }
2428  return 0;
2429  }
2430 
2431  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2438  public function datev_next($id)
2439  {
2440  // phpcs:enable
2441  return $this->datev_change($id, 1);
2442  }
2443 
2444  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2451  public function datev_previous($id)
2452  {
2453  // phpcs:enable
2454  return $this->datev_change($id, -1);
2455  }
2456 
2457 
2458  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2466  public function dateo_change($rowid, $sign = 1)
2467  {
2468  // phpcs:enable
2469  $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2470  $resql = $this->db->query($sql);
2471  if ($resql) {
2472  $obj = $this->db->fetch_object($resql);
2473  $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2474 
2475  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2476  $sql .= " dateo = '".$this->db->idate($newdate)."'";
2477  $sql .= " WHERE rowid = ".((int) $rowid);
2478 
2479  $result = $this->db->query($sql);
2480  if ($result) {
2481  if ($this->db->affected_rows($result)) {
2482  return 1;
2483  }
2484  } else {
2485  dol_print_error($this->db);
2486  return 0;
2487  }
2488  } else {
2489  dol_print_error($this->db);
2490  }
2491  return 0;
2492  }
2493 
2494  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2501  public function dateo_next($id)
2502  {
2503  // phpcs:enable
2504  return $this->dateo_change($id, 1);
2505  }
2506 
2507  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2514  public function dateo_previous($id)
2515  {
2516  // phpcs:enable
2517  return $this->dateo_change($id, -1);
2518  }
2519 
2520 
2527  public function info($id)
2528  {
2529  $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2530  $sql .= ' b.fk_user_author, b.fk_user_rappro';
2531  $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2532  $sql .= ' WHERE b.rowid = '.((int) $id);
2533 
2534  $result = $this->db->query($sql);
2535  if ($result) {
2536  if ($this->db->num_rows($result)) {
2537  $obj = $this->db->fetch_object($result);
2538  $this->id = $obj->rowid;
2539 
2540  if ($obj->fk_user_author) {
2541  $cuser = new User($this->db);
2542  $cuser->fetch($obj->fk_user_author);
2543  $this->user_creation = $cuser;
2544  }
2545  if ($obj->fk_user_rappro) {
2546  $ruser = new User($this->db);
2547  $ruser->fetch($obj->fk_user_rappro);
2548  $this->user_rappro = $ruser;
2549  }
2550 
2551  $this->date_creation = $this->db->jdate($obj->datec);
2552  $this->date_modification = $this->db->jdate($obj->datem);
2553  //$this->date_rappro = $obj->daterappro; // Not yet managed
2554  }
2555  $this->db->free($result);
2556  } else {
2557  dol_print_error($this->db);
2558  }
2559  }
2560 
2561 
2571  public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2572  {
2573  global $conf, $langs;
2574 
2575  $result = '';
2576 
2577  $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2578  $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2579  if ($this->amount) {
2580  $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2581  }
2582 
2583  $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">';
2584  $linkend = '</a>';
2585 
2586  $result .= $linkstart;
2587  if ($withpicto) {
2588  $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);
2589  }
2590  if ($withpicto != 2) {
2591  $result .= ($this->ref ? $this->ref : $this->id);
2592  }
2593 
2594  $result .= $linkend;
2595 
2596  if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2597  $result .= ' <span class="opacitymedium">(';
2598  }
2599  if ($option == 'showall') {
2600  $result .= $langs->trans("BankAccount").': ';
2601  $accountstatic = new Account($this->db);
2602  $accountstatic->id = $this->fk_account;
2603  $accountstatic->ref = $this->bank_account_ref;
2604  $accountstatic->label = $this->bank_account_label;
2605  $result .= $accountstatic->getNomUrl(0).', ';
2606  }
2607  if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2608  $result .= $langs->trans("BankLineConciliated").': ';
2609  $result .= yn($this->rappro);
2610  }
2611  if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2612  $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2613  $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2614  $resql = $this->db->query($sql);
2615  if ($resql) {
2616  $obj = $this->db->fetch_object($resql);
2617  if ($obj && $obj->nb) {
2618  $result .= ' - '.$langs->trans("Accounted").': '.yn(1);
2619  } else {
2620  $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2621  }
2622  }
2623  }
2624  if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2625  $result .= ')</span>';
2626  }
2627 
2628  return $result;
2629  }
2630 
2631 
2638  public function getLibStatut($mode = 0)
2639  {
2640  return $this->LibStatut($this->status, $mode);
2641  }
2642 
2643  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2651  public function LibStatut($status, $mode = 0)
2652  {
2653  // phpcs:enable
2654  //global $langs;
2655 
2656  //$langs->load('companies');
2657  /*
2658  if ($mode == 0)
2659  {
2660  if ($status==0) return $langs->trans("ActivityCeased");
2661  if ($status==1) return $langs->trans("InActivity");
2662  }
2663  if ($mode == 1)
2664  {
2665  if ($status==0) return $langs->trans("ActivityCeased");
2666  if ($status==1) return $langs->trans("InActivity");
2667  }
2668  if ($mode == 2)
2669  {
2670  if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2671  if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2672  }
2673  if ($mode == 3)
2674  {
2675  if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2676  if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2677  }
2678  if ($mode == 4)
2679  {
2680  if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2681  if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2682  }
2683  if ($mode == 5)
2684  {
2685  if ($status==0) return $langs->trans("ActivityCeased").' '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2686  if ($status==1) return $langs->trans("InActivity").' '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2687  }*/
2688 
2689  return '';
2690  }
2691 
2692 
2698  public function getVentilExportCompta()
2699  {
2700  $alreadydispatched = 0;
2701 
2702  $type = 'bank';
2703 
2704  $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);
2705  $resql = $this->db->query($sql);
2706  if ($resql) {
2707  $obj = $this->db->fetch_object($resql);
2708  if ($obj) {
2709  $alreadydispatched = $obj->nb;
2710  }
2711  } else {
2712  $this->error = $this->db->lasterror();
2713  return -1;
2714  }
2715 
2716  if ($alreadydispatched) {
2717  return 1;
2718  }
2719  return 0;
2720  }
2721 }
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
checkIbanForAccount(Account $account)
Check IBAN number informations for a bank account.
Definition: bank.lib.php:295
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition: bank.lib.php:317
checkSwiftForAccount($account)
Check SWIFT informations for a bank account.
Definition: bank.lib.php:279
$object ref
Definition: info.php:78
Class to manage bank accounts.
solde($option=0, $date_end='', $field='dateo')
Return current sold.
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.
static replaceThirdparty($dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
update(User $user, $notrigger=0)
Update bank account card.
getCountryCode()
Return account country code.
needIBAN()
Return 1 if IBAN / BIC is mandatory (otherwise option)
getLibStatut($mode=0)
Return label of object status.
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.
useDetailedBBAN()
Return if a bank account is defined with detailed information (bank code, desk code,...
static getAccountNumberOrder()
Returns the components of the bank account in order.
load_state_board($filteraccountid=0)
Charge indicateurs this->nb de tableau de bord.
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()
Renvoi si un compte peut etre supprimer ou non (sans mouvements)
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.
initAsSpecimen()
Initialise an instance with random values.
get_url($fk_bank='', $url_id='', $type='')
TODO Move this into AccountLine Return array with links from llx_bank_url.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
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)
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.
info($id)
Load miscellaneous information for tab "Info".
__construct(DoliDB $db)
Constructor.
update_conciliation(User $user, $cat, $conciliated=1)
Update conciliation field.
getLibStatut($mode=0)
Return the label of the status.
fetch($rowid, $ref='', $num='')
Load into memory content of a bank transaction line.
dateo_change($rowid, $sign=1)
Increase/decrease operation date of a rowid.
datev_next($id)
Increase value date of a rowid.
LibStatut($status, $mode=0)
Return the label of a given status.
update(User $user, $notrigger=0)
Update bank account record in database.
insert()
Inserts a transaction to a bank account.
getNomUrl($withpicto=0, $maxlen=0, $option='', $notooltip=0)
Return clickable name (with picto eventually)
delete_urls(User $user=null)
Delete bank line records.
getVentilExportCompta()
Return if a bank line was dispatched into bookkeeping.
datev_change($rowid, $sign=1)
Increase/decrease value date of a rowid.
dateo_previous($id)
Decrease operation date of a rowid.
dateo_next($id)
Increase operation date of a rowid.
datev_previous($id)
Decrease value date of a rowid.
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...
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.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
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.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120