dolibarr 25.0.0-alpha
account.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4 * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
6 * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
7 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
8 * Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
9 * Copyright (C) 2015-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2016 Ferran Marcet <fmarcet@2byte.es>
11 * Copyright (C) 2019 JC Prieto <jcprieto@virtual20.com><prietojc@gmail.com>
12 * Copyright (C) 2022-2026 Frédéric France <frederic.france@free.fr>
13 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
14 * Copyright (C) 2026 Sylvain Legrand <contact@infras.fr>
15 * Copyright (C) 2026 Lucky Ranasolonirina <technique@infras.fr>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <https://www.gnu.org/licenses/>.
29 */
30
37require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
38
39
43class Account extends CommonObject
44{
48 public $element = 'bank_account';
49
53 public $table_element = 'bank_account';
54
58 public $picto = 'account';
59
65 public $ref;
66
72 public $rowid;
73
78 public $label;
79
86 public $courant;
87
92 public $type;
93
98 public $bank;
99
107 public $clos = self::STATUS_OPEN;
108
113 public $rappro = 1;
114
119 public $url;
120
125 public $socid;
126
131 public $code_banque;
132
137 public $code_guichet;
138
143 public $number;
144
149 public $cle_rib;
150
155 public $bic;
156
161 public $iban;
162
169 public $iban_prefix;
170
175 public $pti_in_ctti = 0;
176
182 public $sepa_category_purpose = 'CORE';
183
189 public $sepa_local_instrument = 'CORE';
190
197 public $proprio;
198
203 public $owner_name;
204
209 public $owner_address;
210
215 public $owner_zip;
216
221 public $owner_town;
225 public $owner_country_id;
229 public $owner_country_code;
230
237 public $domiciliation;
238
243 public $address;
247 public $state_id;
251 public $state_code;
255 public $state;
259 public $country_id;
260
266 public $type_lib = array();
267
272 public $account_number;
273
277 public $fk_accountancy_journal;
278
282 public $accountancy_journal;
283
288 public $currency_code;
289
296 public $account_currency_code;
297
302 public $min_allowed;
303
308 public $min_desired;
309
314 public $comment;
315
320 public $date_solde;
321
328 public $solde;
329
334 public $balance;
335
340 public $ics;
341
346 public $ics_transfer;
347
351 public $oldref;
352
353
378 // BEGIN MODULEBUILDER PROPERTIES
382 public $fields = array(
383 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 10),
384 'ref' => array('type' => 'varchar(12)', 'label' => 'Ref', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'showoncombobox' => 1, 'position' => 25),
385 'label' => array('type' => 'varchar(30)', 'label' => 'Label', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 30),
386 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 35, 'index' => 1),
387 'bank' => array('type' => 'varchar(60)', 'label' => 'Bank', 'enabled' => 1, 'visible' => -1, 'position' => 40),
388 'code_banque' => array('type' => 'varchar(128)', 'label' => 'Code banque', 'enabled' => 1, 'visible' => -1, 'position' => 45),
389 'code_guichet' => array('type' => 'varchar(6)', 'label' => 'Code guichet', 'enabled' => 1, 'visible' => -1, 'position' => 50),
390 'number' => array('type' => 'varchar(255)', 'label' => 'Number', 'enabled' => 1, 'visible' => -1, 'position' => 55),
391 'cle_rib' => array('type' => 'varchar(5)', 'label' => 'Cle rib', 'enabled' => 1, 'visible' => -1, 'position' => 60),
392 'bic' => array('type' => 'varchar(11)', 'label' => 'Bic', 'enabled' => 1, 'visible' => -1, 'position' => 65),
393 'iban_prefix' => array('type' => 'varchar(34)', 'label' => 'Iban prefix', 'enabled' => 1, 'visible' => -1, 'position' => 70),
394 'country_iban' => array('type' => 'varchar(2)', 'label' => 'Country iban', 'enabled' => 1, 'visible' => -1, 'position' => 75),
395 'cle_iban' => array('type' => 'varchar(2)', 'label' => 'Cle iban', 'enabled' => 1, 'visible' => -1, 'position' => 80),
396 'domiciliation' => array('type' => 'varchar(255)', 'label' => 'Domiciliation', 'enabled' => 1, 'visible' => -1, 'position' => 85),
397 'state_id' => array('type' => 'integer', 'label' => 'StateId', 'enabled' => 1, 'visible' => -1, 'position' => 90),
398 'fk_pays' => array('type' => 'integer', 'label' => 'Country', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 95),
399 'proprio' => array('type' => 'varchar(60)', 'label' => 'Proprio', 'enabled' => 1, 'visible' => -1, 'position' => 100),
400 'owner_address' => array('type' => 'varchar(255)', 'label' => 'Owner address', 'enabled' => 1, 'visible' => -1, 'position' => 105),
401 'owner_zip' => array('type' => 'varchar(25)', 'label' => 'Owner zip', 'enabled' => 1, 'visible' => -1, 'position' => 106),
402 'owner_town' => array('type' => 'varchar(50)', 'label' => 'Owner town', 'enabled' => 1, 'visible' => -1, 'position' => 107),
403 'owner_country_id' => array('type' => 'integer', 'label' => 'Owner country', 'enabled' => 1, 'visible' => -1, 'position' => 108),
404 'courant' => array('type' => 'smallint(6)', 'label' => 'Courant', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 110),
405 'clos' => array('type' => 'smallint(6)', 'label' => 'Clos', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 115),
406 'rappro' => array('type' => 'smallint(6)', 'label' => 'Rappro', 'enabled' => 1, 'visible' => -1, 'position' => 120),
407 'url' => array('type' => 'varchar(128)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 125),
408 'account_number' => array('type' => 'varchar(32)', 'label' => 'Account number', 'enabled' => 1, 'visible' => -1, 'position' => 130),
409 'fk_accountancy_journal' => array('type' => 'integer', 'label' => 'Accountancy journal ID', 'enabled' => 1, 'visible' => -1, 'position' => 132),
410 'accountancy_journal' => array('type' => 'varchar(20)', 'label' => 'Accountancy journal', 'enabled' => 1, 'visible' => -1, 'position' => 135),
411 'currency_code' => array('type' => 'varchar(3)', 'label' => 'Currency code', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 140),
412 'min_allowed' => array('type' => 'integer', 'label' => 'Min allowed', 'enabled' => 1, 'visible' => -1, 'position' => 145),
413 'min_desired' => array('type' => 'integer', 'label' => 'Min desired', 'enabled' => 1, 'visible' => -1, 'position' => 150),
414 'comment' => array('type' => 'text', 'label' => 'Comment', 'enabled' => 1, 'visible' => -1, 'position' => 155),
415 'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 156),
416 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 157),
417 'fk_user_author' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -1, 'position' => 160),
418 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 165),
419 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 170),
420 'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 175),
421 'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 180),
422 'extraparams' => array('type' => 'varchar(255)', 'label' => 'Extraparams', 'enabled' => 1, 'visible' => -1, 'position' => 185),
423 );
424 // END MODULEBUILDER PROPERTIES
425
429 const TYPE_CURRENT = 1;
433 const TYPE_CASH = 2;
437 const TYPE_SAVINGS = 0;
438
439
440 const STATUS_OPEN = 0;
441 const STATUS_CLOSED = 1;
442
447 const SEPA_CATEGORY_PURPOSES = array('CORE', 'CORT', 'CASH', 'INST', 'SUPP', 'TREA');
448
453 const SEPA_LOCAL_INSTRUMENTS = array('CORE', 'INST');
454
455
461 public function __construct(DoliDB $db)
462 {
463 global $langs;
464
465 $this->db = $db;
466
467 $this->ismultientitymanaged = 1;
468
469 $this->balance = 0;
470
471 $this->type_lib = array(
472 self::TYPE_SAVINGS => $langs->transnoentitiesnoconv("BankType0"),
473 self::TYPE_CURRENT => $langs->transnoentitiesnoconv("BankType1"),
474 self::TYPE_CASH => $langs->transnoentitiesnoconv("BankType2"),
475 );
476
477 $this->labelStatus = array(
478 self::STATUS_OPEN => $langs->transnoentitiesnoconv("StatusAccountOpened"),
479 self::STATUS_CLOSED => $langs->transnoentitiesnoconv("StatusAccountClosed")
480 );
481 }
482
489 public function getSepaCategoryPurpose()
490 {
491 $code = strtoupper(trim((string) $this->sepa_category_purpose));
492 return (in_array($code, self::SEPA_CATEGORY_PURPOSES) ? $code : 'CORE');
493 }
494
501 public function getSepaLocalInstrument()
502 {
503 $code = strtoupper(trim((string) $this->sepa_local_instrument));
504 return (in_array($code, self::SEPA_LOCAL_INSTRUMENTS) ? $code : 'CORE');
505 }
506
512 public function __toString()
513 {
514 $string = '';
515 foreach ($this->getFieldsToShow() as $val) {
516 if ($val == 'BankCode') {
517 $string .= $this->code_banque.' ';
518 } elseif ($val == 'BankAccountNumber') {
519 $string .= $this->number.' ';
520 } elseif ($val == 'DeskCode') {
521 $string .= $this->code_guichet.' ';
522 } elseif ($val == 'BankAccountNumberKey') {
523 $string .= $this->cle_rib.' ';
524 } elseif ($val == 'BIC') {
525 $string .= $this->bic.' ';
526 } elseif ($val == 'IBAN') {
527 $string .= $this->iban.' ';
528 }
529 }
530
531 return trim($string);
532 }
533
534
540 public function canBeConciliated()
541 {
542 if (empty($this->rappro)) {
543 return -1;
544 }
545 if ($this->type == Account::TYPE_CASH && !getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
546 return -2;
547 }
548 if ($this->status) {
549 return -3;
550 }
551 return 1;
552 }
553
554
555 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
566 public function add_url_line($line_id, $url_id, $url, $label, $type)
567 {
568 // phpcs:enable
569 // Avoid uk_bank_url collision when the same target (line_id, url_id, type) is linked twice
570 // e.g. two distinct credit transfers for the same employee dispatched on the same bank line.
571 $sqlcheck = "SELECT rowid FROM ".MAIN_DB_PREFIX."bank_url";
572 $sqlcheck .= " WHERE fk_bank = ".((int) $line_id);
573 $sqlcheck .= " AND url_id = ".((int) $url_id);
574 $sqlcheck .= " AND type = '".$this->db->escape($type)."'";
575 $resqlcheck = $this->db->query($sqlcheck);
576 if ($resqlcheck) {
577 $obj = $this->db->fetch_object($resqlcheck);
578 if ($obj) {
579 $this->db->free($resqlcheck);
580 return (int) $obj->rowid;
581 }
582 $this->db->free($resqlcheck);
583 }
584
585 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
586 $sql .= "fk_bank";
587 $sql .= ", url_id";
588 $sql .= ", url"; // deprecated
589 $sql .= ", label";
590 $sql .= ", type";
591 $sql .= ") VALUES (";
592 $sql .= ((int) $line_id);
593 $sql .= ", ".((int) $url_id);
594 $sql .= ", '".$this->db->escape($url)."'"; // deprecated
595 $sql .= ", '".$this->db->escape($label)."'";
596 $sql .= ", '".$this->db->escape($type)."'";
597 $sql .= ")";
598
599 dol_syslog(get_class($this)."::add_url_line", LOG_DEBUG);
600 if ($this->db->query($sql)) {
601 $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
602 return $rowid;
603 } else {
604 $this->error = $this->db->lasterror();
605 return -1;
606 }
607 }
608
609 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
619 public function get_url($fk_bank = 0, $url_id = 0, $type = '')
620 {
621 // phpcs:enable
622 $lines = array();
623
624 // Check parameters
625 if (!empty($fk_bank) && (!empty($url_id) || !empty($type))) {
626 $this->error = "ErrorBadParameter";
627 return -1;
628 }
629
630 $sql = "SELECT fk_bank, url_id, url, label, type";
631 $sql .= " FROM ".MAIN_DB_PREFIX."bank_url";
632 if ($fk_bank > 0) {
633 $sql .= " WHERE fk_bank = ".((int) $fk_bank);
634 } else {
635 $sql .= " WHERE url_id = ".((int) $url_id)." AND type = '".$this->db->escape($type)."'";
636 }
637 $sql .= " ORDER BY type, label";
638
639 dol_syslog(get_class($this)."::get_url", LOG_DEBUG);
640 $result = $this->db->query($sql);
641 if ($result) {
642 $i = 0;
643 $num = $this->db->num_rows($result);
644 while ($i < $num) {
645 $obj = $this->db->fetch_object($result);
646 // Old links (for compatibility)
647 $lines[$i][0] = $obj->url;
648 $lines[$i][1] = $obj->url_id;
649 $lines[$i][2] = $obj->label;
650 $lines[$i][3] = $obj->type;
651 // New links
652 $lines[$i]['url'] = $obj->url;
653 $lines[$i]['url_id'] = $obj->url_id;
654 $lines[$i]['label'] = $obj->label;
655 $lines[$i]['type'] = $obj->type;
656 $lines[$i]['fk_bank'] = $obj->fk_bank;
657 $i++;
658 }
659 } else {
660 dol_print_error($this->db);
661 }
662
663 return $lines;
664 }
665
685 public function addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur = '', $banque = '', $accountancycode = '', $datev = null, $num_releve = '', $amount_main_currency = null, $note_private = '')
686 {
687 global $langs;
688
689 // Deprecation warning
690 if (is_numeric($oper)) {
691 dol_syslog(__METHOD__.": using numeric operations is deprecated", LOG_WARNING);
692 }
693
694 if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
695 $this->id = $this->rowid;
696 }
697
698 // Clean parameters
699 $emetteur = trim($emetteur);
700 $banque = trim($banque);
701 $label = trim($label);
702
703 $now = dol_now();
704
705 if (is_numeric($oper)) { // Clean operation to have a code instead of a rowid
706 $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
707 $sql .= " WHERE id = ".((int) $oper);
708 $sql .= " AND entity IN (".getEntity('c_paiement').")";
709 $resql = $this->db->query($sql);
710 if ($resql) {
711 $obj = $this->db->fetch_object($resql);
712 $oper = $obj->code;
713 } else {
714 dol_print_error($this->db, 'Failed to get payment type code');
715 return -1;
716 }
717 }
718
719 // Check parameters
720 if (!$oper) {
721 $this->error = $langs->trans("OperNotDefined");
722 return -1;
723 }
724 if (!$this->id) {
725 $this->error = $langs->trans("ThisIdNotDefined");
726 return -2;
727 }
728 if ($this->type == Account::TYPE_CASH && $oper != 'LIQ') {
729 $this->error = "ErrorCashAccountAcceptsOnlyCashMoney";
730 return -3;
731 }
732
733 $this->db->begin();
734
735 if (is_null($datev) || empty($datev)) {
736 $datev = $date;
737 }
738
739 $accline = new AccountLine($this->db);
740 $accline->datec = $now;
741 $accline->dateo = $date;
742 $accline->datev = $datev;
743 $accline->label = $label;
744 $accline->amount = $amount;
745 $accline->amount_main_currency = $amount_main_currency;
746 $accline->fk_user_author = $user->id;
747 $accline->fk_account = $this->id;
748 $accline->fk_type = $oper;
749 $accline->numero_compte = $accountancycode;
750 $accline->num_releve = $num_releve;
751 $accline->note_private = $note_private;
752
753 if ($num_chq) {
754 $accline->num_chq = $num_chq;
755 }
756
757 if ($emetteur) {
758 $accline->emetteur = $emetteur;
759 }
760
761 if ($banque) {
762 $accline->bank_chq = $banque;
763 }
764
765 if ($accline->insert() > 0) {
766 if ($categorie > 0) {
767 $sql = "INSERT INTO ".MAIN_DB_PREFIX."category_bankline(";
768 $sql .= "lineid, fk_categ";
769 $sql .= ") VALUES (";
770 $sql .= ((int) $accline->id).", ".((int) $categorie);
771 $sql .= ")";
772
773 $result = $this->db->query($sql);
774 if (!$result) {
775 $this->error = $this->db->lasterror();
776 $this->db->rollback();
777
778 return -4;
779 }
780 }
781
782 $this->db->commit();
783
784 return $accline->id;
785 } else {
786 $this->setErrorsFromObject($accline);
787 $this->db->rollback();
788
789 return -5;
790 }
791 }
792
800 public function create($user, $notrigger = 0)
801 {
802 global $langs, $conf;
803
804 $error = 0;
805
806 // Clean parameters
807 if (!$this->min_allowed) {
808 $this->min_allowed = 0;
809 }
810 if (!$this->min_desired) {
811 $this->min_desired = 0;
812 }
813
814 // Check parameters
815 if (empty($this->country_id)) {
816 $langs->load('errors');
817 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
818 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
819 return -1;
820 }
821 if (empty($this->ref)) {
822 $langs->load('errors');
823 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
824 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
825 return -1;
826 }
827 if (empty($this->date_solde)) {
828 $langs->load('errors');
829 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateInitialBalance"));
830 dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
831 return -1;
832 }
833
834 // Load libraries to check BAN
835 $balance = $this->balance;
836 if (empty($balance) && !empty($this->solde)) {
837 dol_syslog(get_class($this)."::create solde is deprecated use balance", LOG_NOTICE);
838 $balance = $this->solde;
839 }
840 if (empty($balance)) {
841 $balance = 0;
842 }
843 if (empty($this->status && !empty($this->clos))) {
844 dol_syslog(get_class($this)."::create clos is deprecated use status", LOG_NOTICE);
845 $this->status = $this->clos;
846 }
847
848 if (empty($this->country_id) && !empty($this->country_code)) {
849 $country_id = getCountry($this->country_code, '3');
850 $this->country_id = is_int($country_id) ? $country_id : 0;
851 }
852
853 // Load the library to validate/check a BAN account
854 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
855
856 $now = dol_now();
857
858 $this->db->begin();
859
860 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
861 $sql .= "datec";
862 $sql .= ", ref";
863 $sql .= ", label";
864 $sql .= ", entity";
865 $sql .= ", account_number";
866 $sql .= ", fk_accountancy_journal";
867 $sql .= ", bank";
868 $sql .= ", code_banque";
869 $sql .= ", code_guichet";
870 $sql .= ", number";
871 $sql .= ", cle_rib";
872 $sql .= ", bic";
873 $sql .= ", iban_prefix";
874 $sql .= ", domiciliation";
875 $sql .= ", pti_in_ctti";
876 $sql .= ", sepa_category_purpose";
877 $sql .= ", sepa_local_instrument";
878 $sql .= ", proprio";
879 $sql .= ", owner_address";
880 $sql .= ", owner_zip";
881 $sql .= ", owner_town";
882 $sql .= ", owner_country_id";
883 $sql .= ", currency_code";
884 $sql .= ", rappro";
885 $sql .= ", min_allowed";
886 $sql .= ", min_desired";
887 $sql .= ", comment";
888 $sql .= ", state_id";
889 $sql .= ", fk_pays";
890 $sql .= ", ics";
891 $sql .= ", ics_transfer";
892 $sql .= ") VALUES (";
893 $sql .= "'".$this->db->idate($now)."'";
894 $sql .= ", '".$this->db->escape($this->ref)."'";
895 $sql .= ", '".$this->db->escape($this->label)."'";
896 $sql .= ", ".((int) $conf->entity);
897 $sql .= ", '".$this->db->escape($this->account_number)."'";
898 $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
899 $sql .= ", '".$this->db->escape($this->bank)."'";
900 $sql .= ", '".$this->db->escape($this->code_banque)."'";
901 $sql .= ", '".$this->db->escape($this->code_guichet)."'";
902 $sql .= ", '".$this->db->escape($this->number)."'";
903 $sql .= ", '".$this->db->escape($this->cle_rib)."'";
904 $sql .= ", '".$this->db->escape($this->bic)."'";
905 $sql .= ", '".$this->db->escape($this->iban)."'";
906 $sql .= ", '".$this->db->escape($this->address)."'";
907 $sql .= ", ".((int) $this->pti_in_ctti);
908 $sql .= ", '".$this->db->escape($this->getSepaCategoryPurpose())."'";
909 $sql .= ", '".$this->db->escape($this->getSepaLocalInstrument())."'";
910 $sql .= ", '".$this->db->escape($this->owner_name)."'";
911 $sql .= ", '".$this->db->escape($this->owner_address)."'";
912 $sql .= ", '".$this->db->escape($this->owner_zip)."'";
913 $sql .= ", '".$this->db->escape($this->owner_town)."'";
914 $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
915 $sql .= ", '".$this->db->escape($this->currency_code)."'";
916 $sql .= ", ".((int) $this->rappro);
917 $sql .= ", ".price2num($this->min_allowed, 'MT');
918 $sql .= ", ".price2num($this->min_desired, 'MT');
919 $sql .= ", '".$this->db->escape($this->comment)."'";
920 $sql .= ", ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
921 $sql .= ", ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
922 $sql .= ", '".$this->db->escape($this->ics)."'";
923 $sql .= ", '".$this->db->escape($this->ics_transfer)."'";
924 $sql .= ")";
925
926 dol_syslog(get_class($this)."::create", LOG_DEBUG);
927 $resql = $this->db->query($sql);
928 if ($resql) {
929 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
930
931 $result = $this->update($user, 1);
932 if ($result > 0) {
933 $accline = new AccountLine($this->db);
934 $accline->datec = $now;
935 $accline->label = '('.$langs->trans("InitialBankBalance").')';
936 $accline->amount = (float) price2num($balance);
937 $accline->fk_user_author = $user->id;
938 $accline->fk_account = $this->id;
939 $accline->datev = $this->date_solde;
940 $accline->dateo = $this->date_solde;
941 $accline->fk_type = 'SOLD';
942
943 if ($accline->insert() < 0) {
944 $error++;
945 $this->setErrorsFromObject($accline);
946 }
947
948 if (!$error) {
949 $result = $this->insertExtraFields();
950 if ($result < 0) {
951 $error++;
952 }
953 }
954
955 if (!$error && !$notrigger) {
956 // Call trigger
957 $result = $this->call_trigger('BANKACCOUNT_CREATE', $user);
958 if ($result < 0) {
959 $error++;
960 }
961 // End call triggers
962 }
963 } else {
964 $error++;
965 }
966 } else {
967 if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
968 $this->error = $langs->trans("ErrorBankLabelAlreadyExists");
969 $error++;
970 } else {
971 $this->error = $this->db->error()." sql=".$sql;
972 $error++;
973 }
974 }
975
976 if (!$error) {
977 $this->db->commit();
978 return $this->id;
979 } else {
980 $this->db->rollback();
981 return -1 * $error;
982 }
983 }
984
992 public function update($user, $notrigger = 0)
993 {
994 global $langs, $conf;
995
996 if (empty($this->country_id) && !empty($this->country_code)) {
997 $country_id = getCountry($this->country_code, '3');
998 $this->country_id = is_int($country_id) ? $country_id : 0;
999 }
1000
1001 $error = 0;
1002
1003 $this->db->begin();
1004
1005 // Check parameters
1006 if (empty($this->country_id)) {
1007 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Country"));
1008 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
1009 return -1;
1010 }
1011 if (empty($this->ref)) {
1012 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Ref"));
1013 dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR);
1014 return -1;
1015 }
1016 if (!$this->label) {
1017 $this->label = "???";
1018 }
1019
1020 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
1021 $sql .= " ref = '".$this->db->escape($this->ref)."'";
1022 $sql .= ",label = '".$this->db->escape($this->label)."'";
1023 $sql .= ",courant = ".((int) $this->type);
1024 $sql .= ",clos = ".((int) $this->status);
1025 $sql .= ",rappro = ".((int) $this->rappro);
1026 $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null");
1027 $sql .= ",account_number = '".$this->db->escape($this->account_number)."'";
1028 $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null");
1029 $sql .= ",bank = '".$this->db->escape($this->bank)."'";
1030 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1031 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1032 $sql .= ",number='".$this->db->escape($this->number)."'";
1033 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1034 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1035 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1036 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
1037 $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti);
1038 $sql .= ",sepa_category_purpose = '".$this->db->escape($this->getSepaCategoryPurpose())."'";
1039 $sql .= ",sepa_local_instrument = '".$this->db->escape($this->getSepaLocalInstrument())."'";
1040 $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'";
1041 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1042 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1043 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1044 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1045
1046 $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'";
1047
1048 $sql .= ",min_allowed = ".($this->min_allowed != '' ? price2num($this->min_allowed) : "null");
1049 $sql .= ",min_desired = ".($this->min_desired != '' ? price2num($this->min_desired) : "null");
1050 $sql .= ",comment = '".$this->db->escape($this->comment)."'";
1051
1052 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
1053 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
1054 $sql .= ",ics = '".$this->db->escape($this->ics)."'";
1055 $sql .= ",ics_transfer = '".$this->db->escape($this->ics_transfer)."'";
1056
1057 $sql .= " WHERE rowid = ".((int) $this->id);
1058
1059 dol_syslog(get_class($this)."::update", LOG_DEBUG);
1060 $result = $this->db->query($sql);
1061 if ($result) {
1062 // Actions on extra fields (by external module or standard code)
1063 if (!$error) {
1064 $result = $this->insertExtraFields();
1065 if ($result < 0) {
1066 $error++;
1067 }
1068 }
1069
1070 if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
1071 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
1072 $sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type = 'bank_account' and entity = ".((int) $conf->entity);
1073 $resql = $this->db->query($sql);
1074 if (!$resql) {
1075 $error++;
1076 $this->error = $this->db->lasterror();
1077 }
1078
1079 // We rename directory in order not to lose the attachments
1080 $oldref = dol_sanitizeFileName($this->oldref);
1081 $newref = dol_sanitizeFileName($this->ref);
1082 $dirsource = $conf->bank->dir_output.'/'.$oldref;
1083 $dirdest = $conf->bank->dir_output.'/'.$newref;
1084 if (file_exists($dirsource)) {
1085 dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
1086 if (@rename($dirsource, $dirdest)) {
1087 dol_syslog("Rename ok", LOG_DEBUG);
1088 }
1089 }
1090 }
1091
1092 if (!$error && !$notrigger) {
1093 // Call trigger
1094 $result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
1095 if ($result < 0) {
1096 $error++;
1097 }
1098 // End call triggers
1099 }
1100 } else {
1101 $error++;
1102 $this->error = $this->db->lasterror();
1103 dol_print_error($this->db);
1104 }
1105
1106 if (!$error) {
1107 $this->db->commit();
1108 return $this->id;
1109 } else {
1110 $this->db->rollback();
1111 return -1 * $error;
1112 }
1113 }
1114
1115
1116 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1123 public function update_bban($user = null)
1124 {
1125 // phpcs:enable
1126 global $conf, $langs;
1127
1128 // Load library to get BAN control function
1129 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1130
1131 dol_syslog(get_class($this)."::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
1132
1133 // Check parameters
1134 if (!$this->ref) {
1135 $this->error = $langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->trans("Ref"));
1136 return -2;
1137 }
1138
1139 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET";
1140 $sql .= " bank = '".$this->db->escape($this->bank)."'";
1141 $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'";
1142 $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'";
1143 $sql .= ",number='".$this->db->escape($this->number)."'";
1144 $sql .= ",cle_rib='".$this->db->escape($this->cle_rib)."'";
1145 $sql .= ",bic='".$this->db->escape($this->bic)."'";
1146 $sql .= ",iban_prefix = '".$this->db->escape($this->iban)."'";
1147 $sql .= ",domiciliation='".$this->db->escape($this->address)."'";
1148 $sql .= ",proprio = '".$this->db->escape($this->owner_name)."'";
1149 $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'";
1150 $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'";
1151 $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'";
1152 $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null");
1153 $sql .= ",state_id = ".($this->state_id > 0 ? ((int) $this->state_id) : "null");
1154 $sql .= ",fk_pays = ".($this->country_id > 0 ? ((int) $this->country_id) : "null");
1155 $sql .= " WHERE rowid = ".((int) $this->id);
1156 $sql .= " AND entity = ".((int) $conf->entity);
1157
1158 dol_syslog(get_class($this)."::update_bban", LOG_DEBUG);
1159
1160 $result = $this->db->query($sql);
1161 if ($result) {
1162 return 1;
1163 } else {
1164 $this->error = $this->db->lasterror();
1165 dol_print_error($this->db);
1166 return -1;
1167 }
1168 }
1169
1170
1178 public function fetch($id, $ref = '')
1179 {
1180 if (empty($id) && empty($ref)) {
1181 $this->error = "ErrorBadParameters";
1182 return -1;
1183 }
1184
1185 $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant as type, ba.clos as status, ba.rappro, ba.url,";
1186 $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
1187 $sql .= " ba.domiciliation as address, ba.pti_in_ctti, ba.sepa_category_purpose, ba.sepa_local_instrument, ba.proprio as owner_name, ba.owner_address, ba.owner_zip, ba.owner_town, ba.owner_country_id, ba.state_id, ba.fk_pays as country_id,";
1188 $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,";
1189 $sql .= " ba.min_allowed, ba.min_desired, ba.comment,";
1190 $sql .= " ba.datec as date_creation, ba.tms as date_modification, ba.ics, ba.ics_transfer,";
1191 $sql .= ' c.code as country_code, c.label as country,';
1192 $sql .= ' d.code_departement as state_code, d.nom as state,';
1193 $sql .= ' aj.code as accountancy_journal';
1194 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1195 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid';
1196 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid';
1197 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'accounting_journal as aj ON aj.rowid=ba.fk_accountancy_journal';
1198 $sql .= " WHERE ba.entity IN (".getEntity($this->element).")";
1199 if ($id) {
1200 $sql .= " AND ba.rowid = ".((int) $id);
1201 }
1202 if ($ref) {
1203 $sql .= " AND ba.ref = '".$this->db->escape($ref)."'";
1204 }
1205
1206 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
1207 $result = $this->db->query($sql);
1208 if ($result) {
1209 if ($this->db->num_rows($result)) {
1210 $obj = $this->db->fetch_object($result);
1211
1212 $this->id = $obj->rowid;
1213 $this->rowid = $obj->rowid;
1214 $this->ref = $obj->ref;
1215 $this->label = $obj->label;
1216 $this->type = $obj->type;
1217 $this->courant = $obj->type;
1218 $this->bank = $obj->bank;
1219 $this->clos = $obj->status;
1220 $this->status = $obj->status;
1221 $this->rappro = $obj->rappro;
1222 $this->url = $obj->url;
1223
1224 $this->code_banque = $obj->code_banque;
1225 $this->code_guichet = $obj->code_guichet;
1226 $this->number = $obj->number;
1227 $this->cle_rib = $obj->cle_rib;
1228 $this->bic = $obj->bic;
1229 $this->iban = $obj->iban;
1230 $this->address = $obj->address;
1231
1232 $this->owner_name = $obj->owner_name;
1233 $this->proprio = $this->owner_name;
1234 $this->owner_address = $obj->owner_address;
1235 $this->owner_zip = $obj->owner_zip;
1236 $this->owner_town = $obj->owner_town;
1237 $this->owner_country_id = $obj->owner_country_id;
1238
1239 $this->pti_in_ctti = $obj->pti_in_ctti;
1240 $this->sepa_category_purpose = (in_array($obj->sepa_category_purpose, self::SEPA_CATEGORY_PURPOSES) ? $obj->sepa_category_purpose : 'CORE');
1241 $this->sepa_local_instrument = (in_array($obj->sepa_local_instrument, self::SEPA_LOCAL_INSTRUMENTS) ? $obj->sepa_local_instrument : 'CORE');
1242
1243 $this->state_id = $obj->state_id;
1244 $this->state_code = $obj->state_code;
1245 $this->state = $obj->state;
1246
1247 $this->country_id = $obj->country_id;
1248 $this->country_code = $obj->country_code;
1249 $this->country = $obj->country;
1250
1251 $this->account_number = $obj->account_number;
1252 $this->fk_accountancy_journal = $obj->fk_accountancy_journal;
1253 $this->accountancy_journal = $obj->accountancy_journal;
1254
1255 $this->currency_code = $obj->currency_code;
1256 $this->account_currency_code = $obj->currency_code;
1257 $this->min_allowed = $obj->min_allowed;
1258 $this->min_desired = $obj->min_desired;
1259 $this->comment = $obj->comment;
1260
1261 $this->date_creation = $this->db->jdate($obj->date_creation);
1262 $this->date_modification = $this->db->jdate($obj->date_modification);
1263
1264 $this->ics = $obj->ics;
1265 $this->ics_transfer = $obj->ics_transfer;
1266
1267 // Retrieve all extrafield
1268 // fetch optionals attributes and labels
1269 $this->fetch_optionals();
1270
1271 return 1;
1272 } else {
1273 return 0;
1274 }
1275 } else {
1276 $this->error = $this->db->lasterror();
1277 $this->errors[] = $this->error;
1278 return -1;
1279 }
1280 }
1281
1292 public function setCategories($categories)
1293 {
1294 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1295 return parent::setCategoriesCommon($categories, Categorie::TYPE_ACCOUNT);
1296 }
1297
1305 public function delete($user, $notrigger = 0)
1306 {
1307 $error = 0;
1308
1309 $this->db->begin();
1310
1311 // @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
1312
1313 // Delete link between tag and bank account
1314 if (!$error) {
1315 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
1316 $sql .= " WHERE fk_account = ".((int) $this->id);
1317
1318 $resql = $this->db->query($sql);
1319 if (!$resql) {
1320 $error++;
1321 $this->error = "Error ".$this->db->lasterror();
1322 }
1323 }
1324
1325 if (!$error) {
1326 $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element;
1327 $sql .= " WHERE rowid = ".((int) $this->id);
1328
1329 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1330 $result = $this->db->query($sql);
1331 if ($result) {
1332 // Remove extrafields
1333 if (!$error) {
1334 $result = $this->deleteExtraFields();
1335 if ($result < 0) {
1336 $error++;
1337 dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
1338 }
1339 }
1340 } else {
1341 $error++;
1342 $this->error = "Error ".$this->db->lasterror();
1343 }
1344 }
1345
1346 if (!$error && !$notrigger) {
1347 // Call trigger
1348 $result = $this->call_trigger('BANKACCOUNT_DELETE', $user);
1349 if ($result < 0) {
1350 $error++;
1351 }
1352 // End call triggers
1353 }
1354
1355 if (!$error) {
1356 $this->db->commit();
1357 return 1;
1358 } else {
1359 $this->db->rollback();
1360 return -1;
1361 }
1362 }
1363
1364
1371 public function getLibStatut($mode = 0)
1372 {
1373 return $this->LibStatut($this->status, $mode);
1374 }
1375
1376 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1384 public function LibStatut($status, $mode = 0)
1385 {
1386 // phpcs:enable
1387 global $langs;
1388 $langs->load('banks');
1389
1390 if ($status == self::STATUS_OPEN) {
1391 $label = $langs->transnoentitiesnoconv("StatusAccountOpened");
1392 $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened");
1393 $statusType = 'status4';
1394 } else {
1395 $label = $langs->transnoentitiesnoconv("StatusAccountClosed");
1396 $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed");
1397 $statusType = 'status5';
1398 }
1399
1400 return dolGetStatus($label, $labelshort, '', $statusType, $mode);
1401 }
1402
1403
1404 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1410 public function can_be_deleted()
1411 {
1412 // phpcs:enable
1413 $can_be_deleted = false;
1414
1415 $sql = "SELECT COUNT(rowid) as nb";
1416 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1417 $sql .= " WHERE fk_account = ".((int) $this->id);
1418
1419 $resql = $this->db->query($sql);
1420 if ($resql) {
1421 $obj = $this->db->fetch_object($resql);
1422 if ($obj->nb <= 1) {
1423 $can_be_deleted = true; // Juste le solde
1424 }
1425 } else {
1426 dol_print_error($this->db);
1427 }
1428 return $can_be_deleted;
1429 }
1430
1431
1437 public function error()
1438 {
1439 return $this->error;
1440 }
1441
1450 public function solde($option = 0, $date_end = '', $field = 'dateo')
1451 {
1452 $solde = 0;
1453
1454 $sql = "SELECT sum(amount) as amount";
1455 $sql .= " FROM ".MAIN_DB_PREFIX."bank";
1456 $sql .= " WHERE fk_account = ".((int) $this->id);
1457 if ($option == 1) {
1458 $sql .= " AND ".$this->db->sanitize($field)." <= '".(!empty($date_end) ? $this->db->idate($date_end) : $this->db->idate(dol_now()))."'";
1459 }
1460
1461 $resql = $this->db->query($sql);
1462 if ($resql) {
1463 if ($this->db->num_rows($resql)) {
1464 $obj = $this->db->fetch_object($resql);
1465 $solde = $obj->amount;
1466 }
1467 $this->db->free($resql);
1468 } else {
1469 $this->errors[] = $this->db->lasterror;
1470 return -1;
1471 }
1472
1473 return (float) price2num($solde, 'MU');
1474 }
1475
1476 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1484 public function load_board(User $user, $filteraccountid = 0)
1485 {
1486 // phpcs:enable
1487 global $conf, $langs;
1488
1489 if ($user->socid) {
1490 return -1; // Protection to prevent calls by external users
1491 }
1492
1493 $now = dol_now();
1494
1495 // The count and the number of late transactions are computed by the database instead of reading every transaction to
1496 // conciliate (there can be a lot of them). A transaction is late when its value date is before now minus the warning
1497 // delay (a transaction without value date was counted as late, this is kept).
1498 $sql = "SELECT COUNT(b.rowid) as nb,";
1499 $sql .= " SUM(CASE WHEN b.datev IS NULL OR b.datev < '".$this->db->idate($now - $conf->bank->rappro->warning_delay)."' THEN 1 ELSE 0 END) as nblate";
1500 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1501 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1502 $sql .= " WHERE b.rappro=0";
1503 $sql .= " AND b.fk_account = ba.rowid";
1504 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1505 $sql .= " AND (ba.rappro = 1 AND ba.courant != " . Account::TYPE_CASH . ")"; // Compte rapprochable
1506 $sql .= " AND clos = 0";
1507 if ($filteraccountid) {
1508 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1509 }
1510 $resql = $this->db->query($sql);
1511 if ($resql) {
1512 $langs->load("banks");
1513
1514 require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php';
1515
1516 $response = new WorkboardResponse();
1517 $response->warning_delay = $conf->bank->rappro->warning_delay / 60 / 60 / 24;
1518 $response->label = $langs->trans("TransactionsToConciliate");
1519 $response->labelShort = $langs->trans("TransactionsToConciliateShort");
1520 $response->url = DOL_URL_ROOT.'/compta/bank/list.php?leftmenu=bank&amp;mainmenu=bank';
1521 $response->img = img_object('', "payment");
1522
1523 $obj = $this->db->fetch_object($resql);
1524 if ($obj) {
1525 $response->nbtodo = (int) $obj->nb;
1526 $response->nbtodolate = (int) $obj->nblate;
1527 }
1528 return $response;
1529 } else {
1530 dol_print_error($this->db);
1531 $this->error = $this->db->error();
1532 return -1;
1533 }
1534 }
1535
1542 public function loadStateBoard($filteraccountid = 0)
1543 {
1544 global $user;
1545
1546 if ($user->socid) {
1547 return -1; // Protection to prevent calls by external users
1548 }
1549
1550 $sql = "SELECT count(b.rowid) as nb";
1551 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
1552 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
1553 $sql .= " WHERE b.fk_account = ba.rowid";
1554 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1555 $sql .= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
1556 $sql .= " AND clos = 0";
1557 if ($filteraccountid) {
1558 $sql .= " AND ba.rowid = ".((int) $filteraccountid);
1559 }
1560
1561 $resql = $this->db->query($sql);
1562 if ($resql) {
1563 while ($obj = $this->db->fetch_object($resql)) {
1564 $this->nb["banklines"] = $obj->nb;
1565 }
1566 $this->db->free($resql);
1567 return 1;
1568 } else {
1569 dol_print_error($this->db);
1570 $this->error = $this->db->error();
1571 return -1;
1572 }
1573 }
1574
1575
1581 public function countAccountToReconcile()
1582 {
1583 global $user;
1584
1585 //Protection against external users
1586 if ($user->socid) {
1587 return 0;
1588 }
1589
1590 $nb = 0;
1591
1592 $sql = "SELECT COUNT(ba.rowid) as nb";
1593 $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
1594 $sql .= " WHERE ba.rappro > 0 and ba.clos = 0";
1595 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
1596 if (!getDolGlobalString('BANK_CAN_RECONCILIATE_CASHACCOUNT')) {
1597 $sql .= " AND ba.courant != " . Account::TYPE_CASH;
1598 }
1599
1600 $resql = $this->db->query($sql);
1601 if ($resql) {
1602 $obj = $this->db->fetch_object($resql);
1603 $nb = (int) $obj->nb;
1604 } else {
1605 dol_print_error($this->db);
1606 }
1607
1608 return $nb;
1609 }
1610
1619 public function getTooltipContentArray($params)
1620 {
1621 global $langs;
1622 $langs->loadLangs(['banks', 'compta']);
1623 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1624
1625 $datas = array();
1626
1627 $nofetch = !empty($params['nofetch']);
1628 $pictos = img_picto('', $this->picto).' <u class="paddingrightnow">'.$langs->trans("BankAccount").'</u>';
1629 if (isset($this->status)) {
1630 $pictos .= ' '.$this->getLibStatut(5);
1631 }
1632 $datas['picto'] = $pictos;
1633 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1634 $datas['label'] = '<br><b>'.$langs->trans('Label').':</b> '.$this->label;
1635 $datas['accountnumber'] = '<br><br><b>'.$langs->trans('AccountNumber').':</b> '.$this->number;
1636 $datas['iban'] = '<br><b>'.$langs->trans('IBAN').':</b> '.getIbanHumanReadable($this);
1637 $datas['bic'] = '<br><b>'.$langs->trans('BIC').':</b> '.$this->bic;
1638 $datas['accountcurrency'] = '<br><br><b>'.$langs->trans("AccountCurrency").':</b> '.$this->currency_code;
1639
1640 if (isModEnabled('accounting')) {
1641 include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
1642 $langs->load("accountancy");
1643 $datas['accountaccounting'] = '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number);
1644 $datas['accountancyjournal'] = '<br><b>'.$langs->trans('AccountancyJournal').':</b> '.$this->accountancy_journal;
1645 }
1646 // show categories for this record only in ajax to not overload lists
1647 if (isModEnabled('category') && !$nofetch) {
1648 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1649 $form = new Form($this->db);
1650 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACCOUNT, 1);
1651 }
1652
1653 return $datas;
1654 }
1655
1667 public function getNomUrl($withpicto = 0, $mode = '', $option = '', $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1668 {
1669 global $conf, $langs;
1670
1671 if (!empty($conf->dol_no_mouse_hover)) {
1672 $notooltip = 1; // Force disable tooltips
1673 }
1674
1675 include_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1676
1677 $result = '';
1678 $classfortooltip = 'classfortooltip';
1679 $dataparams = '';
1680 $params = [
1681 'id' => $this->id,
1682 'objecttype' => $this->element,
1683 'option' => $option,
1684 'nofetch' => 1,
1685 ];
1686 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1687 $classfortooltip = 'classforajaxtooltip';
1688 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1689 $label = '';
1690 } else {
1691 $label = implode($this->getTooltipContentArray($params));
1692 }
1693
1694 $baseurl = DOL_URL_ROOT.'/compta/bank/card.php';
1695 $query = ['id' => $this->id];
1696 if ($mode == 'transactions') {
1697 $baseurl = DOL_URL_ROOT.'/compta/bank/bankentries_list.php';
1698 } elseif ($mode == 'receipts') {
1699 $baseurl = DOL_URL_ROOT.'/compta/bank/releve.php';
1700 $query = ['account' => $this->id];
1701 }
1702
1703 if ($option != 'nolink') {
1704 // Add param to save lastsearch_values or not
1705 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1706 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1707 $add_save_lastsearch_values = 1;
1708 }
1709 if ($add_save_lastsearch_values) {
1710 $query = array_merge($query, ['save_lastsearch_values' => 1]);
1711 }
1712 }
1713 $url = dolBuildUrl($baseurl, $query);
1714
1715 $linkclose = '';
1716 if (empty($notooltip)) {
1717 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1718 $label = $langs->trans("BankAccount");
1719 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1720 }
1721 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1722 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1723 } else {
1724 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1725 }
1726
1727 if ($option == 'nolink' || empty($url)) {
1728 $linkstart = '<span';
1729 } else {
1730 $linkstart = '<a href="'.$url.'"';
1731 }
1732 $linkstart .= $linkclose.'>';
1733 if ($option == 'nolink' || empty($url)) {
1734 $linkend = '</span>';
1735 } else {
1736 $linkend = '</a>';
1737 }
1738
1739 $result .= $linkstart;
1740
1741 if ($withpicto) {
1742 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1743 }
1744 if ($withpicto != 2) {
1745 $result .= $this->ref.($option == 'reflabel' && $this->label ? ' - '.$this->label : '');
1746 }
1747 $result .= $linkend;
1748
1749 global $action, $hookmanager;
1750 $hookmanager->initHooks(array($this->element . 'dao'));
1751 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1752 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1753 if ($reshook > 0) {
1754 $result = $hookmanager->resPrint;
1755 } else {
1756 $result .= $hookmanager->resPrint;
1757 }
1758
1759 return $result;
1760 }
1761
1762
1763 // Method after here are common to Account and CompanyBankAccount
1764
1765
1771 public function verif()
1772 {
1773 require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
1774
1775 $error = 0;
1776
1777 // Call functions to check BAN
1778 if (!checkIbanForAccount($this)) {
1779 $error++;
1780 $this->error = 'IBANNotValid';
1781 }
1782 // Call function to check Swift/BIC.
1783 // A non valid BIC/Swift is a problem if: it is not empty or always a problem if WITHDRAWAL_WITHOUT_BIC is not set).
1784 if (!checkSwiftForAccount($this) && (!empty($this->bic) || !getDolGlobalInt('WITHDRAWAL_WITHOUT_BIC'))) {
1785 $error++;
1786 $this->error = 'SwiftNotValid';
1787 }
1788
1789 if (! $error) {
1790 return 1;
1791 } else {
1792 return 0;
1793 }
1794 }
1795
1801 public function getCountryCode()
1802 {
1803 global $mysoc;
1804
1805 // We return country code of bank account
1806 if (!empty($this->country_code)) {
1807 return $this->country_code;
1808 }
1809
1810 // For backward compatibility, we try to guess country from other information
1811 if (!empty($this->iban)) {
1812 // If IBAN defined, we can know country of account from it
1813 $reg = array();
1814 if (preg_match("/^([a-zA-Z][a-zA-Z])/i", $this->iban, $reg)) {
1815 return $reg[1];
1816 }
1817 }
1818
1819 // If this class is linked to a third party
1820 if (!empty($this->socid)) {
1821 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
1822 $company = new Societe($this->db);
1823 $result = $company->fetch($this->socid);
1824 if (!empty($company->country_code)) {
1825 return $company->country_code;
1826 }
1827 }
1828
1829 // We return country code of managed company
1830 if (!empty($mysoc->country_code)) {
1831 return $mysoc->country_code;
1832 }
1833
1834 return '';
1835 }
1836
1844 public function getBannerAddress($htmlkey, $object)
1845 {
1846 global $conf, $langs;
1847
1848 $out = '';
1849
1850 $outdone = 0;
1851 $coords = $this->getFullAddress(1, ', ', getDolGlobalInt('MAIN_SHOW_REGION_IN_STATE_SELECT'));
1852 if ($coords) {
1853 if (!empty($conf->use_javascript_ajax)) {
1854 // hideonsmatphone because copyToClipboard call jquery dialog that does not work with jmobile
1855 $out .= '<a href="#" class="hideonsmartphone" onclick="return copyToClipboard(\''.dol_escape_js($coords).'\',\''.dol_escape_js($langs->trans("HelpCopyToClipboard")).'\');">';
1856 $out .= img_picto($langs->trans("Address"), 'map-marker-alt');
1857 $out .= '</a> ';
1858 }
1859 $address = dol_print_address($coords, 'address_'.$htmlkey.'_'.$this->id, $this->element, $this->id, 1, ', ');
1860 if ($address) {
1861 $out .= $address;
1862 $outdone++;
1863 }
1864 $outdone++;
1865 }
1866
1867 return $out;
1868 }
1869
1870
1879 public function useDetailedBBAN()
1880 {
1881 $country_code = $this->getCountryCode();
1882
1883 if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) {
1884 return 1; // France, Spain, Gabon, ... - Not valid for CH
1885 }
1886 if (in_array($country_code, array('AD', 'AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) {
1887 return 2; // Australia, England...
1888 }
1889 return 0;
1890 }
1891
1897 public function needIBAN()
1898 {
1899 global $conf;
1900
1901 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1902 return 0;
1903 }
1904
1905 $country_code = $this->getCountryCode();
1906
1907 $country_code_in_EEC = array(
1908 'AT', // Austria
1909 'BE', // Belgium
1910 'BG', // Bulgaria
1911 'CY', // Cyprus
1912 'CZ', // Czech republic
1913 'DE', // Germany
1914 'DK', // Danemark
1915 'EE', // Estonia
1916 'ES', // Spain
1917 'FI', // Finland
1918 'FR', // France
1919 'GB', // United Kingdom
1920 'GR', // Greece
1921 'HR', // Croatia
1922 'NL', // Holland
1923 'HU', // Hungary
1924 'IE', // Ireland
1925 'IM', // Isle of Man - Included in UK
1926 'IT', // Italy
1927 'LT', // Lithuania
1928 'LU', // Luxembourg
1929 'LV', // Latvia
1930 'MC', // Monaco - Included in France
1931 'MT', // Malta
1932 //'NO', // Norway
1933 'PL', // Poland
1934 'PT', // Portugal
1935 'RO', // Romania
1936 'SE', // Sweden
1937 'SK', // Slovakia
1938 'SI', // Slovenia
1939 'UK', // United Kingdom
1940 //'CH', // Switzerland - No. Swizerland in not in EEC
1941 );
1942
1943 if (in_array($country_code, $country_code_in_EEC)) {
1944 return 1; // France, Spain, ...
1945 }
1946 return 0;
1947 }
1948
1954 public function needBIC()
1955 {
1956 if (getDolGlobalString('MAIN_IBAN_IS_NEVER_MANDATORY')) {
1957 return 0;
1958 }
1959
1960 $country_code = $this->getCountryCode();
1961
1962 $country_code_in_EEC = array(
1963 'AD', // Andorra
1964 'BH', // Bahrein
1965 'DK', // Denmark
1966 'FR', // France
1967 'GH', // Ghana
1968 'HU', // Hungary
1969 'JP', // Japan
1970 'LV', // Latvia
1971 'SE', // Sweden
1972 );
1973
1974 if (in_array($country_code, $country_code_in_EEC)) {
1975 return 1; // Andorra, Bahrein, ...
1976 }
1977 return 0;
1978 }
1979
1986 public function info($id)
1987 {
1988 }
1989
2004 public function getFieldsToShow($includeibanbic = 0)
2005 {
2006 //Get the required properties depending on the country
2007 $detailedBBAN = $this->useDetailedBBAN();
2008
2009 if ($detailedBBAN == 0) {
2010 $fieldarray = array(
2011 'BankAccountNumber'
2012 );
2013 } elseif ($detailedBBAN == 2) {
2014 $fieldarray = array(
2015 'BankCode',
2016 'BankAccountNumber'
2017 );
2018 } else {
2019 $fieldarray = self::getAccountNumberOrder();
2020 }
2021
2022 //if ($this->needIBAN()) { // return always IBAN and BIC (this was old behaviour)
2023 if ($includeibanbic) {
2024 $fieldarray[] = 'IBAN';
2025 $fieldarray[] = 'BIC';
2026 }
2027 //}
2028
2029 //Get the order the properties are shown
2030 return $fieldarray;
2031 }
2032
2043 public static function getAccountNumberOrder()
2044 {
2045 global $conf;
2046
2047 $fieldlists = array(
2048 'BankCode',
2049 'DeskCode',
2050 'BankAccountNumber',
2051 'BankAccountNumberKey'
2052 );
2053
2054 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION')) {
2055 if (is_numeric(getDolGlobalString('BANK_SHOW_ORDER_OPTION'))) {
2056 if (getDolGlobalString('BANK_SHOW_ORDER_OPTION') == '1') {
2057 $fieldlists = array(
2058 'BankCode',
2059 'DeskCode',
2060 'BankAccountNumberKey',
2061 'BankAccountNumber'
2062 );
2063 }
2064 } else {
2065 //Replace the old AccountNumber key with the new BankAccountNumber key
2066 $fieldlists = explode(
2067 ' ',
2068 preg_replace('/ ?[^Bank]AccountNumber ?/', 'BankAccountNumber', $conf->global->BANK_SHOW_ORDER_OPTION)
2069 );
2070 }
2071 }
2072
2073 return $fieldlists;
2074 }
2075
2076
2084 public function initAsSpecimen()
2085 {
2086 // Example of IBAN FR7630001007941234567890185
2087 $this->specimen = 1;
2088 $this->ref = 'MBA';
2089 $this->label = 'My Big Company Bank account';
2090 $this->clos = Account::STATUS_OPEN;
2091 $this->type = Account::TYPE_CURRENT;
2092 $this->status = Account::STATUS_OPEN;
2093 $this->code_banque = '30001';
2094 $this->code_guichet = '00794';
2095 $this->number = '12345678901';
2096 $this->cle_rib = '85';
2097 $this->bic = 'AA12';
2098 $this->iban = 'FR7630001007941234567890185';
2099
2100 $this->bank = 'MyBank';
2101 $this->address = 'Rue de Paris';
2102 $this->owner_name = 'Owner';
2103 $this->owner_address = 'Owner address';
2104 $this->owner_zip = 'Owner zip';
2105 $this->owner_town = 'Owner town';
2106 $this->owner_country_id = 1;
2107 $this->country_id = 1;
2108
2109 return 1;
2110 }
2111
2120 public static function replaceThirdparty($dbs, $origin_id, $dest_id)
2121 {
2122 $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type = 'company'";
2123
2124 if ($dbs->query($sql)) {
2125 return true;
2126 } else {
2127 //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.
2128 //$this->errors = $dbs->lasterror();
2129 return false;
2130 }
2131 }
2132
2140 public function getKanbanView($option = '', $arraydata = null)
2141 {
2142 global $langs;
2143
2144 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2145
2146 $return = '<div class="box-flex-item box-flex-grow-zero">';
2147 $return .= '<div class="info-box info-box-sm">';
2148 $return .= '<span class="info-box-icon bg-infobox-action">';
2149 $return .= img_picto('', $this->picto);
2150 $return .= '</span>';
2151 $return .= '<div class="info-box-content">';
2152 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
2153 if ($selected >= 0) {
2154 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2155 }
2156 if (property_exists($this, 'type_lib')) {
2157 $return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
2158 }
2159 if (method_exists($this, 'solde')) {
2160 $return .= '<br><a href="'.DOL_URL_ROOT.'/compta/bank/bankentries_list.php?id='.$this->id.'">';
2161 $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>';
2162 }
2163 if (method_exists($this, 'getLibStatut')) {
2164 $return .= '<br><div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2165 }
2166 $return .= '</div>';
2167 $return .= '</div>';
2168 $return .= '</div>';
2169 return $return;
2170 }
2171}
2172
2173
2174require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
2175
2179class AccountLine extends CommonObjectLine
2180{
2184 public $db;
2185
2189 public $element = 'bank';
2190
2194 public $table_element = 'bank';
2195
2199 public $picto = 'accountline';
2200
2204 public $id;
2205
2209 public $ref;
2210
2216 public $datec;
2217
2223 public $dateo;
2224
2230 public $datev;
2231
2235 public $amount;
2236
2240 public $amount_main_currency;
2241
2245 public $fk_user_author;
2246
2250 public $fk_user_rappro;
2251
2255 public $fk_type;
2256
2260 public $fk_bordereau;
2261
2265 public $fk_account;
2266
2270 public $bank_account_ref;
2271
2275 public $bank_account_label;
2276
2280 public $numero_compte;
2281
2285 public $emetteur;
2286
2290 public $rappro;
2291
2295 public $num_releve;
2296
2300 public $num_chq;
2301
2305 public $bank_chq;
2306
2310 public $label;
2311
2315 public $note;
2316
2322 public $user_rappro;
2323
2324
2330 public function __construct(DoliDB $db)
2331 {
2332 $this->db = $db;
2333 }
2334
2343 public function fetch($rowid, $ref = '', $num = '')
2344 {
2345 // Check parameters
2346 if (empty($rowid) && empty($ref) && empty($num)) {
2347 return -1;
2348 }
2349
2350 $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
2351 $sql .= " b.fk_user_author, b.fk_user_rappro,";
2352 $sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
2353 $sql .= " b.fk_bordereau, b.banque, b.emetteur,";
2354 $sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
2355 $sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
2356 $sql .= " ".MAIN_DB_PREFIX."bank_account as ba";
2357 $sql .= " WHERE b.fk_account = ba.rowid";
2358 $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
2359 if ($num) {
2360 $sql .= " AND b.num_chq = '".$this->db->escape($num)."'";
2361 } elseif ($ref) {
2362 $sql .= " AND b.rowid = '".$this->db->escape($ref)."'";
2363 } else {
2364 $sql .= " AND b.rowid = ".((int) $rowid);
2365 }
2366
2367 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
2368 $result = $this->db->query($sql);
2369 if ($result) {
2370 $ret = 0;
2371
2372 $obj = $this->db->fetch_object($result);
2373 if ($obj) {
2374 $this->id = $obj->rowid;
2375 $this->rowid = $obj->rowid;
2376 $this->ref = $obj->rowid;
2377
2378 $this->datec = $this->db->jdate($obj->datec);
2379 $this->datev = $this->db->jdate($obj->datev);
2380 $this->dateo = $this->db->jdate($obj->dateo);
2381 $this->amount = $obj->amount;
2382 $this->label = $obj->label;
2383 $this->note = $obj->note;
2384
2385 $this->fk_user_author = $obj->fk_user_author;
2386 $this->fk_user_rappro = $obj->fk_user_rappro;
2387
2388 $this->fk_type = $obj->fk_type; // Type of transaction
2389 $this->rappro = (int) $obj->rappro;
2390 $this->num_releve = $obj->num_releve;
2391
2392 $this->num_chq = $obj->num_chq;
2393 $this->bank_chq = $obj->banque;
2394 $this->fk_bordereau = $obj->fk_bordereau;
2395
2396 $this->fk_account = $obj->fk_account;
2397 $this->bank_account_ref = $obj->bank_account_ref;
2398 $this->bank_account_label = $obj->bank_account_label;
2399
2400 // Retrieve all extrafield
2401 // fetch optionals attributes and labels
2402 $this->fetch_optionals();
2403
2404 $ret = 1;
2405 }
2406 $this->db->free($result);
2407 return $ret;
2408 } else {
2409 return -1;
2410 }
2411 }
2412
2418 public function insert()
2419 {
2420 $error = 0;
2421
2422 $this->db->begin();
2423
2424 $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
2425 $sql .= "datec";
2426 $sql .= ", dateo";
2427 $sql .= ", datev";
2428 $sql .= ", label";
2429 $sql .= ", amount";
2430 $sql .= ", amount_main_currency";
2431 $sql .= ", fk_user_author";
2432 $sql .= ", num_chq";
2433 $sql .= ", fk_account";
2434 $sql .= ", fk_type";
2435 $sql .= ", emetteur,banque";
2436 $sql .= ", rappro";
2437 $sql .= ", numero_compte";
2438 $sql .= ", num_releve";
2439 $sql .= ", note";
2440 $sql .= ") VALUES (";
2441 $sql .= "'".$this->db->idate($this->datec)."'";
2442 $sql .= ", '".$this->db->idate($this->dateo)."'";
2443 $sql .= ", '".$this->db->idate($this->datev)."'";
2444 $sql .= ", '".$this->db->escape($this->label)."'";
2445 $sql .= ", ".price2num($this->amount);
2446 $sql .= ", ".(empty($this->amount_main_currency) ? "NULL" : price2num($this->amount_main_currency));
2447 $sql .= ", ".($this->fk_user_author > 0 ? ((int) $this->fk_user_author) : "null");
2448 $sql .= ", ".($this->num_chq ? "'".$this->db->escape($this->num_chq)."'" : "null");
2449 $sql .= ", '".$this->db->escape((string) $this->fk_account)."'";
2450 $sql .= ", '".$this->db->escape($this->fk_type)."'";
2451 $sql .= ", ".($this->emetteur ? "'".$this->db->escape($this->emetteur)."'" : "null");
2452 $sql .= ", ".($this->bank_chq ? "'".$this->db->escape($this->bank_chq)."'" : "null");
2453 $sql .= ", ".(int) $this->rappro;
2454 $sql .= ", ".($this->numero_compte ? "'".$this->db->escape($this->numero_compte)."'" : "''");
2455 $sql .= ", ".($this->num_releve ? "'".$this->db->escape($this->num_releve)."'" : "null");
2456 $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null");
2457 $sql .= ")";
2458
2459
2460 dol_syslog(get_class($this)."::insert", LOG_DEBUG);
2461 $resql = $this->db->query($sql);
2462 if ($resql) {
2463 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.'bank');
2464 // Actions on extra fields (by external module or standard code)
2465 $result = $this->insertExtraFields();
2466 if ($result < 0) {
2467 $error++;
2468 }
2469 } else {
2470 $error++;
2471 $this->error = $this->db->lasterror();
2472 dol_print_error($this->db);
2473 }
2474
2475 if (!$error) {
2476 $this->db->commit();
2477 return $this->id;
2478 } else {
2479 $this->db->rollback();
2480 return -1 * $error;
2481 }
2482 }
2483
2491 public function delete($user, $notrigger = 0)
2492 {
2493 $nbko = 0;
2494
2495 if ($this->rappro) {
2496 // Protection to avoid any delete of consolidated lines
2497 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2498 return -1;
2499 }
2500
2501 $this->db->begin();
2502
2503 if (!$notrigger) {
2504 // Call trigger
2505 $result = $this->call_trigger('BANKACCOUNTLINE_DELETE', $user);
2506 if ($result < 0) {
2507 $this->db->rollback();
2508 return -1;
2509 }
2510 // End call triggers
2511 }
2512
2513 // Protection to avoid any delete of accounted lines. Protection on by default
2514 if (!getDolGlobalString('BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING')) {
2515 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2516 $resql = $this->db->query($sql);
2517 if ($resql) {
2518 $obj = $this->db->fetch_object($resql);
2519 if ($obj && $obj->nb) {
2520 $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible';
2521 $this->db->rollback();
2522 return -1;
2523 }
2524 } else {
2525 $this->error = $this->db->lasterror();
2526 $this->db->rollback();
2527 return -1;
2528 }
2529 }
2530
2531 // Delete urls
2532 $result = $this->delete_urls($user);
2533 if ($result < 0) {
2534 $nbko++;
2535 }
2536
2537 $sql = "DELETE FROM ".MAIN_DB_PREFIX."category_bankline WHERE lineid=".(int) $this->rowid;
2538 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2539 $result = $this->db->query($sql);
2540 if (!$result) {
2541 $nbko++;
2542 }
2543
2544 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_extrafields WHERE fk_object=".(int) $this->rowid;
2545 $result = $this->db->query($sql);
2546 if (!$result) {
2547 $nbko++;
2548 }
2549
2550 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".(int) $this->rowid;
2551 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
2552 $result = $this->db->query($sql);
2553 if (!$result) {
2554 $nbko++;
2555 }
2556
2557 if (!$nbko) {
2558 $this->db->commit();
2559 return 1;
2560 } else {
2561 $this->db->rollback();
2562 return -$nbko;
2563 }
2564 }
2565
2566
2567 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2574 public function delete_urls($user = null)
2575 {
2576 // phpcs:enable
2577 $nbko = 0;
2578
2579 if ($this->rappro) {
2580 // Protection to avoid any delete of consolidated lines
2581 $this->error = "ErrorDeleteNotPossibleLineIsConsolidated";
2582 return -1;
2583 }
2584
2585 $this->db->begin();
2586
2587 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".(int) $this->rowid;
2588 dol_syslog(get_class($this)."::delete_urls", LOG_DEBUG);
2589 $result = $this->db->query($sql);
2590 if (!$result) {
2591 $nbko++;
2592 }
2593
2594 if (!$nbko) {
2595 $this->db->commit();
2596 return 1;
2597 } else {
2598 $this->db->rollback();
2599 return -$nbko;
2600 }
2601 }
2602
2603
2611 public function update(User $user, $notrigger = 0)
2612 {
2613 $this->db->begin();
2614
2615 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2616 $sql .= " amount = ".price2num($this->amount).",";
2617 $sql .= " datev='".$this->db->idate($this->datev)."',";
2618 $sql .= " dateo='".$this->db->idate($this->dateo)."'";
2619 $sql .= " WHERE rowid = ".((int) $this->rowid);
2620
2621 dol_syslog(get_class($this)."::update", LOG_DEBUG);
2622 $resql = $this->db->query($sql);
2623 if (!$resql) {
2624 $this->db->rollback();
2625 $this->error = $this->db->error();
2626 return -1;
2627 }
2628
2629 if (!$notrigger) {
2630 // Call trigger
2631 $result = $this->call_trigger('BANKACCOUNTLINE_MODIFY', $user);
2632 if ($result < 0) {
2633 $this->db->rollback();
2634 return -1;
2635 }
2636 // End call triggers
2637 }
2638
2639 $this->db->commit();
2640 return 1;
2641 }
2642
2643
2649 public function updateLabel()
2650 {
2651 $this->db->begin();
2652
2653 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2654 $sql .= " label = '".$this->db->escape($this->label)."'";
2655 $sql .= " WHERE rowid = ".((int) $this->rowid);
2656
2657 dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
2658 $resql = $this->db->query($sql);
2659 if ($resql) {
2660 $this->db->commit();
2661 return 1;
2662 } else {
2663 $this->db->rollback();
2664 $this->error = $this->db->error();
2665 return -1;
2666 }
2667 }
2668
2669
2670 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2680 public function update_conciliation(User $user, $cat, $conciliated = 1, $notrigger = 0)
2681 {
2682 // phpcs:enable
2683 global $conf, $langs;
2684
2685 $this->db->begin();
2686
2687 // Check statement field
2688 if (getDolGlobalString('BANK_STATEMENT_REGEX_RULE')) {
2689 if (!preg_match('/' . getDolGlobalString('BANK_STATEMENT_REGEX_RULE').'/', $this->num_releve)) {
2690 $this->errors[] = $langs->trans("ErrorBankStatementNameMustFollowRegex", getDolGlobalString('BANK_STATEMENT_REGEX_RULE'));
2691 $this->db->rollback();
2692 return -1;
2693 }
2694 }
2695
2696 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2697 $sql .= " rappro = ".((int) $conciliated);
2698 $sql .= ", num_releve = '".$this->db->escape($this->num_releve)."'";
2699 if ($conciliated) {
2700 $sql .= ", fk_user_rappro = ".((int) $user->id);
2701 }
2702 $sql .= " WHERE rowid = ".((int) $this->id);
2703
2704 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2705 $resql = $this->db->query($sql);
2706 if ($resql) {
2707 if (!empty($cat) && $cat > 0) {
2708 $sql = "INSERT INTO ".MAIN_DB_PREFIX."category_bankline (";
2709 $sql .= "lineid";
2710 $sql .= ", fk_categ";
2711 $sql .= ") VALUES (";
2712 $sql .= ((int) $this->id);
2713 $sql .= ", ".((int) $cat);
2714 $sql .= ")";
2715
2716 dol_syslog(get_class($this)."::update_conciliation", LOG_DEBUG);
2717 $this->db->query($sql);
2718
2719 // No error check. Can fail if category already affected
2720 // TODO Do no try the insert if link already exists
2721 }
2722
2723 $this->rappro = (int) $conciliated;
2724
2725 if (!$notrigger) {
2726 // Call trigger
2727 $result = $this->call_trigger('BANKACCOUNTLINE_MODIFY', $user);
2728 if ($result < 0) {
2729 $this->db->rollback();
2730 return -1;
2731 }
2732 // End call triggers
2733 }
2734
2735 $this->db->commit();
2736 return 1;
2737 } else {
2738 $this->db->rollback();
2739 return -1;
2740 }
2741 }
2742
2743
2744 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2752 public function datev_change($rowid, $sign = 1)
2753 {
2754 // phpcs:enable
2755 $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2756 $resql = $this->db->query($sql);
2757 if ($resql) {
2758 $obj = $this->db->fetch_object($resql);
2759 $newdate = (int) $this->db->jdate($obj->datev) + (3600 * 24 * $sign);
2760
2761 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2762 $sql .= " datev = '".$this->db->idate($newdate)."'";
2763 $sql .= " WHERE rowid = ".((int) $rowid);
2764
2765 $result = $this->db->query($sql);
2766 if ($result) {
2767 if ($this->db->affected_rows($result)) {
2768 return 1;
2769 }
2770 } else {
2771 dol_print_error($this->db);
2772 return 0;
2773 }
2774 } else {
2775 dol_print_error($this->db);
2776 }
2777 return 0;
2778 }
2779
2780 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2787 public function datev_next($id)
2788 {
2789 // phpcs:enable
2790 return $this->datev_change($id, 1);
2791 }
2792
2793 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2800 public function datev_previous($id)
2801 {
2802 // phpcs:enable
2803 return $this->datev_change($id, -1);
2804 }
2805
2806
2807 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2815 public function dateo_change($rowid, $sign = 1)
2816 {
2817 // phpcs:enable
2818 $sql = "SELECT dateo FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".((int) $rowid);
2819 $resql = $this->db->query($sql);
2820 if ($resql) {
2821 $obj = $this->db->fetch_object($resql);
2822 $newdate = (int) $this->db->jdate($obj->dateo) + (3600 * 24 * $sign);
2823
2824 $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
2825 $sql .= " dateo = '".$this->db->idate($newdate)."'";
2826 $sql .= " WHERE rowid = ".((int) $rowid);
2827
2828 $result = $this->db->query($sql);
2829 if ($result) {
2830 if ($this->db->affected_rows($result)) {
2831 return 1;
2832 }
2833 } else {
2834 dol_print_error($this->db);
2835 return 0;
2836 }
2837 } else {
2838 dol_print_error($this->db);
2839 }
2840 return 0;
2841 }
2842
2843 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2850 public function dateo_next($id)
2851 {
2852 // phpcs:enable
2853 return $this->dateo_change($id, 1);
2854 }
2855
2856 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2863 public function dateo_previous($id)
2864 {
2865 // phpcs:enable
2866 return $this->dateo_change($id, -1);
2867 }
2868
2869
2876 public function info($id)
2877 {
2878 $sql = 'SELECT b.rowid, b.datec, b.tms as datem,';
2879 $sql .= ' b.fk_user_author, b.fk_user_rappro';
2880 $sql .= ' FROM '.MAIN_DB_PREFIX.'bank as b';
2881 $sql .= ' WHERE b.rowid = '.((int) $id);
2882
2883 $result = $this->db->query($sql);
2884 if ($result) {
2885 if ($this->db->num_rows($result)) {
2886 $obj = $this->db->fetch_object($result);
2887
2888 $this->id = $obj->rowid;
2889
2890 $this->user_creation_id = $obj->fk_user_author;
2891 $this->user_rappro = $obj->fk_user_rappro;
2892 $this->date_creation = $this->db->jdate($obj->datec);
2893 $this->date_modification = $this->db->jdate($obj->datem);
2894 //$this->date_rappro = $obj->daterappro; // Not yet managed
2895 }
2896 $this->db->free($result);
2897 } else {
2898 dol_print_error($this->db);
2899 }
2900 }
2901
2902
2912 public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
2913 {
2914 global $conf, $langs;
2915
2916 $result = '';
2917
2918 $label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
2919 $label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
2920 if ($this->amount) {
2921 $label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
2922 }
2923
2924 $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">';
2925 $linkend = '</a>';
2926
2927 $result .= $linkstart;
2928 if ($withpicto) {
2929 $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);
2930 }
2931 if ($withpicto != 2) {
2932 $result .= ($this->ref ? $this->ref : $this->id);
2933 }
2934
2935 $result .= $linkend;
2936
2937 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2938 $result .= ' <span class="opacitymedium">(';
2939 }
2940 if ($option == 'showall') {
2941 $result .= $langs->trans("BankAccount").': ';
2942 $accountstatic = new Account($this->db);
2943 $accountstatic->id = $this->fk_account;
2944 $accountstatic->ref = $this->bank_account_ref;
2945 $accountstatic->label = $this->bank_account_label;
2946 $result .= $accountstatic->getNomUrl(0).', ';
2947 }
2948 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2949 $result .= $langs->trans("BankLineConciliated").': ';
2950 $result .= yn($this->rappro);
2951 }
2952 if (isModEnabled('accounting') && ($option == 'showall' || $option == 'showconciliatedandaccounted')) {
2953 $sql = "SELECT COUNT(rowid) as nb, MAX(piece_num) as banktransactionid FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
2954 $sql .= " WHERE doc_type = 'bank' AND fk_doc = ".((int) $this->id);
2955 $resql = $this->db->query($sql);
2956 if ($resql) {
2957 $obj = $this->db->fetch_object($resql);
2958 if ($obj && $obj->nb) {
2959 $result .= ' - '.$langs->trans("Accounted").': <span title="'.$langs->trans("TransactionNumShort").' '.$obj->banktransactionid.'">'.yn(1).'</span>';
2960 } else {
2961 $result .= ' - '.$langs->trans("Accounted").': '.yn(0);
2962 }
2963 }
2964 }
2965 if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
2966 $result .= ')</span>';
2967 }
2968
2969 global $action, $hookmanager;
2970 $hookmanager->initHooks(array($this->element . 'dao'));
2971 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
2972 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
2973 if ($reshook > 0) {
2974 $result = $hookmanager->resPrint;
2975 } else {
2976 $result .= $hookmanager->resPrint;
2977 }
2978
2979 return $result;
2980 }
2981
2982
2989 public function getLibStatut($mode = 0)
2990 {
2991 return $this->LibStatut($this->status, $mode);
2992 }
2993
2994 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3002 public function LibStatut($status, $mode = 0)
3003 {
3004 // phpcs:enable
3005 return '';
3006 }
3007
3014 public function getVentilExportCompta($mode = 0)
3015 {
3016 $alreadydispatched = 0;
3017
3018 $type = 'bank';
3019
3020 $sql = " SELECT ".($mode ? 'DISTINCT piece_num' : 'COUNT(ab.rowid)')." as nb";
3021 $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type = '".$this->db->escape($type)."' AND ab.fk_doc = ".((int) $this->id);
3022 $resql = $this->db->query($sql);
3023 if ($resql) {
3024 $obj = $this->db->fetch_object($resql);
3025 if ($obj) {
3026 $alreadydispatched = $obj->nb;
3027 }
3028 } else {
3029 $this->error = $this->db->lasterror();
3030 return -1;
3031 }
3032
3033 if ($alreadydispatched) {
3034 return $alreadydispatched;
3035 }
3036 return 0;
3037 }
3038}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
$propal type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition propal.php:280
checkIbanForAccount($account=null, $ibantocheck=null)
Check IBAN number information for a bank account.
Definition bank.lib.php:390
getIbanHumanReadable(Account $account)
Returns the iban human readable.
Definition bank.lib.php:415
checkSwiftForAccount($account=null, $swift=null)
Check SWIFT information for a bank account.
Definition bank.lib.php:369
$object ref
Definition info.php:90
Class to manage bank accounts.
solde($option=0, $date_end='', $field='dateo')
Return current balance.
fetch($id, $ref='')
Load a bank account into memory from database.
__construct(DoliDB $db)
Constructor.
getNomUrl($withpicto=0, $mode='', $option='', $save_lastsearch_value=-1, $notooltip=0, $morecss='')
Return clickable name (with picto eventually)
getSepaCategoryPurpose()
Return the category purpose code to write into a SEPA file for this account (PmtTpInf/CtgyPurp/Cd).
add_url_line($line_id, $url_id, $url, $label, $type)
Add a link between bank line record and its source.
const SEPA_CATEGORY_PURPOSES
Allowed codes for the category purpose of a SEPA payment (ISO 20022, ExternalCategoryPurpose1Code sub...
loadStateBoard($filteraccountid=0)
Load the indicators this->nb for the state board.
getCountryCode()
Return account country code.
getLibStatut($mode=0)
Return label of object status.
update_bban($user=null)
Update BBAN (RIB) account fields.
create($user, $notrigger=0)
Create bank account into database.
addline($date, $oper, $label, $amount, $num_chq, $categorie, User $user, $emetteur='', $banque='', $accountancycode='', $datev=null, $num_releve='', $amount_main_currency=null, $note_private='')
Add an entry into table llx_bank.
getBannerAddress($htmlkey, $object)
Return full address for banner.
error()
Return error.
info($id)
Load miscellaneous information for tab "Info".
const TYPE_CASH
Cash account.
update($user, $notrigger=0)
Update bank account card.
__toString()
Shows the account number in the appropriate format.
delete($user, $notrigger=0)
Delete bank account from database.
const TYPE_SAVINGS
Savings account.
getTooltipContentArray($params)
getTooltipContentArray
canBeConciliated()
Return if a bank account need to be conciliated.
can_be_deleted()
Indicates if an account can be deleted or not (without movements)
const TYPE_CURRENT
Current account.
setCategories($categories)
Sets object to supplied categories.
countAccountToReconcile()
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
verif()
Return if an account has valid information for Direct debit payment.
getSepaLocalInstrument()
Return the local instrument code to write into a SEPA file for this account (PmtTpInf/LclInstrm/Cd).
getFieldsToShow($includeibanbic=0)
Returns the fields in order that this bank account should show to the user Will return an array with ...
const SEPA_LOCAL_INSTRUMENTS
Allowed codes for the local instrument of a SEPA payment (ISO 20022, ExternalLocalInstrument1Code sub...
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.
LibStatut($status, $mode=0)
Return label of given object status.
Class to manage bank transaction lines.
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
setErrorsFromObject($object)
setErrorsFromObject
getFullAddress($withcountry=0, $sep="\n", $withregion=0, $extralangcode='')
Return full address of contact.
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
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.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:169
getCountry($searchkey, $withcode='', $dbtouse=null, $outputlangs=null, $entconv=1, $searchlabel='')
Return country label, code or id from an id, code or label.
global $mysoc
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_now($mode='gmt')
Return date for now.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
div refaddress div address
print $langs trans('Date')." left Ref Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:494