From 1be5145148ec0037b545ac1fc834c97b4a6d7120 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 2 Feb 2023 14:56:03 +0100 Subject: [PATCH] NEW Add more zip, town, country for owner of a bank account --- .../qr-bar-codes/QR code for invoices.txt | 4 +- htdocs/compta/bank/card.php | 122 +++++++++++++----- htdocs/compta/bank/class/account.class.php | 56 +++++--- htdocs/core/class/commoninvoice.class.php | 6 +- .../install/mysql/migration/17.0.0-18.0.0.sql | 7 + .../install/mysql/tables/llx_bank_account.sql | 3 + htdocs/langs/en_US/banks.lang | 3 + 7 files changed, 148 insertions(+), 53 deletions(-) diff --git a/dev/resources/iso-normes/qr-bar-codes/QR code for invoices.txt b/dev/resources/iso-normes/qr-bar-codes/QR code for invoices.txt index b388ed0c599..b14f33638c2 100644 --- a/dev/resources/iso-normes/qr-bar-codes/QR code for invoices.txt +++ b/dev/resources/iso-normes/qr-bar-codes/QR code for invoices.txt @@ -22,8 +22,8 @@ https://www.tecklenborgh.com/post/ksa-zatca-publishes-guide-on-how-to-develop-a- Method to encode/decode ZATCA string is available in test/phpunit/BarcodeTest.php -* FOR QR-Bill in switzerland ----------------------------- +* FOR QR-Bill in switzerland - Facture-QR +----------------------------------------- Syntax of QR Code https://www.swiss-qr-invoice.org/fr/ Syntax of complentary field named "structured information of invoice S1": https://www.swiss-qr-invoice.org/downloads/qr-bill-s1-syntax-fr.pdf To test/validate: https://www.swiss-qr-invoice.org/validator/ diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 15cb5123e0f..3ba717f7a51 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -51,7 +51,7 @@ if (isModEnabled('accounting')) { } // Load translation files required by the page -$langs->loadLangs(array("banks", "bills", "categories", "companies", "compta")); +$langs->loadLangs(array("banks", "bills", "categories", "companies", "compta", "withdrawals")); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); @@ -140,6 +140,9 @@ if (empty($reshook)) { $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'alphanohtml')); + $object->owner_zip = trim(GETPOST("owner_zip", 'alphanohtml')); + $object->owner_town = trim(GETPOST("owner_town", 'alphanohtml')); + $object->owner_country_id = GETPOST("owner_country_id", 'int'); $object->ics = trim(GETPOST("ics", 'alpha')); $object->ics_transfer = trim(GETPOST("ics_transfer", 'alpha')); @@ -241,6 +244,9 @@ if (empty($reshook)) { $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'alphanohtml')); + $object->owner_zip = trim(GETPOST("owner_zip", 'alphanohtml')); + $object->owner_town = trim(GETPOST("owner_town", 'alphanohtml')); + $object->owner_country_id = GETPOST("owner_country_id", 'int'); $object->ics = trim(GETPOST("ics", 'alpha')); $object->ics_transfer = trim(GETPOST("ics_transfer", 'alpha')); @@ -422,7 +428,8 @@ if ($action == 'create') { print ''.$langs->trans("BankAccountCountry").''; print ''; - print img_picto('', 'country', 'class="pictofixedwidth"').$form->select_country($selectedcode, 'account_country_id'); + print img_picto('', 'country', 'class="pictofixedwidth"'); + print $form->select_country($selectedcode, 'account_country_id'); if ($user->admin) { print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); } @@ -438,6 +445,14 @@ if ($action == 'create') { } print ''; + $type = (GETPOSTISSET("type") ? GETPOST('type', 'int') : Account::TYPE_CURRENT); // add default value + if ($type == Account::TYPE_SAVINGS || $type == Account::TYPE_CURRENT) { + print ''.$langs->trans("BankAccountDomiciliation").''; + print '"; + } + // Web print ''.$langs->trans("Web").''; print ''; @@ -552,18 +567,15 @@ if ($action == 'create') { print ''; if (isModEnabled('paymentbybanktransfer')) { - print ''.$langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation").''; - print ' '; - print img_picto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp"), 'info'); + print ''.$form->textwithpicto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation"), $langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp")).''; + print ''; print ''; } + print ''; + print '
'; - print ''.$langs->trans("BankAccountDomiciliation").''; - print '"; - - print ''.$langs->trans("BankAccountOwner").''; + print ''; + print ''; print ''; @@ -572,8 +584,22 @@ if ($action == 'create') { print (GETPOST('owner_address') ?GETPOST('owner_address', 'alpha') : $object->owner_address); print ""; + print ''; + print ''; + + print ''; + print ''; + + print ''; + print ''; + print '
'.$langs->trans("BankAccountOwner").''; print '
'.$langs->trans("BankAccountOwnerZip").''; + print '
'.$langs->trans("BankAccountOwnerTown").''; + print '
'.$langs->trans("BankAccountOwnerCountry").''; + print img_picto('', 'country', 'class="pictofixedwidth"'); + print $form->select_country(GETPOST('owner_country_id') ?GETPOST('owner_country_id', 'alpha') : $object->owner_country_id, 'owner_country_id'); + print '
'; - print '
'; + print '
'; } print ''; @@ -722,8 +748,6 @@ if ($action == 'create') { print '
'; if ($object->type == Account::TYPE_SAVINGS || $object->type == Account::TYPE_CURRENT) { - //print '
'; - print ''; print ''; @@ -787,16 +811,11 @@ if ($action == 'create') { print ''; print ''; - print '\n"; } - print '\n"; - print '\n"; @@ -805,6 +824,22 @@ if ($action == 'create') { print nl2br($object->owner_address); print "\n"; + print ''; + print ''; + + print ''; + print ''; + + print ''; + print ''; + print '
'.$langs->trans("BankName").''.$object->ics_transfer.'
'.$langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation").''; - print (empty($object->pti_in_ctti) ? $langs->trans("No") : $langs->trans("Yes")) . ' '; - print img_picto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp"), 'info'); + print '
'.$form->textwithpicto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation"), $langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp")).''; + print (empty($object->pti_in_ctti) ? $langs->trans("No") : $langs->trans("Yes")); print "
'.$langs->trans("BankAccountDomiciliation").''; - print nl2br($object->domiciliation); - print "
'.$langs->trans("BankAccountOwner").''; print $object->proprio; print "
'.$langs->trans("BankAccountOwnerZip").''.$object->owner_zip; + print '
'.$langs->trans("BankAccountOwnerTown").''.$object->owner_town; + print '
'.$langs->trans("BankAccountOwnerCountry").''; + $object->owner_country_code = dol_getIdFromCode($db, $object->owner_country_id, 'c_country', 'rowid', 'code'); + $langs->load("dict"); + print (empty($object->owner_country_code) ? '' : $langs->convToOutputCharset($langs->transnoentitiesnoconv("Country".$object->owner_country_code))); + + print '
'; } @@ -933,6 +968,14 @@ if ($action == 'create') { } print ''; + $type = (GETPOSTISSET('type') ? GETPOST('type', 'int') : $object->type); // add default current value + if ($type == Account::TYPE_SAVINGS || $type == Account::TYPE_CURRENT) { + print ''.$langs->trans("BankAccountDomiciliation").''; + print '"; + } + // Conciliable print ''.$langs->trans("Conciliable").''; print ''; @@ -942,7 +985,7 @@ if ($action == 'create') { } elseif ($conciliate == -3) { print $langs->trans("No").' ('.$langs->trans("Closed").')'; } else { - print ' 0) ? '' : ' checked="checked"').'"> '; + print ' 0) ? '' : ' checked="checked"').'"> '; } print ''; @@ -993,7 +1036,7 @@ if ($action == 'create') { } print ''; - print '
'; + print '
'; //print '
'; @@ -1030,8 +1073,6 @@ if ($action == 'create') { if ($type == Account::TYPE_SAVINGS || $type == Account::TYPE_CURRENT) { print '
'; - //print '
'; - print ''; // If bank account @@ -1087,26 +1128,39 @@ if ($action == 'create') { print ''; print ''; - print ''; - print ''; + print ''; } - print '"; - print ''; print ''; print ''; - print '
'.$form->textwithpicto($langs->trans("IDS"), $langs->trans("IDS").' ('.$langs->trans("UsedFor", $langs->transnoentitiesnoconv("BankTransfer")).')').'
'.$langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation").'pti_in_ctti ? ' checked ' : '') . '> '; - print img_picto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp"), 'info'); + print '
'.$form->textwithpicto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation"), $langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp")).'pti_in_ctti ? ' checked ' : '') . '>'; print '
'.$langs->trans("BankAccountDomiciliation").''; - print '
'.$langs->trans("BankAccountOwner").'
'.$langs->trans("BankAccountOwnerAddress").''; + print '
'; + print '
'; + + print ''; + + print '"; + print ''; + print ''; + + print ''; + print ''; + + print ''; + print ''; + print '
'.$langs->trans("BankAccountOwnerAddress").''; print '
'.$langs->trans("BankAccountOwnerZip").''; + print '
'.$langs->trans("BankAccountOwnerTown").''; + print '
'.$langs->trans("BankAccountOwnerCountry").''; + print img_picto('', 'country', 'class="pictofixedwidth"'); + print $form->select_country(GETPOST('owner_country_id') ?GETPOST('owner_country_id', 'alpha') : $object->owner_country_id, 'owner_country_id'); + print '
'; } diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index e144677832f..a623184478b 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -146,12 +146,6 @@ class Account extends CommonObject */ public $iban_prefix; - /** - * Address of the bank - * @var string - */ - public $domiciliation; - /** * XML SEPA format: place Payment Type Information (PmtTpInf) in Credit Transfer Transaction Information (CdtTrfTxInf) * @var int @@ -169,7 +163,17 @@ class Account extends CommonObject * @var string */ public $owner_address; + public $owner_zip; + public $owner_town; + public $owner_country_id; + public $owner_country_code; + /** + * Address of the bank account + * @var string + */ + public $domiciliation; // deprecated, use now address + public $address; public $state_id; public $state_code; public $state; @@ -297,10 +301,13 @@ class Account extends CommonObject 'country_iban' =>array('type'=>'varchar(2)', 'label'=>'Country iban', 'enabled'=>1, 'visible'=>-1, 'position'=>75), 'cle_iban' =>array('type'=>'varchar(2)', 'label'=>'Cle iban', 'enabled'=>1, 'visible'=>-1, 'position'=>80), 'domiciliation' =>array('type'=>'varchar(255)', 'label'=>'Domiciliation', 'enabled'=>1, 'visible'=>-1, 'position'=>85), - 'state_id' =>array('type'=>'integer', 'label'=>'State id', 'enabled'=>1, 'visible'=>-1, 'position'=>90), - 'fk_pays' =>array('type'=>'integer', 'label'=>'Fk pays', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>95), + 'state_id' =>array('type'=>'integer', 'label'=>'StateId', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'fk_pays' =>array('type'=>'integer', 'label'=>'Country', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>95), 'proprio' =>array('type'=>'varchar(60)', 'label'=>'Proprio', 'enabled'=>1, 'visible'=>-1, 'position'=>100), - 'owner_address' =>array('type'=>'text', 'label'=>'Owner address', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'owner_address' =>array('type'=>'varchar(255)', 'label'=>'Owner address', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'owner_zip' =>array('type'=>'varchar(25)', 'label'=>'Owner zip', 'enabled'=>1, 'visible'=>-1, 'position'=>106), + 'owner_town' =>array('type'=>'varchar(50)', 'label'=>'Owner town', 'enabled'=>1, 'visible'=>-1, 'position'=>107), + 'owner_country_id' =>array('type'=>'integer', 'label'=>'Owner country', 'enabled'=>1, 'visible'=>-1, 'position'=>108), 'courant' =>array('type'=>'smallint(6)', 'label'=>'Courant', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>110), 'clos' =>array('type'=>'smallint(6)', 'label'=>'Clos', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>115), 'rappro' =>array('type'=>'smallint(6)', 'label'=>'Rappro', 'enabled'=>1, 'visible'=>-1, 'position'=>120), @@ -698,6 +705,9 @@ class Account extends CommonObject $sql .= ", pti_in_ctti"; $sql .= ", proprio"; $sql .= ", owner_address"; + $sql .= ", owner_zip"; + $sql .= ", owner_town"; + $sql .= ", owner_country_id"; $sql .= ", currency_code"; $sql .= ", rappro"; $sql .= ", min_allowed"; @@ -713,7 +723,7 @@ class Account extends CommonObject $sql .= ", '".$this->db->escape($this->label)."'"; $sql .= ", ".((int) $conf->entity); $sql .= ", '".$this->db->escape($this->account_number)."'"; - $sql .= ", ".($this->fk_accountancy_journal > 0 ? $this->db->escape($this->fk_accountancy_journal) : "null"); + $sql .= ", ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null"); $sql .= ", '".$this->db->escape($this->bank)."'"; $sql .= ", '".$this->db->escape($this->code_banque)."'"; $sql .= ", '".$this->db->escape($this->code_guichet)."'"; @@ -725,6 +735,9 @@ class Account extends CommonObject $sql .= ", ".((int) $this->pti_in_ctti); $sql .= ", '".$this->db->escape($this->proprio)."'"; $sql .= ", '".$this->db->escape($this->owner_address)."'"; + $sql .= ", '".$this->db->escape($this->owner_zip)."'"; + $sql .= ", '".$this->db->escape($this->owner_town)."'"; + $sql .= ", ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null"); $sql .= ", '".$this->db->escape($this->currency_code)."'"; $sql .= ", ".((int) $this->rappro); $sql .= ", ".price2num($this->min_allowed, 'MT'); @@ -836,7 +849,7 @@ class Account extends CommonObject $sql .= ",rappro = ".((int) $this->rappro); $sql .= ",url = ".($this->url ? "'".$this->db->escape($this->url)."'" : "null"); $sql .= ",account_number = '".$this->db->escape($this->account_number)."'"; - $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? $this->db->escape($this->fk_accountancy_journal) : "null"); + $sql .= ",fk_accountancy_journal = ".($this->fk_accountancy_journal > 0 ? ((int) $this->fk_accountancy_journal) : "null"); $sql .= ",bank = '".$this->db->escape($this->bank)."'"; $sql .= ",code_banque='".$this->db->escape($this->code_banque)."'"; $sql .= ",code_guichet='".$this->db->escape($this->code_guichet)."'"; @@ -848,6 +861,9 @@ class Account extends CommonObject $sql .= ",pti_in_ctti=".((int) $this->pti_in_ctti); $sql .= ",proprio = '".$this->db->escape($this->proprio)."'"; $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'"; + $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'"; + $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'"; + $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null"); $sql .= ",currency_code = '".$this->db->escape($this->currency_code)."'"; @@ -931,6 +947,9 @@ class Account extends CommonObject $sql .= ",domiciliation='".$this->db->escape($this->domiciliation)."'"; $sql .= ",proprio = '".$this->db->escape($this->proprio)."'"; $sql .= ",owner_address = '".$this->db->escape($this->owner_address)."'"; + $sql .= ",owner_zip = '".$this->db->escape($this->owner_zip)."'"; + $sql .= ",owner_town = '".$this->db->escape($this->owner_town)."'"; + $sql .= ",owner_country_id = ".($this->owner_country_id > 0 ? ((int) $this->owner_country_id) : "null"); $sql .= ",state_id = ".($this->state_id > 0 ? $this->state_id : "null"); $sql .= ",fk_pays = ".($this->country_id > 0 ? $this->country_id : "null"); $sql .= " WHERE rowid = ".((int) $this->id); @@ -967,13 +986,13 @@ class Account extends CommonObject $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant, ba.clos, ba.rappro, ba.url,"; $sql .= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,"; - $sql .= " ba.domiciliation, ba.pti_in_ctti, ba.proprio, ba.owner_address, ba.state_id, ba.fk_pays as country_id,"; + $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,"; $sql .= " ba.account_number, ba.fk_accountancy_journal, ba.currency_code,"; $sql .= " ba.min_allowed, ba.min_desired, ba.comment,"; $sql .= " ba.datec as date_creation, ba.tms as date_update, ba.ics, ba.ics_transfer,"; $sql .= ' c.code as country_code, c.label as country,'; - $sql .= ' d.code_departement as state_code, d.nom as state'; - $sql .= ' , aj.code as accountancy_journal'; + $sql .= ' d.code_departement as state_code, d.nom as state,'; + $sql .= ' aj.code as accountancy_journal'; $sql .= " FROM ".MAIN_DB_PREFIX."bank_account as ba"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON ba.fk_pays = c.rowid'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.state_id = d.rowid'; @@ -1009,10 +1028,14 @@ class Account extends CommonObject $this->cle_rib = $obj->cle_rib; $this->bic = $obj->bic; $this->iban = $obj->iban; - $this->domiciliation = $obj->domiciliation; + $this->domiciliation = $obj->address; + $this->address = $obj->address; $this->pti_in_ctti = $obj->pti_in_ctti; $this->proprio = $obj->proprio; $this->owner_address = $obj->owner_address; + $this->owner_zip = $obj->owner_zip; + $this->owner_town = $obj->owner_town; + $this->owner_country_id = $obj->owner_country_id; $this->state_id = $obj->state_id; $this->state_code = $obj->state_code; @@ -1723,6 +1746,9 @@ class Account extends CommonObject $this->domiciliation = 'Banque de France'; $this->proprio = 'Owner'; $this->owner_address = 'Owner address'; + $this->owner_zip = 'Owner zip'; + $this->owner_town = 'Owner town'; + $this->owner_country_id = 'Owner country_id'; $this->country_id = 1; } diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index dd0ec988062..cc871fd1ef2 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -1735,15 +1735,17 @@ abstract class CommonInvoice extends CommonObject $complementaryinfo .= '/30/'.$this->thirdparty->tva_intra; } + $bankaccount = new Account($this->db); + // Header $s = ''; $s .= "SPC\n"; $s .= "0200\n"; $s .= "1\n"; + // Info seller if ($this->fk_account > 0) { // Bank BAN if country is LI or CH - // TODO Add - $bankaccount = new Account($this->db); + // TODO Add test on bank iban $bankaccount->fetch($this->fk_account); $s .= $bankaccount->iban."\n"; } else { diff --git a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql index c97d080db3a..11495748eff 100644 --- a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql +++ b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql @@ -64,3 +64,10 @@ ALTER TABLE llx_website ADD COLUMN pageviews_previous_month BIGINT UNSIGNED DEFA ALTER TABLE llx_product_stock ADD CONSTRAINT fk_product_product_rowid FOREIGN KEY (fk_product) REFERENCES llx_product (rowid); ALTER TABLE llx_product_stock ADD CONSTRAINT fk_entrepot_entrepot_rowid FOREIGN KEY (fk_entrepot) REFERENCES llx_entrepot (rowid); + + +ALTER TABLE llx_bank_account ADD COLUMN owner_zip varchar(25); +ALTER TABLE llx_bank_account ADD COLUMN owner_town varchar(50); +ALTER TABLE llx_bank_account ADD COLUMN owner_country_id integer DEFAULT NULL; + + diff --git a/htdocs/install/mysql/tables/llx_bank_account.sql b/htdocs/install/mysql/tables/llx_bank_account.sql index d9713b66d38..d7b8941e69b 100644 --- a/htdocs/install/mysql/tables/llx_bank_account.sql +++ b/htdocs/install/mysql/tables/llx_bank_account.sql @@ -47,6 +47,9 @@ create table llx_bank_account fk_pays integer NOT NULL, proprio varchar(60), owner_address varchar(255), + owner_zip varchar(25), + owner_town varchar(50), + owner_country_id integer DEFAULT NULL, courant smallint DEFAULT 0 NOT NULL, clos smallint DEFAULT 0 NOT NULL, rappro smallint DEFAULT 1, diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang index 10ba859e71f..7be02da2c27 100644 --- a/htdocs/langs/en_US/banks.lang +++ b/htdocs/langs/en_US/banks.lang @@ -49,6 +49,9 @@ BankAccountDomiciliation=Bank address BankAccountCountry=Account country BankAccountOwner=Account owner name BankAccountOwnerAddress=Account owner address +BankAccountOwnerZip=Account owner zip +BankAccountOwnerTown=Account owner town +BankAccountOwnerCountry=Account owner country CreateAccount=Create account NewBankAccount=New account NewFinancialAccount=New financial account