dolibarr  19.0.0-dev
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 
55  public $picto = 'account';
56 
62  public $rowid;
63 
68  public $label;
69 
74  public $courant;
75 
80  public $type;
81 
86  public $bank;
87 
92  public $clos = self::STATUS_OPEN;
93 
98  public $rappro = 1;
99 
104  public $url;
105 
110  public $code_banque;
111 
116  public $code_guichet;
117 
122  public $number;
123 
128  public $cle_rib;
129 
134  public $bic;
135 
140  public $iban;
141 
148  public $iban_prefix;
149 
154  public $pti_in_ctti = 0;
155 
160  public $proprio;
161 
166  public $owner_address;
167  public $owner_zip;
168  public $owner_town;
169  public $owner_country_id;
170  public $owner_country_code;
171 
176  public $domiciliation; // deprecated, use now address
177  public $address;
178  public $state_id;
179  public $state_code;
180  public $state;
181 
187  public $type_lib = array();
188 
194  public $status = array();
195 
200  public $account_number;
201 
205  public $fk_accountancy_journal;
209  public $accountancy_journal;
210 
215  public $currency_code;
216 
222  public $account_currency_code;
223 
228  public $min_allowed;
229 
234  public $min_desired;
235 
240  public $comment;
241 
246  public $date_solde;
247 
254  public $solde;
255 
260  public $balance;
261 
266  public $ics;
267 
272  public $ics_transfer;
273 
274 
275 
300  // BEGIN MODULEBUILDER PROPERTIES
304  public $fields = array(
305  'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
306  'ref' =>array('type'=>'varchar(12)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>25),
307  'label' =>array('type'=>'varchar(30)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>30),
308  'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>35, 'index'=>1),
309  'bank' =>array('type'=>'varchar(60)', 'label'=>'Bank', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
310  'code_banque' =>array('type'=>'varchar(128)', 'label'=>'Code banque', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
311  'code_guichet' =>array('type'=>'varchar(6)', 'label'=>'Code guichet', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
312  'number' =>array('type'=>'varchar(255)', 'label'=>'Number', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
313  'cle_rib' =>array('type'=>'varchar(5)', 'label'=>'Cle rib', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
314  'bic' =>array('type'=>'varchar(11)', 'label'=>'Bic', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
315  'iban_prefix' =>array('type'=>'varchar(34)', 'label'=>'Iban prefix', 'enabled'=>1, 'visible'=>-1, 'position'=>70),
316  'country_iban' =>array('type'=>'varchar(2)', 'label'=>'Country iban', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
317  'cle_iban' =>array('type'=>'varchar(2)', 'label'=>'Cle iban', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
318  'domiciliation' =>array('type'=>'varchar(255)', 'label'=>'Domiciliation', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
319  'state_id' =>array('type'=>'integer', 'label'=>'StateId', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
320  'fk_pays' =>array('type'=>'integer', 'label'=>'Country', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>95),
321  'proprio' =>array('type'=>'varchar(60)', 'label'=>'Proprio', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
322  'owner_address' =>array('type'=>'varchar(255)', 'label'=>'Owner address', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
323  'owner_zip' =>array('type'=>'varchar(25)', 'label'=>'Owner zip', 'enabled'=>1, 'visible'=>-1, 'position'=>106),
324  'owner_town' =>array('type'=>'varchar(50)', 'label'=>'Owner town', 'enabled'=>1, 'visible'=>-1, 'position'=>107),
325  'owner_country_id' =>array('type'=>'integer', 'label'=>'Owner country', 'enabled'=>1, 'visible'=>-1, 'position'=>108),
326  'courant' =>array('type'=>'smallint(6)', 'label'=>'Courant', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>110),
327  'clos' =>array('type'=>'smallint(6)', 'label'=>'Clos', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>115),
328  'rappro' =>array('type'=>'smallint(6)', 'label'=>'Rappro', 'enabled'=>1, 'visible'=>-1, 'position'=>120),
329  'url' =>array('type'=>'varchar(128)', 'label'=>'Url', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
330  'account_number' =>array('type'=>'varchar(32)', 'label'=>'Account number', 'enabled'=>1, 'visible'=>-1, 'position'=>130),
331  'fk_accountancy_journal' =>array('type'=>'integer', 'label'=>'Accountancy journal ID', 'enabled'=>1, 'visible'=>-1, 'position'=>132),
332  'accountancy_journal' =>array('type'=>'varchar(20)', 'label'=>'Accountancy journal', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
333  'currency_code' =>array('type'=>'varchar(3)', 'label'=>'Currency code', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>140),
334  'min_allowed' =>array('type'=>'integer', 'label'=>'Min allowed', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
335  'min_desired' =>array('type'=>'integer', 'label'=>'Min desired', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
336  'comment' =>array('type'=>'text', 'label'=>'Comment', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
337  'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>156),
338  'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>157),
339  'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>160),
340  'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>165),
341  'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170),
342  'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>175),
343  'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>180),
344  'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
345  );
346  // END MODULEBUILDER PROPERTIES
347 
351  const TYPE_CURRENT = 1;
355  const TYPE_CASH = 2;
359  const TYPE_SAVINGS = 0;
360 
361 
362  const STATUS_OPEN = 0;
363  const STATUS_CLOSED = 1;
364 
365 
371  public function __construct(DoliDB $db)
372  {
373  global $langs;
374 
375  $this->db = $db;
376 
377  $this->solde = 0;
378 
379  $this->type_lib = array(
380  self::TYPE_SAVINGS => $langs->trans("BankType0"),
381  self::TYPE_CURRENT => $langs->trans("BankType1"),
382  self::TYPE_CASH => $langs->trans("BankType2"),
383  );
384 
385  $this->status = array(
386  self::STATUS_OPEN => $langs->trans("StatusAccountOpened"),
387  self::STATUS_CLOSED => $langs->trans("StatusAccountClosed")
388  );
389  }
390 
396  public function __toString()
397  {
398  $string = '';
399  foreach ($this->getFieldsToShow() as $val) {
400  if ($val == 'BankCode') {
401  $string .= $this->code_banque.' ';
402  } elseif ($val == 'BankAccountNumber') {
403  $string .= $this->number.' ';
404  } elseif ($val == 'DeskCode') {
405  $string .= $this->code_guichet.' ';
406  } elseif ($val == 'BankAccountNumberKey') {
407  $string .= $this->cle_rib.' ';
408  } elseif ($val == 'BIC') {
409  $string .= $this->bic.' ';
410  } elseif ($val == 'IBAN') {
411  $string .= $this->iban.' ';
412  }
413  }
414 
415  return trim($string);
416  }
417 
418 
424  public function canBeConciliated()
425  {
426  global $conf;
427 
428  if (empty($this->rappro)) {
429  return -1;
430  }
431  if ($this->courant == Account::TYPE_CASH && empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) {
432  return -2;
433  }
434  if ($this->clos) {
435  return -3;
436  }
437  return 1;
438  }
439 
440 
441  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
452  public function add_url_line($line_id, $url_id, $url, $label, $type)
453  {
454  // phpcs:enable
455  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
456  $sql .= "fk_bank";
457  $sql .= ", url_id";
458  $sql .= ", url"; // deprecated
459  $sql .= ", label";
460  $sql .= ", type";
461  $sql .= ") VALUES (";
462  $sql .= " ".((int) $line_id);
463  $sql .= ", ".((int) $url_id);
464  $sql .= ", '".$this->db->escape($url)."'"; // dperecated
465  $sql .= ", '".$this->db->escape($label)."'";
466  $sql .= ", '".$this->db->escape($type)."'";
467  $sql .= ")";
468 
469  dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
470  if ($this->db->query($sql)) {
471  $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
472  return $rowid;
473  } else {
474  $this->error = $this->db->lasterror();
475  return -1;
476  }
477  }
478 
479  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
489  public function get_url($fk_bank = '', $url_id = '', $type = '')
490  {
491  // phpcs:enable
492  $lines = array();
493 
494  // Check parameters
495  if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
496  $this->error = "ErrorBadParameter";
497  return -1;
498  }
499 
500  $sql = "SELECT fk_bank, url_id, url, label, type";
501  $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
502  if ($fk_bank > 0) {
503  $sql .= " WHERE fk_bank = ".((int) $fk_bank);
504  } else {
505  $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
506  }
507  $sql .= " ORDER BY type, label";
508 
509  dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
510  $result = $this->db->query($sql);
511  if ($result) {
512  $i = 0;
513  $num = $this->db->num_rows($result);
514  while ($i < $num) {
515  $obj = $this->db->fetch_object($result);
516  // Anciens liens (pour compatibilite)
517  $lines[$i][0] = $obj->url;
518  $lines[$i][1] = $obj->url_id;
519  $lines[$i][2] = $obj->label;
520  $lines[$i][3] = $obj->type;
521  // Nouveaux liens
522  $lines[$i]['url'] = $obj->url;
523  $lines[$i]['url_id'] = $obj->url_id;
524  $lines[$i]['label'] = $obj->label;
525  $lines[$i]['type'] = $obj->type;
526  $lines[$i]['fk_bank'] = $obj->fk_bank;
527  $i++;
528  }
529  } else {
530  dol_print_error($this->db);
531  }
532 
533  return $lines;
534  }
535 
554  public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
555  {
556  // Deprecation warning
557  if (is_numeric($oper)) {
558  dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
559  }
560 
561  if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
562  $this->id = $this->rowid;
563  }
564 
565  // Clean parameters
566  $emetteur = trim($emetteur);
567  $banque = trim($banque);
568  $label = trim($label);
569 
570  $now = dol_now();
571 
572  if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
573  $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
574  $sql .= " WHERE id = ".((int) $oper);
575  $sql .= " AND entity IN (".getEntity('c_paiement').")";
576  $resql = $this->db->query($sql);
577  if ($resql) {
578  $obj = $this->db->fetch_object($resql);
579  $oper = $obj->code;
580  } else {
581  dol_print_error($this->db, 'Failed to get payment type code');
582  return -1;
583  }
584  }
585 
586  // Check parameters
587  if (!$oper) {
588  $this->error = "oper not defined";
589  return -1;
590  }
591  if (!$this->id) {
592  $this->error = "this->id not defined";
593  return -2;
594  }
595  if ($this->courant == Account::TYPE_CASH && $oper != 'LIQ') {
596  $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
597  return -3;
598  }
599 
600  $this->db->begin();
601 
602  if (is_null($datev) || empty($datev)) {
603  $datev = $date;
604  }
605 
606  $accline = new AccountLine($this->db);
607  $accline->datec = $now;
608  $accline->dateo = $date;
609  $accline->datev = $datev;
610  $accline->label = $label;
611  $accline->amount = $amount;
612  $accline->amount_main_currency = $amount_main_currency;
613  $accline->fk_user_author = $user->id;
614  $accline->fk_account = $this->id;
615  $accline->fk_type = $oper;
616  $accline->numero_compte = $accountancycode;
617  $accline->num_releve = $num_releve;
618 
619  if ($num_chq) {
620  $accline->num_chq = $num_chq;
621  }
622 
623  if ($emetteur) {
624  $accline->emetteur = $emetteur;
625  }
626 
627  if ($banque) {
628  $accline->bank_chq = $banque;
629  }
630 
631  if ($accline->insert() > 0) {
632  if ($categorie > 0) {
633  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class(";
634  $sql .= "lineid, fk_categ";
635  $sql .= ") VALUES (";
636  $sql .= ((int) $accline->id).", '".$this->db->escape($categorie)."'";
637  $sql .= ")";
638 
639  $result = $this->db->query($sql);
640  if (!$result) {
641  $this->error = $this->db->lasterror();
642  $this->db->rollback();
643 
644  return -4;
645  }
646  }
647 
648  $this->db->commit();
649 
650  return $accline->id;
651  } else {
652  $this->error = $accline->error;
653  $this->errors = $accline->errors;
654  $this->db->rollback();
655 
656  return -5;
657  }
658  }
659 
667  public function create(User $user, $notrigger = 0)
668  {
669  global $langs, $conf;
670 
671  $error = 0;
672 
673  // Clean parameters
674  if (!$this->min_allowed) {
675  $this->min_allowed = 0;
676  }
677  if (!$this->min_desired) {
678  $this->min_desired = 0;
679  }
680 
681  // Check parameters
682  if (empty($this->country_id)) {
683  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
684  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
685  return -1;
686  }
687  if (empty($this->ref)) {
688  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
689  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
690  return -1;
691  }
692  if (empty($this->date_solde)) {
693  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
694  dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
695  return -1;
696  }
697 
698  // Chargement librairie pour acces fonction controle RIB
699  require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
700 
701  $now = dol_now();
702 
703  $this->db->begin();
704 
705  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
706  $sql .= "datec";
707  $sql .= ", ref";
708  $sql .= ", label";
709  $sql .= ", entity";
710  $sql .= ", account_number";
711  $sql .= ", fk_accountancy_journal";
712  $sql .= ", bank";
713  $sql .= ", code_banque";
714  $sql .= ", code_guichet";
715  $sql .= ", number";
716  $sql .= ", cle_rib";
717  $sql .= ", bic";
718  $sql .= ", iban_prefix";
719  $sql .= ", domiciliation";
720  $sql .= ", pti_in_ctti";
721  $sql .= ", proprio";
722  $sql .= ", owner_address";
723  $sql .= ", owner_zip";
724  $sql .= ", owner_town";
725  $sql .= ", owner_country_id";
726  $sql .= ", currency_code";
727  $sql .= ", rappro";
728  $sql .= ", min_allowed";
729  $sql .= ", min_desired";
730  $sql .= ", comment";
731  $sql .= ", state_id";
732  $sql .= ", fk_pays";
733  $sql .= ", ics";
734  $sql .= ", ics_transfer";
735  $sql .= ") VALUES (";
736  $sql .= "'".$this->db->idate($now)."'";
737  $sql .= ", '".$this->db->escape($this->ref)."'";
738  $sql .= ", '".$this->db->escape($this->label)."'";
739  $sql .= ", ".((int) $conf->entity);
740  $sql .= ", '".$this->db->escape($this->account_number)."'";
741  $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
742  $sql .= ", '".$this->db->escape($this->bank)."'";
743  $sql .= ", '".$this->db->escape($this->code_banque)."'";
744  $sql .= ", '".$this->db->escape($this->code_guichet)."'";
745  $sql .= ", '".$this->db->escape($this->number)."'";
746  $sql .= ", '".$this->db->escape($this->cle_rib)."'";
747  $sql .= ", '".$this->db->escape($this->bic)."'";
748  $sql .= ", '".$this->db->escape($this->iban)."'";
749  $sql .= ", '".$this->db->escape($this->domiciliation)."'";
750  $sql .= ", ".((int) $this->pti_in_ctti);
751  $sql .= ", '".$this->db->escape($this->proprio)."'";
752  $sql .= ", '".$this->db->escape($this->owner_address)."'";
753  $sql .= ", '".$this->db->escape($this->owner_zip)."'";
754  $sql .= ", '".$this->db->escape($this->owner_town)."'";
755  $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
756  $sql .= ", '".$this->db->escape($this->currency_code)."'";
757  $sql .= ", ".((int) $this->rappro);
758  $sql .= ", ".price2num($this->min_allowed, 'MT');
759  $sql .= ", ".price2num($this->min_desired, 'MT');
760  $sql .= ", '".$this->db->escape($this->comment)."'";
761  $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
762  $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
763  $sql .= ", '".$this->db->escape($this->ics)."'";
764  $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
765  $sql .= ")";
766 
767  dol_syslog(get_class($this)."::create", LOG_DEBUG);
768  $resql = $this->db->query($sql);
769  if ($resql) {
770  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
771 
772  $result = $this->update($user, 1);
773  if ($result > 0) {
774  $accline = new AccountLine($this->db);
775  $accline->datec = $this->db->idate($now);
776  $accline->label = '('.$langs->trans("InitialBankBalance").')';
777  $accline->amount = price2num($this->solde);
778  $accline->fk_user_author = $user->id;
779  $accline->fk_account = $this->id;
780  $accline->datev = $this->db->idate($this->date_solde);
781  $accline->dateo = $this->db->idate($this->date_solde);
782  $accline->fk_type = 'SOLD';
783 
784  if ($accline->insert() < 0) {
785  $error++;
786  $this->error = $accline->error;
787  $this->errors = $accline->errors;
788  }
789 
790  if (!$error) {
791  $result = $this->insertExtraFields();
792  if ($result < 0) {
793  $error++;
794  }
795  }
796 
797  if (!$error && !$notrigger) {
798  // Call trigger
799  $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
800  if ($result < 0) {
801  $error++;
802  }
803  // End call triggers
804  }
805  } else {
806  $error++;
807  }
808  } else {
809  if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
810  $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
811  $error++;
812  } else {
813  $this->error = $this->db->error()." sql=".$sql;
814  $error++;
815  }
816  }
817 
818  if (!$error) {
819  $this->db->commit();
820  return $this->id;
821  } else {
822  $this->db->rollback();
823  return -1 * $error;
824  }
825  }
826 
834  public function update(User $user, $notrigger = 0)
835  {
836  global $langs, $conf;
837 
838  $error = 0;
839 
840  $this->db->begin();
841 
842  // Check parameters
843  if (empty($this->country_id)) {
844  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
845  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
846  return -1;
847  }
848  if (empty($this->ref)) {
849  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
850  dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
851  return -1;
852  }
853  if (!$this->label) {
854  $this->label = "???";
855  }
856 
857  $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
858 
859  $sql .= " ref = '".$this->db->escape($this->ref)."'";
860  $sql .= ",label = '".$this->db->escape($this->label)."'";
861 
862  $sql .= ",courant = ".((int) $this->courant);
863  $sql .= ",clos = ".((int) $this->clos);
864  $sql .= ",rappro = ".((int) $this->rappro);
865  $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
866  $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
867  $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
868  $sql .= ",bank = '".$this->db->escape($this->bank)."'";
869  $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
870  $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
871  $sql .= ",number='".$this->db->escape($this->number)."'";
872  $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
873  $sql .= ",bic='".$this->db->escape($this->bic)."'";
874  $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
875  $sql .= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
876  $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
877  $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
878  $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
879  $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
880  $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
881  $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
882 
883  $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
884 
885  $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
886  $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
887  $sql .= ",comment = '".$this->db->escape($this->comment)."'";
888 
889  $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
890  $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
891  $sql .= ",ics = '".$this->db->escape($this->ics)."'";
892  $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
893 
894  $sql .= " WHERE rowid = ".((int) $this->id);
895 
896  dol_syslog(get_class($this)."::update", LOG_DEBUG);
897  $result = $this->db->query($sql);
898  if ($result) {
899  // Actions on extra fields (by external module or standard code)
900  if (!$error) {
901  $result = $this->insertExtraFields();
902  if ($result < 0) {
903  $error++;
904  }
905  }
906 
907  if (!$error && !$notrigger) {
908  // Call trigger
909  $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
910  if ($result < 0) {
911  $error++;
912  }
913  // End call triggers
914  }
915  } else {
916  $error++;
917  $this->error = $this->db->lasterror();
918  dol_print_error($this->db);
919  }
920 
921  if (!$error) {
922  $this->db->commit();
923  return $this->id;
924  } else {
925  $this->db->rollback();
926  return -1 * $error;
927  }
928  }
929 
930 
931  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
938  public function update_bban(User $user = null)
939  {
940  // phpcs:enable
941  global $conf, $langs;
942 
943  // Load library to get BAN control function
944  require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
945 
946  dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
947 
948  // Check parameters
949  if (!$this->ref) {
950  $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
951  return -2;
952  }
953 
954  $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
955  $sql .= " bank = '".$this->db->escape($this->bank)."'";
956  $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
957  $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
958  $sql .= ",number='".$this->db->escape($this->number)."'";
959  $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
960  $sql .= ",bic='".$this->db->escape($this->bic)."'";
961  $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
962  $sql .= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
963  $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
964  $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
965  $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
966  $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
967  $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
968  $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
969  $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
970  $sql .= " WHERE rowid = ".((int) $this->id);
971  $sql .= " AND entity = ".((int) $conf->entity);
972 
973  dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
974 
975  $result = $this->db->query($sql);
976  if ($result) {
977  return 1;
978  } else {
979  $this->error = $this->db->lasterror();
980  dol_print_error($this->db);
981  return -1;
982  }
983  }
984 
985 
993  public function fetch($id, $ref = '')
994  {
995  if (empty($id) && empty($ref)) {
996  $this->error = "ErrorBadParameters";
997  return -1;
998  }
999 
1000  $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant, ba.clos, ba.rappro, ba.url,";
1001  $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1002  $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,";
1003  $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1004  $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1005  $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1006  $sql .= ' c.code as country_code, c.label as country,';
1007  $sql .= ' d.code_departement as state_code, d.nom as state,';
1008  $sql .= ' aj.code as accountancy_journal';
1009  $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1010  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1011  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1012  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1013  $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1014  if ($id) {
1015  $sql .= " AND ba.rowid = ".((int) $id);
1016  }
1017  if ($ref) {
1018  $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1019  }
1020 
1021  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1022  $result = $this->db->query($sql);
1023  if ($result) {
1024  if ($this->db->num_rows($result)) {
1025  $obj = $this->db->fetch_object($result);
1026 
1027  $this->id = $obj->rowid;
1028  $this->rowid = $obj->rowid;
1029  $this->ref = $obj->ref;
1030  $this->label = $obj->label;
1031  $this->type = $obj->courant;
1032  $this->courant = $obj->courant;
1033  $this->bank = $obj->bank;
1034  $this->clos = $obj->clos;
1035  $this->rappro = $obj->rappro;
1036  $this->url = $obj->url;
1037 
1038  $this->code_banque = $obj->code_banque;
1039  $this->code_guichet = $obj->code_guichet;
1040  $this->number = $obj->number;
1041  $this->cle_rib = $obj->cle_rib;
1042  $this->bic = $obj->bic;
1043  $this->iban = $obj->iban;
1044  $this->domiciliation = $obj->address;
1045  $this->address = $obj->address;
1046  $this->pti_in_ctti = $obj->pti_in_ctti;
1047  $this->proprio = $obj->proprio;
1048  $this->owner_address = $obj->owner_address;
1049  $this->owner_zip = $obj->owner_zip;
1050  $this->owner_town = $obj->owner_town;
1051  $this->owner_country_id = $obj->owner_country_id;
1052 
1053  $this->state_id = $obj->state_id;
1054  $this->state_code = $obj->state_code;
1055  $this->state = $obj->state;
1056 
1057  $this->country_id = $obj->country_id;
1058  $this->country_code = $obj->country_code;
1059  $this->country = $obj->country;
1060 
1061  $this->account_number = $obj->account_number;
1062  $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1063  $this->accountancy_journal = $obj->accountancy_journal;
1064 
1065  $this->currency_code = $obj->currency_code;
1066  $this->account_currency_code = $obj->currency_code;
1067  $this->min_allowed = $obj->min_allowed;
1068  $this->min_desired = $obj->min_desired;
1069  $this->comment = $obj->comment;
1070 
1071  $this->date_creation = $this->db->jdate($obj->date_creation);
1072  $this->date_modification = $this->db->jdate($obj->date_modification);
1073  $this->date_update = $this->date_modification; // For compatibility
1074 
1075  $this->ics = $obj->ics;
1076  $this->ics_transfer = $obj->ics_transfer;
1077 
1078  // Retrieve all extrafield
1079  // fetch optionals attributes and labels
1080  $this->fetch_optionals();
1081 
1082  return 1;
1083  } else {
1084  return 0;
1085  }
1086  } else {
1087  $this->error = $this->db->lasterror();
1088  $this->errors[] = $this->error;
1089  return -1;
1090  }
1091  }
1092 
1103  public function setCategories($categories)
1104  {
1105  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1106  return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1107  }
1108 
1115  public function delete(User $user = null)
1116  {
1117  $error = 0;
1118 
1119  $this->db->begin();
1120 
1121  // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1122 
1123  // Delete link between tag and bank account
1124  if (!$error) {
1125  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1126  $sql .= " WHERE fk_account = ".((int) $this->id);
1127 
1128  $resql = $this->db->query($sql);
1129  if (!$resql) {
1130  $error++;
1131  $this->error = "Error ".$this->db->lasterror();
1132  }
1133  }
1134 
1135  if (!$error) {
1136  $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1137  $sql .= " WHERE rowid = ".((int) $this->id);
1138 
1139  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1140  $result = $this->db->query($sql);
1141  if ($result) {
1142  // Remove extrafields
1143  if (!$error) {
1144  $result = $this->deleteExtraFields();
1145  if ($result < 0) {
1146  $error++;
1147  dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1148  }
1149  }
1150  } else {
1151  $error++;
1152  $this->error = "Error ".$this->db->lasterror();
1153  }
1154  }
1155 
1156  if (!$error) {
1157  $this->db->commit();
1158  return 1;
1159  } else {
1160  $this->db->rollback();
1161  return -1;
1162  }
1163  }
1164 
1165 
1172  public function getLibStatut($mode = 0)
1173  {
1174  return $this->LibStatut($this->clos, $mode);
1175  }
1176 
1177  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1185  public function LibStatut($status, $mode = 0)
1186  {
1187  // phpcs:enable
1188  global $langs;
1189  $langs->load('banks');
1190 
1191  if ($status == self::STATUS_OPEN) {
1192  $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1193  $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1194  $statusType = 'status4';
1195  } else {
1196  $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1197  $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1198  $statusType = 'status5';
1199  }
1200 
1201  return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1202  }
1203 
1204 
1205  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1211  public function can_be_deleted()
1212  {
1213  // phpcs:enable
1214  $can_be_deleted = false;
1215 
1216  $sql = "SELECT COUNT(rowid) as nb";
1217  $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1218  $sql .= " WHERE fk_account = ".((int) $this->id);
1219 
1220  $resql = $this->db->query($sql);
1221  if ($resql) {
1222  $obj = $this->db->fetch_object($resql);
1223  if ($obj->nb <= 1) {
1224  $can_be_deleted = true; // Juste le solde
1225  }
1226  } else {
1227  dol_print_error($this->db);
1228  }
1229  return $can_be_deleted;
1230  }
1231 
1232 
1238  public function error()
1239  {
1240  return $this->error;
1241  }
1242 
1251  public function solde($option = 0, $date_end = '', $field = 'dateo')
1252  {
1253  $solde = 0;
1254 
1255  $sql = "SELECT sum(amount) as amount";
1256  $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1257  $sql .= " WHERE fk_account = ".((int) $this->id);
1258  if ($option == 1) {
1259  $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1260  }
1261 
1262  $resql = $this->db->query($sql);
1263  if ($resql) {
1264  if ($this->db->num_rows($resql)) {
1265  $obj = $this->db->fetch_object($resql);
1266  $solde = $obj->amount;
1267  }
1268  $this->db->free($resql);
1269  } else {
1270  $this->errors[] = $this->db->lasterror;
1271  return -1;
1272  }
1273 
1274  return price2num($solde, 'MU');
1275  }
1276 
1277  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1285  public function load_board(User $user, $filteraccountid = 0)
1286  {
1287  // phpcs:enable
1288  global $conf, $langs;
1289 
1290  if ($user->socid) {
1291  return -1; // protection pour eviter appel par utilisateur externe
1292  }
1293 
1294  $sql = "SELECT b.rowid, b.datev as datefin";
1295  $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1296  $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1297  $sql .= " WHERE b.rappro=0";
1298  $sql .= " AND b.fk_account = ba.rowid";
1299  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1300  $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1301  $sql .= " AND clos = 0";
1302  if ($filteraccountid) {
1303  $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1304  }
1305 
1306  $resql = $this->db->query($sql);
1307  if ($resql) {
1308  $langs->load("banks");
1309  $now = dol_now();
1310 
1311  require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1312 
1313  $response = new WorkboardResponse();
1314  $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1315  $response->label = $langs->trans("TransactionsToConciliate");
1316  $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1317  $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1318  $response->img = img_object('', "payment");
1319 
1320  while ($obj = $this->db->fetch_object($resql)) {
1321  $response->nbtodo++;
1322  if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1323  $response->nbtodolate++;
1324  }
1325  }
1326 
1327  return $response;
1328  } else {
1329  dol_print_error($this->db);
1330  $this->error = $this->db->error();
1331  return -1;
1332  }
1333  }
1334 
1335  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1342  public function load_state_board($filteraccountid = 0)
1343  {
1344  // phpcs:enable
1345  global $user;
1346 
1347  if ($user->socid) {
1348  return -1; // protection pour eviter appel par utilisateur externe
1349  }
1350 
1351  $sql = "SELECT count(b.rowid) as nb";
1352  $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1353  $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1354  $sql .= " WHERE b.fk_account = ba.rowid";
1355  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1356  $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1357  $sql .= " AND clos = 0";
1358  if ($filteraccountid) {
1359  $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1360  }
1361 
1362  $resql = $this->db->query($sql);
1363  if ($resql) {
1364  while ($obj = $this->db->fetch_object($resql)) {
1365  $this->nb["banklines"] = $obj->nb;
1366  }
1367  $this->db->free($resql);
1368  return 1;
1369  } else {
1370  dol_print_error($this->db);
1371  $this->error = $this->db->error();
1372  return -1;
1373  }
1374  }
1375 
1376 
1382  public function countAccountToReconcile()
1383  {
1384  global $db, $conf, $user;
1385 
1386  //Protection against external users
1387  if ($user->socid) {
1388  return 0;
1389  }
1390 
1391  $nb = 0;
1392 
1393  $sql = "SELECT COUNT(ba.rowid) as nb";
1394  $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1395  $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1396  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1397  if (empty($conf->global->BANK_CAN_RECONCILIATE_CASHACCOUNT)) {
1398  $sql .= " AND ba.courant != 2";
1399  }
1400  $resql = $this->db->query($sql);
1401  if ($resql) {
1402  $obj = $this->db->fetch_object($resql);
1403  $nb = $obj->nb;
1404  } else {
1405  dol_print_error($this->db);
1406  }
1407 
1408  return $nb;
1409  }
1410 
1418  public function getTooltipContentArray($params)
1419  {
1420  global $langs;
1421  $langs->loadLangs(['banks', 'compta']);
1422  include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1423 
1424  $datas = array();
1425 
1426  $nofetch = !empty($params['nofetch']);
1427  $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1428  if (isset($this->status)) {
1429  $pictos .= ' '.$this->getLibStatut(5);
1430  }
1431  $datas['picto'] = $pictos;
1432  $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1433  $datas['accountnumber'] = '<br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1434  $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1435  $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1436  $datas['accountcurrency'] = '<br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1437 
1438  if (isModEnabled('accounting')) {
1439  include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1440  $langs->load("accountancy");
1441  $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1442  $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1443  }
1444  // show categories for this record only in ajax to not overload lists
1445  if (isModEnabled('categorie') && !$nofetch) {
1446  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1447  $form = new Form($this->db);
1448  $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1449  }
1450 
1451  return $datas;
1452  }
1453 
1464  public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0)
1465  {
1466  global $conf, $langs, $user;
1467 
1468  include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1469 
1470  $result = '';
1471  $classfortooltip = 'classfortooltip';
1472  $dataparams = '';
1473  $params = [
1474  'id' => $this->id,
1475  'objecttype' => $this->element,
1476  'option' => $option,
1477  'nofetch' => 1,
1478  ];
1479  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1480  $classfortooltip = 'classforajaxtooltip';
1481  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1482  $label = '';
1483  } else {
1484  $label = implode($this->getTooltipContentArray($params));
1485  }
1486 
1487  $linkclose = '';
1488  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1489  $linkclose .= $dataparams.' class="'.$classfortooltip.'">';
1490 
1491  $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1492  if ($mode == 'transactions') {
1493  $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1494  } elseif ($mode == 'receipts') {
1495  $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1496  }
1497 
1498  if ($option != 'nolink') {
1499  // Add param to save lastsearch_values or not
1500  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1501  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1502  $add_save_lastsearch_values = 1;
1503  }
1504  if ($add_save_lastsearch_values) {
1505  $url .= '&save_lastsearch_values=1';
1506  }
1507  }
1508 
1509  $linkstart = '<a href="'.$url.'"'.$linkclose;
1510  $linkend = '</a>';
1511 
1512  if ($option == 'nolink') {
1513  $linkstart = '';
1514  $linkend = '';
1515  }
1516 
1517  $result .= $linkstart;
1518  if ($withpicto) {
1519  $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1);
1520  }
1521  if ($withpicto != 2) {
1522  $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1523  }
1524  $result .= $linkend;
1525 
1526  return $result;
1527  }
1528 
1529 
1530  // Method after here are common to Account and CompanyBankAccount
1531 
1532 
1538  public function verif()
1539  {
1540  require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1541 
1542  $error = 0;
1543 
1544  // Call functions to check BAN
1545  if (!checkIbanForAccount($this)) {
1546  $error++;
1547  $this->error_message = 'IBANNotValid';
1548  }
1549  if (!checkSwiftForAccount($this)) {
1550  $error++;
1551  $this->error_message = 'SwiftNotValid';
1552  }
1553 
1554  if (! $error) {
1555  return 1;
1556  } else {
1557  return 0;
1558  }
1559  }
1560 
1566  public function getCountryCode()
1567  {
1568  global $mysoc;
1569 
1570  // We return country code of bank account
1571  if (!empty($this->country_code)) {
1572  return $this->country_code;
1573  }
1574 
1575  // For backward compatibility, we try to guess country from other information
1576  if (!empty($this->iban)) {
1577  // If IBAN defined, we can know country of account from it
1578  $reg = array();
1579  if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1580  return $reg[1];
1581  }
1582  }
1583 
1584  // If this class is linked to a third party
1585  if (!empty($this->socid)) {
1586  require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1587  $company = new Societe($this->db);
1588  $result = $company->fetch($this->socid);
1589  if (!empty($company->country_code)) {
1590  return $company->country_code;
1591  }
1592  }
1593 
1594  // We return country code of managed company
1595  if (!empty($mysoc->country_code)) {
1596  return $mysoc->country_code;
1597  }
1598 
1599  return '';
1600  }
1601 
1610  public function useDetailedBBAN()
1611  {
1612  $country_code = $this->getCountryCode();
1613 
1614  if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1615  return 1; // France, Spain, Gabon, ... - Not valid for CH
1616  }
1617  if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1618  return 2; // Australia, England...
1619  }
1620  return 0;
1621  }
1622 
1628  public function needIBAN()
1629  {
1630  global $conf;
1631 
1632  if (!empty($conf->global->MAIN_IBAN_IS_NEVER_MANDATORY)) {
1633  return 0;
1634  }
1635 
1636  $country_code = $this->getCountryCode();
1637 
1638  $country_code_in_EEC = array(
1639  'AT', // Austria
1640  'BE', // Belgium
1641  'BG', // Bulgaria
1642  'CY', // Cyprus
1643  'CZ', // Czech republic
1644  'DE', // Germany
1645  'DK', // Danemark
1646  'EE', // Estonia
1647  'ES', // Spain
1648  'FI', // Finland
1649  'FR', // France
1650  'GB', // United Kingdom
1651  'GR', // Greece
1652  'HR', // Croatia
1653  'NL', // Holland
1654  'HU', // Hungary
1655  'IE', // Ireland
1656  'IM', // Isle of Man - Included in UK
1657  'IT', // Italy
1658  'LT', // Lithuania
1659  'LU', // Luxembourg
1660  'LV', // Latvia
1661  'MC', // Monaco - Included in France
1662  'MT', // Malta
1663  //'NO', // Norway
1664  'PL', // Poland
1665  'PT', // Portugal
1666  'RO', // Romania
1667  'SE', // Sweden
1668  'SK', // Slovakia
1669  'SI', // Slovenia
1670  'UK', // United Kingdom
1671  //'CH', // Switzerland - No. Swizerland in not in EEC
1672  );
1673 
1674  if (in_array($country_code, $country_code_in_EEC)) {
1675  return 1; // France, Spain, ...
1676  }
1677  return 0;
1678  }
1679 
1686  public function info($id)
1687  {
1688  }
1689 
1704  public function getFieldsToShow($includeibanbic = 0)
1705  {
1706  //Get the required properties depending on the country
1707  $detailedBBAN = $this->useDetailedBBAN();
1708 
1709  if ($detailedBBAN == 0) {
1710  $fieldarray = array(
1711  'BankAccountNumber'
1712  );
1713  } elseif ($detailedBBAN == 2) {
1714  $fieldarray = array(
1715  'BankCode',
1716  'BankAccountNumber'
1717  );
1718  } else {
1719  $fieldarray = self::getAccountNumberOrder();
1720  }
1721 
1722  //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1723  if ($includeibanbic) {
1724  $fieldarray[] = 'IBAN';
1725  $fieldarray[] = 'BIC';
1726  }
1727  //}
1728 
1729  //Get the order the properties are shown
1730  return $fieldarray;
1731  }
1732 
1743  public static function getAccountNumberOrder()
1744  {
1745  global $conf;
1746 
1747  $fieldlists = array(
1748  'BankCode',
1749  'DeskCode',
1750  'BankAccountNumber',
1751  'BankAccountNumberKey'
1752  );
1753 
1754  if (!empty($conf->global->BANK_SHOW_ORDER_OPTION)) {
1755  if (is_numeric($conf->global->BANK_SHOW_ORDER_OPTION)) {
1756  if ($conf->global->BANK_SHOW_ORDER_OPTION == '1') {
1757  $fieldlists = array(
1758  'BankCode',
1759  'DeskCode',
1760  'BankAccountNumberKey',
1761  'BankAccountNumber'
1762  );
1763  }
1764  } else {
1765  //Replace the old AccountNumber key with the new BankAccountNumber key
1766  $fieldlists = explode(
1767  ' ',
1768  preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1769  );
1770  }
1771  }
1772 
1773  return $fieldlists;
1774  }
1775 
1776 
1784  public function initAsSpecimen()
1785  {
1786  // Example of IBAN FR7630001007941234567890185
1787  $this->specimen = 1;
1788  $this->ref = 'MBA';
1789  $this->label = 'My Big Company Bank account';
1790  $this->bank = 'MyBank';
1791  $this->courant = Account::TYPE_CURRENT;
1792  $this->clos = Account::STATUS_OPEN;
1793  $this->code_banque = '30001';
1794  $this->code_guichet = '00794';
1795  $this->number = '12345678901';
1796  $this->cle_rib = '85';
1797  $this->bic = 'AA12';
1798  $this->iban = 'FR7630001007941234567890185';
1799  $this->domiciliation = 'Banque de France';
1800  $this->proprio = 'Owner';
1801  $this->owner_address = 'Owner address';
1802  $this->owner_zip = 'Owner zip';
1803  $this->owner_town = 'Owner town';
1804  $this->owner_country_id = 'Owner country_id';
1805  $this->country_id = 1;
1806  }
1807 
1816  public static function replaceThirdparty($dbs, $origin_id, $dest_id)
1817  {
1818  $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'";
1819 
1820  if ($dbs->query($sql)) {
1821  return true;
1822  } else {
1823  //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.
1824  //$this->errors = $dbs->lasterror();
1825  return false;
1826  }
1827  }
1828 
1836  public function getKanbanView($option = '', $arraydata = null)
1837  {
1838  global $langs;
1839 
1840  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1841 
1842  $return = '<div class="box-flex-item box-flex-grow-zero">';
1843  $return .= '<div class="info-box info-box-sm">';
1844  $return .= '<span class="info-box-icon bg-infobox-action">';
1845  $return .= img_picto('', $this->picto);
1846  $return .= '</span>';
1847  $return .= '<div class="info-box-content">';
1848  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1849  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1850 
1851  if (property_exists($this, 'type_lib')) {
1852  $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
1853  }
1854  if (method_exists($this, 'solde')) {
1855  $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
1856  $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>';
1857  }
1858  if (method_exists($this, 'getLibStatut')) {
1859  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
1860  }
1861  $return .= '</div>';
1862  $return .= '</div>';
1863  $return .= '</div>';
1864  return $return;
1865  }
1866 }
1867 
1868 
1869 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1870 
1875 {
1879  public $error = '';
1880 
1884  public $db;
1885 
1889  public $element = 'bank';
1890 
1894  public $table_element = 'bank';
1895 
1899  public $picto = 'accountline';
1900 
1904  public $id;
1905 
1909  public $ref;
1910 
1916  public $datec;
1917 
1923  public $dateo;
1924 
1930  public $datev;
1931 
1932  public $amount; /* Amount of payment in the bank account currency */
1933  public $amount_main_currency; /* Amount in the currency of company if bank account use another currency */
1934 
1938  public $fk_user_author;
1939 
1943  public $fk_user_rappro;
1944 
1948  public $fk_type;
1949 
1953  public $fk_bordereau;
1954 
1958  public $fk_account;
1959 
1963  public $bank_account_ref;
1964 
1968  public $bank_account_label;
1969 
1973  public $numero_compte;
1974 
1978  public $emetteur;
1979 
1980  public $rappro; // Is it conciliated
1981  public $num_releve; // If conciliated, what is bank statement
1982  public $num_chq; // Num of cheque
1983  public $bank_chq; // Bank of cheque
1984 
1988  public $label;
1989 
1990  public $note;
1991 
1992 
1993 
1999  public function __construct(DoliDB $db)
2000  {
2001  $this->db = $db;
2002  }
2003 
2012  public function fetch($rowid, $ref = '', $num = '')
2013  {
2014  global $conf;
2015 
2016  // Check parameters
2017  if (empty($rowid) && empty($ref) && empty($num)) {
2018  return -1;
2019  }
2020 
2021  $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2022  $sql .= " b.fk_user_author, b.fk_user_rappro,";
2023  $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2024  $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2025  $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2026  $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2027  $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2028  $sql .= " WHERE b.fk_account = ba.rowid";
2029  $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2030  if ($num) {
2031  $sql .= " AND b.num_chq='".$this->db->escape($num)."'";
2032  } elseif ($ref) {
2033  $sql .= " AND b.rowid='".$this->db->escape($ref)."'";
2034  } else {
2035  $sql .= " AND b.rowid = ".((int) $rowid);
2036  }
2037 
2038  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2039  $result = $this->db->query($sql);
2040  if ($result) {
2041  $ret = 0;
2042 
2043  $obj = $this->db->fetch_object($result);
2044  if ($obj) {
2045  $this->id = $obj->rowid;
2046  $this->rowid = $obj->rowid;
2047  $this->ref = $obj->rowid;
2048 
2049  $this->datec = $obj->datec;
2050  $this->datev = $obj->datev;
2051  $this->dateo = $obj->dateo;
2052  $this->amount = $obj->amount;
2053  $this->label = $obj->label;
2054  $this->note = $obj->note;
2055 
2056  $this->fk_user_author = $obj->fk_user_author;
2057  $this->fk_user_rappro = $obj->fk_user_rappro;
2058 
2059  $this->fk_type = $obj->fk_type; // Type of transaction
2060  $this->rappro = $obj->rappro;
2061  $this->num_releve = $obj->num_releve;
2062 
2063  $this->num_chq = $obj->num_chq;
2064  $this->bank_chq = $obj->banque;
2065  $this->fk_bordereau = $obj->fk_bordereau;
2066 
2067  $this->fk_account = $obj->fk_account;
2068  $this->bank_account_ref = $obj->bank_account_ref;
2069  $this->bank_account_label = $obj->bank_account_label;
2070 
2071  // Retrieve all extrafield
2072  // fetch optionals attributes and labels
2073  $this->fetch_optionals();
2074 
2075  $ret = 1;
2076  }
2077  $this->db->free($result);
2078  return $ret;
2079  } else {
2080  return -1;
2081  }
2082  }
2083 
2089  public function insert()
2090  {
2091  $error = 0;
2092 
2093  $this->db->begin();
2094 
2095  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2096  $sql .= "datec";
2097  $sql .= ", dateo";
2098  $sql .= ", datev";
2099  $sql .= ", label";
2100  $sql .= ", amount";
2101  $sql .= ", amount_main_currency";
2102  $sql .= ", fk_user_author";
2103  $sql .= ", num_chq";
2104  $sql .= ", fk_account";
2105  $sql .= ", fk_type";
2106  $sql .= ", emetteur,banque";
2107  $sql .= ", rappro";
2108  $sql .= ", numero_compte";
2109  $sql .= ", num_releve";
2110  $sql .= ") VALUES (";
2111  $sql .= "'".$this->db->idate($this->datec)."'";
2112  $sql .= ", '".$this->db->idate($this->dateo)."'";
2113  $sql .= ", '".$this->db->idate($this->datev)."'";
2114  $sql .= ", '".$this->db->escape($this->label)."'";
2115  $sql .= ", ".price2num($this->amount);
2116  $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2117  $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2118  $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2119  $sql .= ", '".$this->db->escape($this->fk_account)."'";
2120  $sql .= ", '".$this->db->escape($this->fk_type)."'";
2121  $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2122  $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2123  $sql .= ", ".(int) $this->rappro;
2124  $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2125  $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2126  $sql .= ")";
2127 
2128  dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2129  $resql = $this->db->query($sql);
2130  if ($resql) {
2131  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2132  // Actions on extra fields (by external module or standard code)
2133  $result = $this->insertExtraFields();
2134  if ($result < 0) {
2135  $error++;
2136  }
2137  } else {
2138  $error++;
2139  $this->error = $this->db->lasterror();
2140  dol_print_error($this->db);
2141  }
2142 
2143  if (!$error) {
2144  $this->db->commit();
2145  return $this->id;
2146  } else {
2147  $this->db->rollback();
2148  return -1 * $error;
2149  }
2150  }
2151 
2158  public function delete(User $user = null)
2159  {
2160  global $conf;
2161 
2162  $nbko = 0;
2163 
2164  if ($this->rappro) {
2165  // Protection to avoid any delete of consolidated lines
2166  $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2167  return -1;
2168  }
2169 
2170  $this->db->begin();
2171 
2172  // Protection to avoid any delete of accounted lines. Protection on by default
2173  if (empty($conf->global->BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING)) {
2174  $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2175  $resql = $this->db->query($sql);
2176  if ($resql) {
2177  $obj = $this->db->fetch_object($resql);
2178  if ($obj && $obj->nb) {
2179  $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2180  $this->db->rollback();
2181  return -1;
2182  }
2183  } else {
2184  $this->error = $this->db->lasterror();
2185  $this->db->rollback();
2186  return -1;
2187  }
2188  }
2189 
2190  // Delete urls
2191  $result = $this->delete_urls($user);
2192  if ($result < 0) {
2193  $nbko++;
2194  }
2195 
2196  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid=".(int) $this->rowid;
2197  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2198  $result = $this->db->query($sql);
2199  if (!$result) {
2200  $nbko++;
2201  }
2202 
2203  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2204  $result = $this->db->query($sql);
2205  if (!$result) {
2206  $nbko++;
2207  }
2208 
2209  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2210  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2211  $result = $this->db->query($sql);
2212  if (!$result) {
2213  $nbko++;
2214  }
2215 
2216  if (!$nbko) {
2217  $this->db->commit();
2218  return 1;
2219  } else {
2220  $this->db->rollback();
2221  return -$nbko;
2222  }
2223  }
2224 
2225 
2226  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2233  public function delete_urls(User $user = null)
2234  {
2235  // phpcs:enable
2236  $nbko = 0;
2237 
2238  if ($this->rappro) {
2239  // Protection to avoid any delete of consolidated lines
2240  $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2241  return -1;
2242  }
2243 
2244  $this->db->begin();
2245 
2246  $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2247  dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2248  $result = $this->db->query($sql);
2249  if (!$result) {
2250  $nbko++;
2251  }
2252 
2253  if (!$nbko) {
2254  $this->db->commit();
2255  return 1;
2256  } else {
2257  $this->db->rollback();
2258  return -$nbko;
2259  }
2260  }
2261 
2262 
2270  public function update(User $user, $notrigger = 0)
2271  {
2272  $this->db->begin();
2273 
2274  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2275  $sql .= " amount = ".price2num($this->amount).",";
2276  $sql .= " datev='".$this->db->idate($this->datev)."',";
2277  $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2278  $sql .= " WHERE rowid = ".((int) $this->rowid);
2279 
2280  dol_syslog(get_class($this)."::update", LOG_DEBUG);
2281  $resql = $this->db->query($sql);
2282  if ($resql) {
2283  $this->db->commit();
2284  return 1;
2285  } else {
2286  $this->db->rollback();
2287  $this->error = $this->db->error();
2288  return -1;
2289  }
2290  }
2291 
2292 
2293  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2302  public function update_conciliation(User $user, $cat, $conciliated = 1)
2303  {
2304  // phpcs:enable
2305  global $conf, $langs;
2306 
2307  $this->db->begin();
2308 
2309  // Check statement field
2310  if (!empty($conf->global->BANK_STATEMENT_REGEX_RULE)) {
2311  if (!preg_match('/'.$conf->global->BANK_STATEMENT_REGEX_RULE.'/', $this->num_releve)) {
2312  $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", $conf->global->BANK_STATEMENT_REGEX_RULE);
2313  return -1;
2314  }
2315  }
2316 
2317  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2318  $sql .= " rappro = ".((int) $conciliated);
2319  $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2320  if ($conciliated) {
2321  $sql .= ", fk_user_rappro = ".$user->id;
2322  }
2323  $sql .= " WHERE rowid = ".((int) $this->id);
2324 
2325  dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2326  $resql = $this->db->query($sql);
2327  if ($resql) {
2328  if (!empty($cat)) {
2329  $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
2330  $sql .= "lineid";
2331  $sql .= ", fk_categ";
2332  $sql .= ") VALUES (";
2333  $sql .= $this->id;
2334  $sql .= ", ".((int) $cat);
2335  $sql .= ")";
2336 
2337  dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2338  $this->db->query($sql);
2339 
2340  // No error check. Can fail if category already affected
2341  }
2342 
2343  $this->rappro = 1;
2344 
2345  $this->db->commit();
2346  return 1;
2347  } else {
2348  $this->db->rollback();
2349  return -1;
2350  }
2351  }
2352 
2353 
2354  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2362  public function datev_change($rowid, $sign = 1)
2363  {
2364  // phpcs:enable
2365  $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2366  $resql = $this->db->query($sql);
2367  if ($resql) {
2368  $obj = $this->db->fetch_object($resql);
2369  $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2370 
2371  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2372  $sql .= " datev = '".$this->db->idate($newdate)."'";
2373  $sql .= " WHERE rowid = ".((int) $rowid);
2374 
2375  $result = $this->db->query($sql);
2376  if ($result) {
2377  if ($this->db->affected_rows($result)) {
2378  return 1;
2379  }
2380  } else {
2381  dol_print_error($this->db);
2382  return 0;
2383  }
2384  } else {
2385  dol_print_error($this->db);
2386  }
2387  return 0;
2388  }
2389 
2390  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2397  public function datev_next($id)
2398  {
2399  // phpcs:enable
2400  return $this->datev_change($id, 1);
2401  }
2402 
2403  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2410  public function datev_previous($id)
2411  {
2412  // phpcs:enable
2413  return $this->datev_change($id, -1);
2414  }
2415 
2416 
2417  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2425  public function dateo_change($rowid, $sign = 1)
2426  {
2427  // phpcs:enable
2428  $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2429  $resql = $this->db->query($sql);
2430  if ($resql) {
2431  $obj = $this->db->fetch_object($resql);
2432  $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2433 
2434  $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2435  $sql .= " dateo = '".$this->db->idate($newdate)."'";
2436  $sql .= " WHERE rowid = ".((int) $rowid);
2437 
2438  $result = $this->db->query($sql);
2439  if ($result) {
2440  if ($this->db->affected_rows($result)) {
2441  return 1;
2442  }
2443  } else {
2444  dol_print_error($this->db);
2445  return 0;
2446  }
2447  } else {
2448  dol_print_error($this->db);
2449  }
2450  return 0;
2451  }
2452 
2453  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2460  public function dateo_next($id)
2461  {
2462  // phpcs:enable
2463  return $this->dateo_change($id, 1);
2464  }
2465 
2466  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2473  public function dateo_previous($id)
2474  {
2475  // phpcs:enable
2476  return $this->dateo_change($id, -1);
2477  }
2478 
2479 
2486  public function info($id)
2487  {
2488  $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2489  $sql .= ' b.fk_user_author, b.fk_user_rappro';
2490  $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2491  $sql .= ' WHERE b.rowid = '.((int) $id);
2492 
2493  $result = $this->db->query($sql);
2494  if ($result) {
2495  if ($this->db->num_rows($result)) {
2496  $obj = $this->db->fetch_object($result);
2497  $this->id = $obj->rowid;
2498 
2499  if ($obj->fk_user_author) {
2500  $cuser = new User($this->db);
2501  $cuser->fetch($obj->fk_user_author);
2502  $this->user_creation = $cuser;
2503  }
2504  if ($obj->fk_user_rappro) {
2505  $ruser = new User($this->db);
2506  $ruser->fetch($obj->fk_user_rappro);
2507  $this->user_rappro = $ruser;
2508  }
2509 
2510  $this->date_creation = $this->db->jdate($obj->datec);
2511  $this->date_modification = $this->db->jdate($obj->datem);
2512  //$this->date_rappro = $obj->daterappro; // Not yet managed
2513  }
2514  $this->db->free($result);
2515  } else {
2516  dol_print_error($this->db);
2517  }
2518  }
2519 
2520 
2530  public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2531  {
2532  global $langs;
2533 
2534  $result = '';
2535 
2536  $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2537  $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2538 
2539  $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">';
2540  $linkend = '</a>';
2541 
2542  $result .= $linkstart;
2543  if ($withpicto) {
2544  $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);
2545  }
2546  if ($withpicto != 2) {
2547  $result .= ($this->ref ? $this->ref : $this->id);
2548  }
2549  $result .= $linkend;
2550 
2551  if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2552  $result .= ' <span class="opacitymedium">(';
2553  }
2554  if ($option == 'showall') {
2555  $result .= $langs->trans("BankAccount").': ';
2556  $accountstatic = new Account($this->db);
2557  $accountstatic->id = $this->fk_account;
2558  $accountstatic->ref = $this->bank_account_ref;
2559  $accountstatic->label = $this->bank_account_label;
2560  $result .= $accountstatic->getNomUrl(0).', ';
2561  }
2562  if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2563  $result .= $langs->trans("BankLineConciliated").': ';
2564  $result .= yn($this->rappro);
2565  }
2566  if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2567  $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2568  $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2569  $resql = $this->db->query($sql);
2570  if ($resql) {
2571  $obj = $this->db->fetch_object($resql);
2572  if ($obj && $obj->nb) {
2573  $result .= ' - '.$langs->trans("Accounted").': '.yn(1);
2574  } else {
2575  $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2576  }
2577  }
2578  }
2579  if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2580  $result .= ')</span>';
2581  }
2582 
2583  return $result;
2584  }
2585 
2586 
2593  public function getLibStatut($mode = 0)
2594  {
2595  return $this->LibStatut($this->status, $mode);
2596  }
2597 
2598  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2606  public function LibStatut($status, $mode = 0)
2607  {
2608  // phpcs:enable
2609  //global $langs;
2610 
2611  //$langs->load('companies');
2612  /*
2613  if ($mode == 0)
2614  {
2615  if ($status==0) return $langs->trans("ActivityCeased");
2616  if ($status==1) return $langs->trans("InActivity");
2617  }
2618  if ($mode == 1)
2619  {
2620  if ($status==0) return $langs->trans("ActivityCeased");
2621  if ($status==1) return $langs->trans("InActivity");
2622  }
2623  if ($mode == 2)
2624  {
2625  if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2626  if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2627  }
2628  if ($mode == 3)
2629  {
2630  if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2631  if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2632  }
2633  if ($mode == 4)
2634  {
2635  if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2636  if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2637  }
2638  if ($mode == 5)
2639  {
2640  if ($status==0) return $langs->trans("ActivityCeased").' '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2641  if ($status==1) return $langs->trans("InActivity").' '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2642  }*/
2643 
2644  return '';
2645  }
2646 
2647 
2653  public function getVentilExportCompta()
2654  {
2655  $alreadydispatched = 0;
2656 
2657  $type = 'bank';
2658 
2659  $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);
2660  $resql = $this->db->query($sql);
2661  if ($resql) {
2662  $obj = $this->db->fetch_object($resql);
2663  if ($obj) {
2664  $alreadydispatched = $obj->nb;
2665  }
2666  } else {
2667  $this->error = $this->db->lasterror();
2668  return -1;
2669  }
2670 
2671  if ($alreadydispatched) {
2672  return 1;
2673  }
2674  return 0;
2675  }
2676 }
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.
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.
getNomUrl($withpicto=0, $mode='', $option='', $save_lastsearch_value=-1, $notooltip=0)
Return clicable name (with picto eventually)
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