dolibarr 19.0.3
account.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
6 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2015-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
11 * Copyright (C) 2019 JC Prieto <jcprieto@virtual20.com><prietojc@gmail.com>
12 * Copyright (C) 2022-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
34require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
35
36
40class 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 public $country_id;
188
194 public $type_lib = array();
195
201 public $status = array();
202
207 public $account_number;
208
212 public $fk_accountancy_journal;
216 public $accountancy_journal;
217
222 public $currency_code;
223
229 public $account_currency_code;
230
235 public $min_allowed;
236
241 public $min_desired;
242
247 public $comment;
248
253 public $date_solde;
254
261 public $solde;
262
267 public $balance;
268
273 public $ics;
274
279 public $ics_transfer;
280
284 public $oldref;
285
286
311 // BEGIN MODULEBUILDER PROPERTIES
315 public $fields = array(
316 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10),
317 'ref' =>array('type'=>'varchar(12)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>25),
318 'label' =>array('type'=>'varchar(30)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>30),
319 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>35, 'index'=>1),
320 'bank' =>array('type'=>'varchar(60)', 'label'=>'Bank', 'enabled'=>1, 'visible'=>-1, 'position'=>40),
321 'code_banque' =>array('type'=>'varchar(128)', 'label'=>'Code banque', 'enabled'=>1, 'visible'=>-1, 'position'=>45),
322 'code_guichet' =>array('type'=>'varchar(6)', 'label'=>'Code guichet', 'enabled'=>1, 'visible'=>-1, 'position'=>50),
323 'number' =>array('type'=>'varchar(255)', 'label'=>'Number', 'enabled'=>1, 'visible'=>-1, 'position'=>55),
324 'cle_rib' =>array('type'=>'varchar(5)', 'label'=>'Cle rib', 'enabled'=>1, 'visible'=>-1, 'position'=>60),
325 'bic' =>array('type'=>'varchar(11)', 'label'=>'Bic', 'enabled'=>1, 'visible'=>-1, 'position'=>65),
326 'iban_prefix' =>array('type'=>'varchar(34)', 'label'=>'Iban prefix', 'enabled'=>1, 'visible'=>-1, 'position'=>70),
327 'country_iban' =>array('type'=>'varchar(2)', 'label'=>'Country iban', 'enabled'=>1, 'visible'=>-1, 'position'=>75),
328 'cle_iban' =>array('type'=>'varchar(2)', 'label'=>'Cle iban', 'enabled'=>1, 'visible'=>-1, 'position'=>80),
329 'domiciliation' =>array('type'=>'varchar(255)', 'label'=>'Domiciliation', 'enabled'=>1, 'visible'=>-1, 'position'=>85),
330 'state_id' =>array('type'=>'integer', 'label'=>'StateId', 'enabled'=>1, 'visible'=>-1, 'position'=>90),
331 'fk_pays' =>array('type'=>'integer', 'label'=>'Country', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>95),
332 'proprio' =>array('type'=>'varchar(60)', 'label'=>'Proprio', 'enabled'=>1, 'visible'=>-1, 'position'=>100),
333 'owner_address' =>array('type'=>'varchar(255)', 'label'=>'Owner address', 'enabled'=>1, 'visible'=>-1, 'position'=>105),
334 'owner_zip' =>array('type'=>'varchar(25)', 'label'=>'Owner zip', 'enabled'=>1, 'visible'=>-1, 'position'=>106),
335 'owner_town' =>array('type'=>'varchar(50)', 'label'=>'Owner town', 'enabled'=>1, 'visible'=>-1, 'position'=>107),
336 'owner_country_id' =>array('type'=>'integer', 'label'=>'Owner country', 'enabled'=>1, 'visible'=>-1, 'position'=>108),
337 'courant' =>array('type'=>'smallint(6)', 'label'=>'Courant', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>110),
338 'clos' =>array('type'=>'smallint(6)', 'label'=>'Clos', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>115),
339 'rappro' =>array('type'=>'smallint(6)', 'label'=>'Rappro', 'enabled'=>1, 'visible'=>-1, 'position'=>120),
340 'url' =>array('type'=>'varchar(128)', 'label'=>'Url', 'enabled'=>1, 'visible'=>-1, 'position'=>125),
341 'account_number' =>array('type'=>'varchar(32)', 'label'=>'Account number', 'enabled'=>1, 'visible'=>-1, 'position'=>130),
342 'fk_accountancy_journal' =>array('type'=>'integer', 'label'=>'Accountancy journal ID', 'enabled'=>1, 'visible'=>-1, 'position'=>132),
343 'accountancy_journal' =>array('type'=>'varchar(20)', 'label'=>'Accountancy journal', 'enabled'=>1, 'visible'=>-1, 'position'=>135),
344 'currency_code' =>array('type'=>'varchar(3)', 'label'=>'Currency code', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>140),
345 'min_allowed' =>array('type'=>'integer', 'label'=>'Min allowed', 'enabled'=>1, 'visible'=>-1, 'position'=>145),
346 'min_desired' =>array('type'=>'integer', 'label'=>'Min desired', 'enabled'=>1, 'visible'=>-1, 'position'=>150),
347 'comment' =>array('type'=>'text', 'label'=>'Comment', 'enabled'=>1, 'visible'=>-1, 'position'=>155),
348 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>156),
349 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>157),
350 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>160),
351 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>165),
352 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170),
353 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>175),
354 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>180),
355 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>185),
356 );
357 // END MODULEBUILDER PROPERTIES
358
362 const TYPE_CURRENT = 1;
366 const TYPE_CASH = 2;
370 const TYPE_SAVINGS = 0;
371
372
373 const STATUS_OPEN = 0;
374 const STATUS_CLOSED = 1;
375
376
382 public function __construct(DoliDB $db)
383 {
384 global $langs;
385
386 $this->db = $db;
387
388 $this->solde = 0;
389
390 $this->type_lib = array(
391 self::TYPE_SAVINGS => $langs->trans("BankType0"),
392 self::TYPE_CURRENT => $langs->trans("BankType1"),
393 self::TYPE_CASH => $langs->trans("BankType2"),
394 );
395
396 $this->status = array(
397 self::STATUS_OPEN => $langs->trans("StatusAccountOpened"),
398 self::STATUS_CLOSED => $langs->trans("StatusAccountClosed")
399 );
400 }
401
407 public function __toString()
408 {
409 $string = '';
410 foreach ($this->getFieldsToShow() as $val) {
411 if ($val == 'BankCode') {
412 $string .= $this->code_banque.' ';
413 } elseif ($val == 'BankAccountNumber') {
414 $string .= $this->number.' ';
415 } elseif ($val == 'DeskCode') {
416 $string .= $this->code_guichet.' ';
417 } elseif ($val == 'BankAccountNumberKey') {
418 $string .= $this->cle_rib.' ';
419 } elseif ($val == 'BIC') {
420 $string .= $this->bic.' ';
421 } elseif ($val == 'IBAN') {
422 $string .= $this->iban.' ';
423 }
424 }
425
426 return trim($string);
427 }
428
429
435 public function canBeConciliated()
436 {
437 global $conf;
438
439 if (empty($this->rappro)) {
440 return -1;
441 }
442 if ($this->courant == Account::TYPE_CASH && !getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
443 return -2;
444 }
445 if ($this->clos) {
446 return -3;
447 }
448 return 1;
449 }
450
451
452 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
463 public function add_url_line($line_id, $url_id, $url, $label, $type)
464 {
465 // phpcs:enable
466 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
467 $sql .= "fk_bank";
468 $sql .= ", url_id";
469 $sql .= ", url"; // deprecated
470 $sql .= ", label";
471 $sql .= ", type";
472 $sql .= ") VALUES (";
473 $sql .= " ".((int) $line_id);
474 $sql .= ", ".((int) $url_id);
475 $sql .= ", '".$this->db->escape($url)."'"; // dperecated
476 $sql .= ", '".$this->db->escape($label)."'";
477 $sql .= ", '".$this->db->escape($type)."'";
478 $sql .= ")";
479
480 dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
481 if ($this->db->query($sql)) {
482 $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
483 return $rowid;
484 } else {
485 $this->error = $this->db->lasterror();
486 return -1;
487 }
488 }
489
490 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
500 public function get_url($fk_bank = 0, $url_id = 0, $type = '')
501 {
502 // phpcs:enable
503 $lines = array();
504
505 // Check parameters
506 if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
507 $this->error = "ErrorBadParameter";
508 return -1;
509 }
510
511 $sql = "SELECT fk_bank, url_id, url, label, type";
512 $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
513 if ($fk_bank > 0) {
514 $sql .= " WHERE fk_bank = ".((int) $fk_bank);
515 } else {
516 $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
517 }
518 $sql .= " ORDER BY type, label";
519
520 dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
521 $result = $this->db->query($sql);
522 if ($result) {
523 $i = 0;
524 $num = $this->db->num_rows($result);
525 while ($i < $num) {
526 $obj = $this->db->fetch_object($result);
527 // Anciens liens (pour compatibilite)
528 $lines[$i][0] = $obj->url;
529 $lines[$i][1] = $obj->url_id;
530 $lines[$i][2] = $obj->label;
531 $lines[$i][3] = $obj->type;
532 // Nouveaux liens
533 $lines[$i]['url'] = $obj->url;
534 $lines[$i]['url_id'] = $obj->url_id;
535 $lines[$i]['label'] = $obj->label;
536 $lines[$i]['type'] = $obj->type;
537 $lines[$i]['fk_bank'] = $obj->fk_bank;
538 $i++;
539 }
540 } else {
541 dol_print_error($this->db);
542 }
543
544 return $lines;
545 }
546
565 public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null)
566 {
567 global $langs;
568
569 // Deprecation warning
570 if (is_numeric($oper)) {
571 dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
572 }
573
574 if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
575 $this->id = $this->rowid;
576 }
577
578 // Clean parameters
579 $emetteur = trim($emetteur);
580 $banque = trim($banque);
581 $label = trim($label);
582
583 $now = dol_now();
584
585 if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
586 $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
587 $sql .= " WHERE id = ".((int) $oper);
588 $sql .= " AND entity IN (".getEntity('c_paiement').")";
589 $resql = $this->db->query($sql);
590 if ($resql) {
591 $obj = $this->db->fetch_object($resql);
592 $oper = $obj->code;
593 } else {
594 dol_print_error($this->db, 'Failed to get payment type code');
595 return -1;
596 }
597 }
598
599 // Check parameters
600 if (!$oper) {
601 $this->error = $langs->trans("OperNotDefined");
602 return -1;
603 }
604 if (!$this->id) {
605 $this->error = $langs->trans("ThisIdNotDefined");
606 return -2;
607 }
608 if ($this->courant == Account::TYPE_CASH && $oper != 'LIQ') {
609 $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
610 return -3;
611 }
612
613 $this->db->begin();
614
615 if (is_null($datev) || empty($datev)) {
616 $datev = $date;
617 }
618
619 $accline = new AccountLine($this->db);
620 $accline->datec = $now;
621 $accline->dateo = $date;
622 $accline->datev = $datev;
623 $accline->label = $label;
624 $accline->amount = $amount;
625 $accline->amount_main_currency = $amount_main_currency;
626 $accline->fk_user_author = $user->id;
627 $accline->fk_account = $this->id;
628 $accline->fk_type = $oper;
629 $accline->numero_compte = $accountancycode;
630 $accline->num_releve = $num_releve;
631
632 if ($num_chq) {
633 $accline->num_chq = $num_chq;
634 }
635
636 if ($emetteur) {
637 $accline->emetteur = $emetteur;
638 }
639
640 if ($banque) {
641 $accline->bank_chq = $banque;
642 }
643
644 if ($accline->insert() > 0) {
645 if ($categorie > 0) {
646 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class(";
647 $sql .= "lineid, fk_categ";
648 $sql .= ") VALUES (";
649 $sql .= ((int) $accline->id).", '".$this->db->escape($categorie)."'";
650 $sql .= ")";
651
652 $result = $this->db->query($sql);
653 if (!$result) {
654 $this->error = $this->db->lasterror();
655 $this->db->rollback();
656
657 return -4;
658 }
659 }
660
661 $this->db->commit();
662
663 return $accline->id;
664 } else {
665 $this->error = $accline->error;
666 $this->errors = $accline->errors;
667 $this->db->rollback();
668
669 return -5;
670 }
671 }
672
680 public function create(User $user, $notrigger = 0)
681 {
682 global $langs, $conf;
683
684 $error = 0;
685
686 // Clean parameters
687 if (!$this->min_allowed) {
688 $this->min_allowed = 0;
689 }
690 if (!$this->min_desired) {
691 $this->min_desired = 0;
692 }
693
694 // Check parameters
695 if (empty($this->country_id)) {
696 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
697 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
698 return -1;
699 }
700 if (empty($this->ref)) {
701 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
702 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
703 return -1;
704 }
705 if (empty($this->date_solde)) {
706 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
707 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
708 return -1;
709 }
710
711 // Load librairies to check BAN
712 $balance = $this->balance;
713 if (empty($balance) && !empty($this->solde)) {
714 $balance = $this->solde;
715 }
716 if (empty($balance)) {
717 $balance = 0;
718 }
719
720 if (empty($this->address && !empty($this->domiciliation))) {
721 dol_syslog(get_class($this)."::create domiciliation is deprecated use address", LOG_NOTICE);
722 $this->address = $this->domiciliation;
723 }
724
725 // Load the library to validate/check a BAN account
726 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
727
728 $now = dol_now();
729
730 $this->db->begin();
731
732 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
733 $sql .= "datec";
734 $sql .= ", ref";
735 $sql .= ", label";
736 $sql .= ", entity";
737 $sql .= ", account_number";
738 $sql .= ", fk_accountancy_journal";
739 $sql .= ", bank";
740 $sql .= ", code_banque";
741 $sql .= ", code_guichet";
742 $sql .= ", number";
743 $sql .= ", cle_rib";
744 $sql .= ", bic";
745 $sql .= ", iban_prefix";
746 $sql .= ", domiciliation";
747 $sql .= ", pti_in_ctti";
748 $sql .= ", proprio";
749 $sql .= ", owner_address";
750 $sql .= ", owner_zip";
751 $sql .= ", owner_town";
752 $sql .= ", owner_country_id";
753 $sql .= ", currency_code";
754 $sql .= ", rappro";
755 $sql .= ", min_allowed";
756 $sql .= ", min_desired";
757 $sql .= ", comment";
758 $sql .= ", state_id";
759 $sql .= ", fk_pays";
760 $sql .= ", ics";
761 $sql .= ", ics_transfer";
762 $sql .= ") VALUES (";
763 $sql .= "'".$this->db->idate($now)."'";
764 $sql .= ", '".$this->db->escape($this->ref)."'";
765 $sql .= ", '".$this->db->escape($this->label)."'";
766 $sql .= ", ".((int) $conf->entity);
767 $sql .= ", '".$this->db->escape($this->account_number)."'";
768 $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
769 $sql .= ", '".$this->db->escape($this->bank)."'";
770 $sql .= ", '".$this->db->escape($this->code_banque)."'";
771 $sql .= ", '".$this->db->escape($this->code_guichet)."'";
772 $sql .= ", '".$this->db->escape($this->number)."'";
773 $sql .= ", '".$this->db->escape($this->cle_rib)."'";
774 $sql .= ", '".$this->db->escape($this->bic)."'";
775 $sql .= ", '".$this->db->escape($this->iban)."'";
776 $sql .= ", '".$this->db->escape($this->address)."'";
777 $sql .= ", ".((int) $this->pti_in_ctti);
778 $sql .= ", '".$this->db->escape($this->proprio)."'";
779 $sql .= ", '".$this->db->escape($this->owner_address)."'";
780 $sql .= ", '".$this->db->escape($this->owner_zip)."'";
781 $sql .= ", '".$this->db->escape($this->owner_town)."'";
782 $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
783 $sql .= ", '".$this->db->escape($this->currency_code)."'";
784 $sql .= ", ".((int) $this->rappro);
785 $sql .= ", ".price2num($this->min_allowed, 'MT');
786 $sql .= ", ".price2num($this->min_desired, 'MT');
787 $sql .= ", '".$this->db->escape($this->comment)."'";
788 $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
789 $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
790 $sql .= ", '".$this->db->escape($this->ics)."'";
791 $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
792 $sql .= ")";
793
794 dol_syslog(get_class($this)."::create", LOG_DEBUG);
795 $resql = $this->db->query($sql);
796 if ($resql) {
797 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
798
799 $result = $this->update($user, 1);
800 if ($result > 0) {
801 $accline = new AccountLine($this->db);
802 $accline->datec = $now;
803 $accline->label = '('.$langs->trans("InitialBankBalance").')';
804 $accline->amount = price2num($balance);
805 $accline->fk_user_author = $user->id;
806 $accline->fk_account = $this->id;
807 $accline->datev = $this->date_solde;
808 $accline->dateo = $this->date_solde;
809 $accline->fk_type = 'SOLD';
810
811 if ($accline->insert() < 0) {
812 $error++;
813 $this->error = $accline->error;
814 $this->errors = $accline->errors;
815 }
816
817 if (!$error) {
818 $result = $this->insertExtraFields();
819 if ($result < 0) {
820 $error++;
821 }
822 }
823
824 if (!$error && !$notrigger) {
825 // Call trigger
826 $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
827 if ($result < 0) {
828 $error++;
829 }
830 // End call triggers
831 }
832 } else {
833 $error++;
834 }
835 } else {
836 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
837 $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
838 $error++;
839 } else {
840 $this->error = $this->db->error()." sql=".$sql;
841 $error++;
842 }
843 }
844
845 if (!$error) {
846 $this->db->commit();
847 return $this->id;
848 } else {
849 $this->db->rollback();
850 return -1 * $error;
851 }
852 }
853
861 public function update(User $user, $notrigger = 0)
862 {
863 global $langs, $conf;
864
865 $error = 0;
866
867 $this->db->begin();
868
869 // Check parameters
870 if (empty($this->country_id)) {
871 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
872 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
873 return -1;
874 }
875 if (empty($this->ref)) {
876 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
877 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
878 return -1;
879 }
880 if (!$this->label) {
881 $this->label = "???";
882 }
883
884 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
885
886 $sql .= " ref = '".$this->db->escape($this->ref)."'";
887 $sql .= ",label = '".$this->db->escape($this->label)."'";
888
889 $sql .= ",courant = ".((int) $this->courant);
890 $sql .= ",clos = ".((int) $this->clos);
891 $sql .= ",rappro = ".((int) $this->rappro);
892 $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
893 $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
894 $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
895 $sql .= ",bank = '".$this->db->escape($this->bank)."'";
896 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
897 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
898 $sql .= ",number='".$this->db->escape($this->number)."'";
899 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
900 $sql .= ",bic='".$this->db->escape($this->bic)."'";
901 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
902 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
903 $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
904 $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
905 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
906 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
907 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
908 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
909
910 $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
911
912 $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
913 $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
914 $sql .= ",comment = '".$this->db->escape($this->comment)."'";
915
916 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
917 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
918 $sql .= ",ics = '".$this->db->escape($this->ics)."'";
919 $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
920
921 $sql .= " WHERE rowid = ".((int) $this->id);
922
923 dol_syslog(get_class($this)."::update", LOG_DEBUG);
924 $result = $this->db->query($sql);
925 if ($result) {
926 // Actions on extra fields (by external module or standard code)
927 if (!$error) {
928 $result = $this->insertExtraFields();
929 if ($result < 0) {
930 $error++;
931 }
932 }
933
934 if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
935 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
936 $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type='bank_account' and entity = ".((int) $conf->entity);
937 $resql = $this->db->query($sql);
938 if (!$resql) {
939 $error++;
940 $this->error = $this->db->lasterror();
941 }
942
943 // We rename directory in order not to lose the attachments
944 $oldref = dol_sanitizeFileName($this->oldref);
945 $newref = dol_sanitizeFileName($this->ref);
946 $dirsource = $conf->bank->dir_output.'/'.$oldref;
947 $dirdest = $conf->bank->dir_output.'/'.$newref;
948 if (file_exists($dirsource)) {
949 dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
950 if (@rename($dirsource, $dirdest)) {
951 dol_syslog("Rename ok", LOG_DEBUG);
952 }
953 }
954 }
955
956 if (!$error && !$notrigger) {
957 // Call trigger
958 $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
959 if ($result < 0) {
960 $error++;
961 }
962 // End call triggers
963 }
964 } else {
965 $error++;
966 $this->error = $this->db->lasterror();
967 dol_print_error($this->db);
968 }
969
970 if (!$error) {
971 $this->db->commit();
972 return $this->id;
973 } else {
974 $this->db->rollback();
975 return -1 * $error;
976 }
977 }
978
979
980 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
987 public function update_bban(User $user = null)
988 {
989 // phpcs:enable
990 global $conf, $langs;
991
992 // Load library to get BAN control function
993 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
994
995 dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
996
997 // Check parameters
998 if (!$this->ref) {
999 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
1000 return -2;
1001 }
1002
1003 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
1004 $sql .= " bank = '".$this->db->escape($this->bank)."'";
1005 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1006 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1007 $sql .= ",number='".$this->db->escape($this->number)."'";
1008 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1009 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1010 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1011 $sql .= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
1012 $sql .= ",proprio = '".$this->db->escape($this->proprio)."'";
1013 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1014 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1015 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1016 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1017 $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null");
1018 $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null");
1019 $sql .= " WHERE rowid = ".((int) $this->id);
1020 $sql .= " AND entity = ".((int) $conf->entity);
1021
1022 dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
1023
1024 $result = $this->db->query($sql);
1025 if ($result) {
1026 return 1;
1027 } else {
1028 $this->error = $this->db->lasterror();
1029 dol_print_error($this->db);
1030 return -1;
1031 }
1032 }
1033
1034
1042 public function fetch($id, $ref = '')
1043 {
1044 if (empty($id) && empty($ref)) {
1045 $this->error = "ErrorBadParameters";
1046 return -1;
1047 }
1048
1049 $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant, ba.clos, ba.rappro, ba.url,";
1050 $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1051 $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,";
1052 $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1053 $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1054 $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1055 $sql .= ' c.code as country_code, c.label as country,';
1056 $sql .= ' d.code_departement as state_code, d.nom as state,';
1057 $sql .= ' aj.code as accountancy_journal';
1058 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1059 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1060 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1061 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1062 $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1063 if ($id) {
1064 $sql .= " AND ba.rowid = ".((int) $id);
1065 }
1066 if ($ref) {
1067 $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1068 }
1069
1070 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1071 $result = $this->db->query($sql);
1072 if ($result) {
1073 if ($this->db->num_rows($result)) {
1074 $obj = $this->db->fetch_object($result);
1075
1076 $this->id = $obj->rowid;
1077 $this->rowid = $obj->rowid;
1078 $this->ref = $obj->ref;
1079 $this->label = $obj->label;
1080 $this->type = $obj->courant;
1081 $this->courant = $obj->courant;
1082 $this->bank = $obj->bank;
1083 $this->clos = $obj->clos;
1084 $this->rappro = $obj->rappro;
1085 $this->url = $obj->url;
1086
1087 $this->code_banque = $obj->code_banque;
1088 $this->code_guichet = $obj->code_guichet;
1089 $this->number = $obj->number;
1090 $this->cle_rib = $obj->cle_rib;
1091 $this->bic = $obj->bic;
1092 $this->iban = $obj->iban;
1093 $this->domiciliation = $obj->address;
1094 $this->address = $obj->address;
1095 $this->pti_in_ctti = $obj->pti_in_ctti;
1096 $this->proprio = $obj->proprio;
1097 $this->owner_address = $obj->owner_address;
1098 $this->owner_zip = $obj->owner_zip;
1099 $this->owner_town = $obj->owner_town;
1100 $this->owner_country_id = $obj->owner_country_id;
1101
1102 $this->state_id = $obj->state_id;
1103 $this->state_code = $obj->state_code;
1104 $this->state = $obj->state;
1105
1106 $this->country_id = $obj->country_id;
1107 $this->country_code = $obj->country_code;
1108 $this->country = $obj->country;
1109
1110 $this->account_number = $obj->account_number;
1111 $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1112 $this->accountancy_journal = $obj->accountancy_journal;
1113
1114 $this->currency_code = $obj->currency_code;
1115 $this->account_currency_code = $obj->currency_code;
1116 $this->min_allowed = $obj->min_allowed;
1117 $this->min_desired = $obj->min_desired;
1118 $this->comment = $obj->comment;
1119
1120 $this->date_creation = $this->db->jdate($obj->date_creation);
1121 $this->date_modification = $this->db->jdate($obj->date_modification);
1122 $this->date_update = $this->date_modification; // For compatibility
1123
1124 $this->ics = $obj->ics;
1125 $this->ics_transfer = $obj->ics_transfer;
1126
1127 // Retrieve all extrafield
1128 // fetch optionals attributes and labels
1129 $this->fetch_optionals();
1130
1131 return 1;
1132 } else {
1133 return 0;
1134 }
1135 } else {
1136 $this->error = $this->db->lasterror();
1137 $this->errors[] = $this->error;
1138 return -1;
1139 }
1140 }
1141
1152 public function setCategories($categories)
1153 {
1154 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1155 return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1156 }
1157
1164 public function delete(User $user = null)
1165 {
1166 $error = 0;
1167
1168 $this->db->begin();
1169
1170 // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1171
1172 // Delete link between tag and bank account
1173 if (!$error) {
1174 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1175 $sql .= " WHERE fk_account = ".((int) $this->id);
1176
1177 $resql = $this->db->query($sql);
1178 if (!$resql) {
1179 $error++;
1180 $this->error = "Error ".$this->db->lasterror();
1181 }
1182 }
1183
1184 if (!$error) {
1185 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1186 $sql .= " WHERE rowid = ".((int) $this->id);
1187
1188 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1189 $result = $this->db->query($sql);
1190 if ($result) {
1191 // Remove extrafields
1192 if (!$error) {
1193 $result = $this->deleteExtraFields();
1194 if ($result < 0) {
1195 $error++;
1196 dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1197 }
1198 }
1199 } else {
1200 $error++;
1201 $this->error = "Error ".$this->db->lasterror();
1202 }
1203 }
1204
1205 if (!$error) {
1206 $this->db->commit();
1207 return 1;
1208 } else {
1209 $this->db->rollback();
1210 return -1;
1211 }
1212 }
1213
1214
1221 public function getLibStatut($mode = 0)
1222 {
1223 return $this->LibStatut($this->clos, $mode);
1224 }
1225
1226 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1234 public function LibStatut($status, $mode = 0)
1235 {
1236 // phpcs:enable
1237 global $langs;
1238 $langs->load('banks');
1239
1240 if ($status == self::STATUS_OPEN) {
1241 $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1242 $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1243 $statusType = 'status4';
1244 } else {
1245 $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1246 $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1247 $statusType = 'status5';
1248 }
1249
1250 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1251 }
1252
1253
1254 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1260 public function can_be_deleted()
1261 {
1262 // phpcs:enable
1263 $can_be_deleted = false;
1264
1265 $sql = "SELECT COUNT(rowid) as nb";
1266 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1267 $sql .= " WHERE fk_account = ".((int) $this->id);
1268
1269 $resql = $this->db->query($sql);
1270 if ($resql) {
1271 $obj = $this->db->fetch_object($resql);
1272 if ($obj->nb <= 1) {
1273 $can_be_deleted = true; // Juste le solde
1274 }
1275 } else {
1276 dol_print_error($this->db);
1277 }
1278 return $can_be_deleted;
1279 }
1280
1281
1287 public function error()
1288 {
1289 return $this->error;
1290 }
1291
1300 public function solde($option = 0, $date_end = '', $field = 'dateo')
1301 {
1302 $solde = 0;
1303
1304 $sql = "SELECT sum(amount) as amount";
1305 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1306 $sql .= " WHERE fk_account = ".((int) $this->id);
1307 if ($option == 1) {
1308 $sql .= " AND ".$this->db->escape($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1309 }
1310
1311 $resql = $this->db->query($sql);
1312 if ($resql) {
1313 if ($this->db->num_rows($resql)) {
1314 $obj = $this->db->fetch_object($resql);
1315 $solde = $obj->amount;
1316 }
1317 $this->db->free($resql);
1318 } else {
1319 $this->errors[] = $this->db->lasterror;
1320 return -1;
1321 }
1322
1323 return price2num($solde, 'MU');
1324 }
1325
1326 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1334 public function load_board(User $user, $filteraccountid = 0)
1335 {
1336 // phpcs:enable
1337 global $conf, $langs;
1338
1339 if ($user->socid) {
1340 return -1; // protection pour eviter appel par utilisateur externe
1341 }
1342
1343 $sql = "SELECT b.rowid, b.datev as datefin";
1344 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1345 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1346 $sql .= " WHERE b.rappro=0";
1347 $sql .= " AND b.fk_account = ba.rowid";
1348 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1349 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1350 $sql .= " AND clos = 0";
1351 if ($filteraccountid) {
1352 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1353 }
1354
1355 $resql = $this->db->query($sql);
1356 if ($resql) {
1357 $langs->load("banks");
1358 $now = dol_now();
1359
1360 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1361
1362 $response = new WorkboardResponse();
1363 $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1364 $response->label = $langs->trans("TransactionsToConciliate");
1365 $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1366 $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1367 $response->img = img_object('', "payment");
1368
1369 while ($obj = $this->db->fetch_object($resql)) {
1370 $response->nbtodo++;
1371 if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) {
1372 $response->nbtodolate++;
1373 }
1374 }
1375
1376 return $response;
1377 } else {
1378 dol_print_error($this->db);
1379 $this->error = $this->db->error();
1380 return -1;
1381 }
1382 }
1383
1384 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1391 public function load_state_board($filteraccountid = 0)
1392 {
1393 // phpcs:enable
1394 global $user;
1395
1396 if ($user->socid) {
1397 return -1; // protection pour eviter appel par utilisateur externe
1398 }
1399
1400 $sql = "SELECT count(b.rowid) as nb";
1401 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1402 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1403 $sql .= " WHERE b.fk_account = ba.rowid";
1404 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1405 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1406 $sql .= " AND clos = 0";
1407 if ($filteraccountid) {
1408 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1409 }
1410
1411 $resql = $this->db->query($sql);
1412 if ($resql) {
1413 while ($obj = $this->db->fetch_object($resql)) {
1414 $this->nb["banklines"] = $obj->nb;
1415 }
1416 $this->db->free($resql);
1417 return 1;
1418 } else {
1419 dol_print_error($this->db);
1420 $this->error = $this->db->error();
1421 return -1;
1422 }
1423 }
1424
1425
1431 public function countAccountToReconcile()
1432 {
1433 global $db, $conf, $user;
1434
1435 //Protection against external users
1436 if ($user->socid) {
1437 return 0;
1438 }
1439
1440 $nb = 0;
1441
1442 $sql = "SELECT COUNT(ba.rowid) as nb";
1443 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1444 $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1445 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1446 if (!getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
1447 $sql .= " AND ba.courant != 2";
1448 }
1449 $resql = $this->db->query($sql);
1450 if ($resql) {
1451 $obj = $this->db->fetch_object($resql);
1452 $nb = $obj->nb;
1453 } else {
1454 dol_print_error($this->db);
1455 }
1456
1457 return $nb;
1458 }
1459
1467 public function getTooltipContentArray($params)
1468 {
1469 global $langs;
1470 $langs->loadLangs(['banks', 'compta']);
1471 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1472
1473 $datas = array();
1474
1475 $nofetch = !empty($params['nofetch']);
1476 $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1477 if (isset($this->status)) {
1478 $pictos .= ' '.$this->getLibStatut(5);
1479 }
1480 $datas['picto'] = $pictos;
1481 $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1482 $datas['accountnumber'] = '<br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1483 $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1484 $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1485 $datas['accountcurrency'] = '<br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1486
1487 if (isModEnabled('accounting')) {
1488 include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1489 $langs->load("accountancy");
1490 $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1491 $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1492 }
1493 // show categories for this record only in ajax to not overload lists
1494 if (isModEnabled('categorie') && !$nofetch) {
1495 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1496 $form = new Form($this->db);
1497 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1498 }
1499
1500 return $datas;
1501 }
1502
1514 public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1515 {
1516 global $conf, $langs;
1517
1518 if (!empty($conf->dol_no_mouse_hover)) {
1519 $notooltip = 1; // Force disable tooltips
1520 }
1521
1522 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1523
1524 $result = '';
1525 $classfortooltip = 'classfortooltip';
1526 $dataparams = '';
1527 $params = [
1528 'id' => $this->id,
1529 'objecttype' => $this->element,
1530 'option' => $option,
1531 'nofetch' => 1,
1532 ];
1533 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1534 $classfortooltip = 'classforajaxtooltip';
1535 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1536 $label = '';
1537 } else {
1538 $label = implode($this->getTooltipContentArray($params));
1539 }
1540
1541 $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id;
1542 if ($mode == 'transactions') {
1543 $url = DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id;
1544 } elseif ($mode == 'receipts') {
1545 $url = DOL_URL_ROOT.'/compta/bank/releve.php?account='.$this->id;
1546 }
1547
1548 if ($option != 'nolink') {
1549 // Add param to save lastsearch_values or not
1550 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1551 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1552 $add_save_lastsearch_values = 1;
1553 }
1554 if ($add_save_lastsearch_values) {
1555 $url .= '&save_lastsearch_values=1';
1556 }
1557 }
1558
1559 $linkclose = '';
1560 if (empty($notooltip)) {
1561 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1562 $label = $langs->trans("BankAccount");
1563 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1564 }
1565 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1566 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1567 } else {
1568 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1569 }
1570
1571 if ($option == 'nolink' || empty($url)) {
1572 $linkstart = '<span';
1573 } else {
1574 $linkstart = '<a href="'.$url.'"';
1575 }
1576 $linkstart .= $linkclose.'>';
1577 if ($option == 'nolink' || empty($url)) {
1578 $linkend = '</span>';
1579 } else {
1580 $linkend = '</a>';
1581 }
1582
1583 $result .= $linkstart;
1584
1585 if ($withpicto) {
1586 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1587 }
1588 if ($withpicto != 2) {
1589 $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1590 }
1591 $result .= $linkend;
1592
1593 return $result;
1594 }
1595
1596
1597 // Method after here are common to Account and CompanyBankAccount
1598
1599
1605 public function verif()
1606 {
1607 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1608
1609 $error = 0;
1610
1611 // Call functions to check BAN
1612 if (!checkIbanForAccount($this)) {
1613 $error++;
1614 $this->error = 'IBANNotValid';
1615 }
1616 if (!checkSwiftForAccount($this)) {
1617 $error++;
1618 $this->error = 'SwiftNotValid';
1619 }
1620
1621 if (! $error) {
1622 return 1;
1623 } else {
1624 return 0;
1625 }
1626 }
1627
1633 public function getCountryCode()
1634 {
1635 global $mysoc;
1636
1637 // We return country code of bank account
1638 if (!empty($this->country_code)) {
1639 return $this->country_code;
1640 }
1641
1642 // For backward compatibility, we try to guess country from other information
1643 if (!empty($this->iban)) {
1644 // If IBAN defined, we can know country of account from it
1645 $reg = array();
1646 if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1647 return $reg[1];
1648 }
1649 }
1650
1651 // If this class is linked to a third party
1652 if (!empty($this->socid)) {
1653 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1654 $company = new Societe($this->db);
1655 $result = $company->fetch($this->socid);
1656 if (!empty($company->country_code)) {
1657 return $company->country_code;
1658 }
1659 }
1660
1661 // We return country code of managed company
1662 if (!empty($mysoc->country_code)) {
1663 return $mysoc->country_code;
1664 }
1665
1666 return '';
1667 }
1668
1676 public function getBannerAddress($htmlkey, $object)
1677 {
1678 global $conf, $langs;
1679
1680 $out = '';
1681
1682 $outdone = 0;
1683 $coords = $this->getFullAddress(1, ', ', getDolGlobalInt('MAIN_SHOW_REGION_IN_STATE_SELECT'));
1684 if ($coords) {
1685 if (!empty($conf->use_javascript_ajax)) {
1686 // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
1687 $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
1688 $out .= img_picto($langs->trans("Address"), 'map-marker-alt');
1689 $out .= '</a> ';
1690 }
1691 $address = dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
1692 if ($address) {
1693 $out .= $address;
1694 $outdone++;
1695 }
1696 $outdone++;
1697 }
1698
1699 return $out;
1700 }
1701
1702
1711 public function useDetailedBBAN()
1712 {
1713 $country_code = $this->getCountryCode();
1714
1715 if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1716 return 1; // France, Spain, Gabon, ... - Not valid for CH
1717 }
1718 if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1719 return 2; // Australia, England...
1720 }
1721 return 0;
1722 }
1723
1729 public function needIBAN()
1730 {
1731 global $conf;
1732
1733 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1734 return 0;
1735 }
1736
1737 $country_code = $this->getCountryCode();
1738
1739 $country_code_in_EEC = array(
1740 'AT', // Austria
1741 'BE', // Belgium
1742 'BG', // Bulgaria
1743 'CY', // Cyprus
1744 'CZ', // Czech republic
1745 'DE', // Germany
1746 'DK', // Danemark
1747 'EE', // Estonia
1748 'ES', // Spain
1749 'FI', // Finland
1750 'FR', // France
1751 'GB', // United Kingdom
1752 'GR', // Greece
1753 'HR', // Croatia
1754 'NL', // Holland
1755 'HU', // Hungary
1756 'IE', // Ireland
1757 'IM', // Isle of Man - Included in UK
1758 'IT', // Italy
1759 'LT', // Lithuania
1760 'LU', // Luxembourg
1761 'LV', // Latvia
1762 'MC', // Monaco - Included in France
1763 'MT', // Malta
1764 //'NO', // Norway
1765 'PL', // Poland
1766 'PT', // Portugal
1767 'RO', // Romania
1768 'SE', // Sweden
1769 'SK', // Slovakia
1770 'SI', // Slovenia
1771 'UK', // United Kingdom
1772 //'CH', // Switzerland - No. Swizerland in not in EEC
1773 );
1774
1775 if (in_array($country_code, $country_code_in_EEC)) {
1776 return 1; // France, Spain, ...
1777 }
1778 return 0;
1779 }
1780
1787 public function info($id)
1788 {
1789 }
1790
1805 public function getFieldsToShow($includeibanbic = 0)
1806 {
1807 //Get the required properties depending on the country
1808 $detailedBBAN = $this->useDetailedBBAN();
1809
1810 if ($detailedBBAN == 0) {
1811 $fieldarray = array(
1812 'BankAccountNumber'
1813 );
1814 } elseif ($detailedBBAN == 2) {
1815 $fieldarray = array(
1816 'BankCode',
1817 'BankAccountNumber'
1818 );
1819 } else {
1820 $fieldarray = self::getAccountNumberOrder();
1821 }
1822
1823 //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
1824 if ($includeibanbic) {
1825 $fieldarray[] = 'IBAN';
1826 $fieldarray[] = 'BIC';
1827 }
1828 //}
1829
1830 //Get the order the properties are shown
1831 return $fieldarray;
1832 }
1833
1844 public static function getAccountNumberOrder()
1845 {
1846 global $conf;
1847
1848 $fieldlists = array(
1849 'BankCode',
1850 'DeskCode',
1851 'BankAccountNumber',
1852 'BankAccountNumberKey'
1853 );
1854
1855 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION')) {
1856 if (is_numeric($conf->global->BANK_SHOW_ORDER_OPTION)) {
1857 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION') == '1') {
1858 $fieldlists = array(
1859 'BankCode',
1860 'DeskCode',
1861 'BankAccountNumberKey',
1862 'BankAccountNumber'
1863 );
1864 }
1865 } else {
1866 //Replace the old AccountNumber key with the new BankAccountNumber key
1867 $fieldlists = explode(
1868 ' ',
1869 preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
1870 );
1871 }
1872 }
1873
1874 return $fieldlists;
1875 }
1876
1877
1885 public function initAsSpecimen()
1886 {
1887 // Example of IBAN FR7630001007941234567890185
1888 $this->specimen = 1;
1889 $this->ref = 'MBA';
1890 $this->label = 'My Big Company Bank account';
1891 $this->bank = 'MyBank';
1892 $this->courant = Account::TYPE_CURRENT;
1893 $this->clos = Account::STATUS_OPEN;
1894 $this->code_banque = '30001';
1895 $this->code_guichet = '00794';
1896 $this->number = '12345678901';
1897 $this->cle_rib = '85';
1898 $this->bic = 'AA12';
1899 $this->iban = 'FR7630001007941234567890185';
1900 $this->domiciliation = 'Banque de France';
1901 $this->proprio = 'Owner';
1902 $this->owner_address = 'Owner address';
1903 $this->owner_zip = 'Owner zip';
1904 $this->owner_town = 'Owner town';
1905 $this->owner_country_id = 'Owner country_id';
1906 $this->country_id = 1;
1907 }
1908
1917 public static function replaceThirdparty($dbs, $origin_id, $dest_id)
1918 {
1919 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'";
1920
1921 if ($dbs->query($sql)) {
1922 return true;
1923 } else {
1924 //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.
1925 //$this->errors = $dbs->lasterror();
1926 return false;
1927 }
1928 }
1929
1937 public function getKanbanView($option = '', $arraydata = null)
1938 {
1939 global $langs;
1940
1941 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1942
1943 $return = '<div class="box-flex-item box-flex-grow-zero">';
1944 $return .= '<div class="info-box info-box-sm">';
1945 $return .= '<span class="info-box-icon bg-infobox-action">';
1946 $return .= img_picto('', $this->picto);
1947 $return .= '</span>';
1948 $return .= '<div class="info-box-content">';
1949 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
1950 if ($selected >= 0) {
1951 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1952 }
1953 if (property_exists($this, 'type_lib')) {
1954 $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
1955 }
1956 if (method_exists($this, 'solde')) {
1957 $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
1958 $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>';
1959 }
1960 if (method_exists($this, 'getLibStatut')) {
1961 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
1962 }
1963 $return .= '</div>';
1964 $return .= '</div>';
1965 $return .= '</div>';
1966 return $return;
1967 }
1968}
1969
1970
1971require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1972
1976class AccountLine extends CommonObjectLine
1977{
1981 public $error = '';
1982
1986 public $db;
1987
1991 public $element = 'bank';
1992
1996 public $table_element = 'bank';
1997
2001 public $picto = 'accountline';
2002
2006 public $id;
2007
2011 public $ref;
2012
2018 public $datec;
2019
2025 public $dateo;
2026
2032 public $datev;
2033
2034 public $amount; /* Amount of payment in the bank account currency */
2035 public $amount_main_currency; /* Amount in the currency of company if bank account use another currency */
2036
2040 public $fk_user_author;
2041
2045 public $fk_user_rappro;
2046
2050 public $fk_type;
2051
2055 public $fk_bordereau;
2056
2060 public $fk_account;
2061
2065 public $bank_account_ref;
2066
2070 public $bank_account_label;
2071
2075 public $numero_compte;
2076
2080 public $emetteur;
2081
2082 public $rappro; // Is it conciliated
2083 public $num_releve; // If conciliated, what is bank statement
2084 public $num_chq; // Num of cheque
2085 public $bank_chq; // Bank of cheque
2086
2090 public $label;
2091
2092 public $note;
2093
2097 public $user_rappro;
2098
2099
2105 public function __construct(DoliDB $db)
2106 {
2107 $this->db = $db;
2108 }
2109
2118 public function fetch($rowid, $ref = '', $num = '')
2119 {
2120 // Check parameters
2121 if (empty($rowid) && empty($ref) && empty($num)) {
2122 return -1;
2123 }
2124
2125 $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2126 $sql .= " b.fk_user_author, b.fk_user_rappro,";
2127 $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2128 $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2129 $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2130 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2131 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2132 $sql .= " WHERE b.fk_account = ba.rowid";
2133 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2134 if ($num) {
2135 $sql .= " AND b.num_chq = '".$this->db->escape($num)."'";
2136 } elseif ($ref) {
2137 $sql .= " AND b.rowid = '".$this->db->escape($ref)."'";
2138 } else {
2139 $sql .= " AND b.rowid = ".((int) $rowid);
2140 }
2141
2142 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2143 $result = $this->db->query($sql);
2144 if ($result) {
2145 $ret = 0;
2146
2147 $obj = $this->db->fetch_object($result);
2148 if ($obj) {
2149 $this->id = $obj->rowid;
2150 $this->rowid = $obj->rowid;
2151 $this->ref = $obj->rowid;
2152
2153 $this->datec = $this->db->jdate($obj->datec);
2154 $this->datev = $this->db->jdate($obj->datev);
2155 $this->dateo = $this->db->jdate($obj->dateo);
2156 $this->amount = $obj->amount;
2157 $this->label = $obj->label;
2158 $this->note = $obj->note;
2159
2160 $this->fk_user_author = $obj->fk_user_author;
2161 $this->fk_user_rappro = $obj->fk_user_rappro;
2162
2163 $this->fk_type = $obj->fk_type; // Type of transaction
2164 $this->rappro = (int) $obj->rappro;
2165 $this->num_releve = $obj->num_releve;
2166
2167 $this->num_chq = $obj->num_chq;
2168 $this->bank_chq = $obj->banque;
2169 $this->fk_bordereau = $obj->fk_bordereau;
2170
2171 $this->fk_account = $obj->fk_account;
2172 $this->bank_account_ref = $obj->bank_account_ref;
2173 $this->bank_account_label = $obj->bank_account_label;
2174
2175 // Retrieve all extrafield
2176 // fetch optionals attributes and labels
2177 $this->fetch_optionals();
2178
2179 $ret = 1;
2180 }
2181 $this->db->free($result);
2182 return $ret;
2183 } else {
2184 return -1;
2185 }
2186 }
2187
2193 public function insert()
2194 {
2195 $error = 0;
2196
2197 $this->db->begin();
2198
2199 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2200 $sql .= "datec";
2201 $sql .= ", dateo";
2202 $sql .= ", datev";
2203 $sql .= ", label";
2204 $sql .= ", amount";
2205 $sql .= ", amount_main_currency";
2206 $sql .= ", fk_user_author";
2207 $sql .= ", num_chq";
2208 $sql .= ", fk_account";
2209 $sql .= ", fk_type";
2210 $sql .= ", emetteur,banque";
2211 $sql .= ", rappro";
2212 $sql .= ", numero_compte";
2213 $sql .= ", num_releve";
2214 $sql .= ") VALUES (";
2215 $sql .= "'".$this->db->idate($this->datec)."'";
2216 $sql .= ", '".$this->db->idate($this->dateo)."'";
2217 $sql .= ", '".$this->db->idate($this->datev)."'";
2218 $sql .= ", '".$this->db->escape($this->label)."'";
2219 $sql .= ", ".price2num($this->amount);
2220 $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2221 $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2222 $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2223 $sql .= ", '".$this->db->escape($this->fk_account)."'";
2224 $sql .= ", '".$this->db->escape($this->fk_type)."'";
2225 $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2226 $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2227 $sql .= ", ".(int) $this->rappro;
2228 $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2229 $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2230 $sql .= ")";
2231
2232
2233 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2234 $resql = $this->db->query($sql);
2235 if ($resql) {
2236 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2237 // Actions on extra fields (by external module or standard code)
2238 $result = $this->insertExtraFields();
2239 if ($result < 0) {
2240 $error++;
2241 }
2242 } else {
2243 $error++;
2244 $this->error = $this->db->lasterror();
2245 dol_print_error($this->db);
2246 }
2247
2248 if (!$error) {
2249 $this->db->commit();
2250 return $this->id;
2251 } else {
2252 $this->db->rollback();
2253 return -1 * $error;
2254 }
2255 }
2256
2264 public function delete(User $user = null, $notrigger = 0)
2265 {
2266 $nbko = 0;
2267
2268 if ($this->rappro) {
2269 // Protection to avoid any delete of consolidated lines
2270 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2271 return -1;
2272 }
2273
2274 $this->db->begin();
2275
2276 if (!$notrigger) {
2277 // Call trigger
2278 $result = $this->call_trigger('BANKACCOUNTLINE_DELETE', $user);
2279 if ($result < 0) {
2280 $this->db->rollback();
2281 return -1;
2282 }
2283 // End call triggers
2284 }
2285
2286 // Protection to avoid any delete of accounted lines. Protection on by default
2287 if (!getDolGlobalString('BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING')) {
2288 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2289 $resql = $this->db->query($sql);
2290 if ($resql) {
2291 $obj = $this->db->fetch_object($resql);
2292 if ($obj && $obj->nb) {
2293 $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2294 $this->db->rollback();
2295 return -1;
2296 }
2297 } else {
2298 $this->error = $this->db->lasterror();
2299 $this->db->rollback();
2300 return -1;
2301 }
2302 }
2303
2304 // Delete urls
2305 $result = $this->delete_urls($user);
2306 if ($result < 0) {
2307 $nbko++;
2308 }
2309
2310 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid=".(int) $this->rowid;
2311 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2312 $result = $this->db->query($sql);
2313 if (!$result) {
2314 $nbko++;
2315 }
2316
2317 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2318 $result = $this->db->query($sql);
2319 if (!$result) {
2320 $nbko++;
2321 }
2322
2323 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2324 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2325 $result = $this->db->query($sql);
2326 if (!$result) {
2327 $nbko++;
2328 }
2329
2330 if (!$nbko) {
2331 $this->db->commit();
2332 return 1;
2333 } else {
2334 $this->db->rollback();
2335 return -$nbko;
2336 }
2337 }
2338
2339
2340 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2347 public function delete_urls(User $user = null)
2348 {
2349 // phpcs:enable
2350 $nbko = 0;
2351
2352 if ($this->rappro) {
2353 // Protection to avoid any delete of consolidated lines
2354 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2355 return -1;
2356 }
2357
2358 $this->db->begin();
2359
2360 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2361 dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2362 $result = $this->db->query($sql);
2363 if (!$result) {
2364 $nbko++;
2365 }
2366
2367 if (!$nbko) {
2368 $this->db->commit();
2369 return 1;
2370 } else {
2371 $this->db->rollback();
2372 return -$nbko;
2373 }
2374 }
2375
2376
2384 public function update(User $user, $notrigger = 0)
2385 {
2386 $this->db->begin();
2387
2388 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2389 $sql .= " amount = ".price2num($this->amount).",";
2390 $sql .= " datev='".$this->db->idate($this->datev)."',";
2391 $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2392 $sql .= " WHERE rowid = ".((int) $this->rowid);
2393
2394 dol_syslog(get_class($this)."::update", LOG_DEBUG);
2395 $resql = $this->db->query($sql);
2396 if ($resql) {
2397 $this->db->commit();
2398 return 1;
2399 } else {
2400 $this->db->rollback();
2401 $this->error = $this->db->error();
2402 return -1;
2403 }
2404 }
2405
2406
2407 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2416 public function update_conciliation(User $user, $cat, $conciliated = 1)
2417 {
2418 // phpcs:enable
2419 global $conf, $langs;
2420
2421 $this->db->begin();
2422
2423 // Check statement field
2424 if (getDolGlobalString('BANK_STATEMENT_REGEX_RULE')) {
2425 if (!preg_match('/' . getDolGlobalString('BANK_STATEMENT_REGEX_RULE').'/', $this->num_releve)) {
2426 $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", $conf->global->BANK_STATEMENT_REGEX_RULE);
2427 return -1;
2428 }
2429 }
2430
2431 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2432 $sql .= " rappro = ".((int) $conciliated);
2433 $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2434 if ($conciliated) {
2435 $sql .= ", fk_user_rappro = ".$user->id;
2436 }
2437 $sql .= " WHERE rowid = ".((int) $this->id);
2438
2439 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2440 $resql = $this->db->query($sql);
2441 if ($resql) {
2442 if (!empty($cat) && $cat > 0) {
2443 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
2444 $sql .= "lineid";
2445 $sql .= ", fk_categ";
2446 $sql .= ") VALUES (";
2447 $sql .= $this->id;
2448 $sql .= ", ".((int) $cat);
2449 $sql .= ")";
2450
2451 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2452 $this->db->query($sql);
2453
2454 // No error check. Can fail if category already affected
2455 // TODO Do no try the insert if link already exists
2456 }
2457
2458 $this->rappro = 1;
2459
2460 $this->db->commit();
2461 return 1;
2462 } else {
2463 $this->db->rollback();
2464 return -1;
2465 }
2466 }
2467
2468
2469 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2477 public function datev_change($rowid, $sign = 1)
2478 {
2479 // phpcs:enable
2480 $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2481 $resql = $this->db->query($sql);
2482 if ($resql) {
2483 $obj = $this->db->fetch_object($resql);
2484 $newdate = $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2485
2486 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2487 $sql .= " datev = '".$this->db->idate($newdate)."'";
2488 $sql .= " WHERE rowid = ".((int) $rowid);
2489
2490 $result = $this->db->query($sql);
2491 if ($result) {
2492 if ($this->db->affected_rows($result)) {
2493 return 1;
2494 }
2495 } else {
2496 dol_print_error($this->db);
2497 return 0;
2498 }
2499 } else {
2500 dol_print_error($this->db);
2501 }
2502 return 0;
2503 }
2504
2505 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2512 public function datev_next($id)
2513 {
2514 // phpcs:enable
2515 return $this->datev_change($id, 1);
2516 }
2517
2518 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2525 public function datev_previous($id)
2526 {
2527 // phpcs:enable
2528 return $this->datev_change($id, -1);
2529 }
2530
2531
2532 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2540 public function dateo_change($rowid, $sign = 1)
2541 {
2542 // phpcs:enable
2543 $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2544 $resql = $this->db->query($sql);
2545 if ($resql) {
2546 $obj = $this->db->fetch_object($resql);
2547 $newdate = $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2548
2549 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2550 $sql .= " dateo = '".$this->db->idate($newdate)."'";
2551 $sql .= " WHERE rowid = ".((int) $rowid);
2552
2553 $result = $this->db->query($sql);
2554 if ($result) {
2555 if ($this->db->affected_rows($result)) {
2556 return 1;
2557 }
2558 } else {
2559 dol_print_error($this->db);
2560 return 0;
2561 }
2562 } else {
2563 dol_print_error($this->db);
2564 }
2565 return 0;
2566 }
2567
2568 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2575 public function dateo_next($id)
2576 {
2577 // phpcs:enable
2578 return $this->dateo_change($id, 1);
2579 }
2580
2581 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2588 public function dateo_previous($id)
2589 {
2590 // phpcs:enable
2591 return $this->dateo_change($id, -1);
2592 }
2593
2594
2601 public function info($id)
2602 {
2603 $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2604 $sql .= ' b.fk_user_author, b.fk_user_rappro';
2605 $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2606 $sql .= ' WHERE b.rowid = '.((int) $id);
2607
2608 $result = $this->db->query($sql);
2609 if ($result) {
2610 if ($this->db->num_rows($result)) {
2611 $obj = $this->db->fetch_object($result);
2612
2613 $this->id = $obj->rowid;
2614
2615 $this->user_creation_id = $obj->fk_user_author;
2616 $this->user_rappro = $obj->fk_user_rappro;
2617 $this->date_creation = $this->db->jdate($obj->datec);
2618 $this->date_modification = $this->db->jdate($obj->datem);
2619 //$this->date_rappro = $obj->daterappro; // Not yet managed
2620 }
2621 $this->db->free($result);
2622 } else {
2623 dol_print_error($this->db);
2624 }
2625 }
2626
2627
2637 public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2638 {
2639 global $conf, $langs;
2640
2641 $result = '';
2642
2643 $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2644 $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2645 if ($this->amount) {
2646 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2647 }
2648
2649 $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">';
2650 $linkend = '</a>';
2651
2652 $result .= $linkstart;
2653 if ($withpicto) {
2654 $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);
2655 }
2656 if ($withpicto != 2) {
2657 $result .= ($this->ref ? $this->ref : $this->id);
2658 }
2659
2660 $result .= $linkend;
2661
2662 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2663 $result .= ' <span class="opacitymedium">(';
2664 }
2665 if ($option == 'showall') {
2666 $result .= $langs->trans("BankAccount").': ';
2667 $accountstatic = new Account($this->db);
2668 $accountstatic->id = $this->fk_account;
2669 $accountstatic->ref = $this->bank_account_ref;
2670 $accountstatic->label = $this->bank_account_label;
2671 $result .= $accountstatic->getNomUrl(0).', ';
2672 }
2673 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2674 $result .= $langs->trans("BankLineConciliated").': ';
2675 $result .= yn($this->rappro);
2676 }
2677 if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2678 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2679 $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2680 $resql = $this->db->query($sql);
2681 if ($resql) {
2682 $obj = $this->db->fetch_object($resql);
2683 if ($obj && $obj->nb) {
2684 $result .= ' - '.$langs->trans("Accounted").': '.yn(1);
2685 } else {
2686 $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2687 }
2688 }
2689 }
2690 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2691 $result .= ')</span>';
2692 }
2693
2694 return $result;
2695 }
2696
2697
2704 public function getLibStatut($mode = 0)
2705 {
2706 return $this->LibStatut($this->status, $mode);
2707 }
2708
2709 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2717 public function LibStatut($status, $mode = 0)
2718 {
2719 // phpcs:enable
2720 //global $langs;
2721
2722 //$langs->load('companies');
2723 /*
2724 if ($mode == 0)
2725 {
2726 if ($status==0) return $langs->trans("ActivityCeased");
2727 if ($status==1) return $langs->trans("InActivity");
2728 }
2729 if ($mode == 1)
2730 {
2731 if ($status==0) return $langs->trans("ActivityCeased");
2732 if ($status==1) return $langs->trans("InActivity");
2733 }
2734 if ($mode == 2)
2735 {
2736 if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2737 if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2738 }
2739 if ($mode == 3)
2740 {
2741 if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2742 if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2743 }
2744 if ($mode == 4)
2745 {
2746 if ($status==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2747 if ($status==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2748 }
2749 if ($mode == 5)
2750 {
2751 if ($status==0) return $langs->trans("ActivityCeased").' '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2752 if ($status==1) return $langs->trans("InActivity").' '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2753 }*/
2754
2755 return '';
2756 }
2757
2763 public function getVentilExportCompta()
2764 {
2765 $alreadydispatched = 0;
2766
2767 $type = 'bank';
2768
2769 $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);
2770 $resql = $this->db->query($sql);
2771 if ($resql) {
2772 $obj = $this->db->fetch_object($resql);
2773 if ($obj) {
2774 $alreadydispatched = $obj->nb;
2775 }
2776 } else {
2777 $this->error = $this->db->lasterror();
2778 return -1;
2779 }
2780
2781 if ($alreadydispatched) {
2782 return 1;
2783 }
2784 return 0;
2785 }
2786}
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
checkSwiftForAccount(Account $account=null, $swift=null)
Check SWIFT informations for a bank account.
Definition bank.lib.php:282
checkIbanForAccount(Account $account=null, $ibantocheck=null)
Check IBAN number informations for a bank account.
Definition bank.lib.php:303
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition bank.lib.php:328
$object ref
Definition info.php:79
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.
update(User $user, $notrigger=0)
Update bank account card.
getCountryCode()
Return account country code.
getLibStatut($mode=0)
Return label of object status.
getBannerAddress($htmlkey, $object)
Return full address for banner.
error()
Return error.
info($id)
Load miscellaneous information for tab "Info".
const TYPE_CASH
Cash account.
__toString()
Shows the account number in the appropriate format.
const TYPE_SAVINGS
Savings account.
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.
getFieldsToShow($includeibanbic=0)
Returns the fields in order that this bank account should show to the user Will return an array with ...
delete(User $user=null)
Delete bank account from database.
load_board(User $user, $filteraccountid=0)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
get_url($fk_bank=0, $url_id=0, $type='')
TODO Move this into AccountLine Return array with links from llx_bank_url.
addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur='', $banque='', $accountancycode='', $datev=null, $num_releve='', $amount_main_currency=null)
Add an entry into table ".MAIN_DB_PREFIX."bank.
LibStatut($status, $mode=0)
Return label of given object status.
Class to manage bank transaction lines.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
getFullAddress($withcountry=0, $sep="\n", $withregion=0, $extralangcode='')
Return full address of contact.
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class to manage generation of HTML components Only common components must be here.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
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)
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a 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)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
Definition invoice.php:1926
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:121