Make bank address optional in XML generation (some banks, at least in France, refuse files with bank addresses): new field 'pain_bank_address' on account.payment.method

Improve bank address block
Other small code improvements
This commit is contained in:
Alexis de Lattre
2018-11-28 22:47:22 +01:00
committed by Alexis de Lattre
parent 1e3bd3d6f6
commit 6bca6c3010
5 changed files with 59 additions and 13 deletions

View File

@@ -15,6 +15,14 @@ class AccountPaymentMethod(models.Model):
help="If active, Odoo will convert each accented character to "
"the corresponding unaccented character, so that only ASCII "
"characters are used in the generated PAIN file.")
pain_bank_address = fields.Boolean(
string='Bank Address in PAIN XML',
help="If enabled, the name and address of the bank will be set "
"in the appropriate XML tags (if the bank account is linked to a "
"bank and if the information is set on the related bank). "
"Some banks reject PAIN XML files that contain the name and "
"address of the bank, although the ISO 20022 "
"standard and the EPC guidelines specify this possibility.")
@api.multi
def get_xsd_file_path(self):

View File

@@ -316,14 +316,42 @@ class AccountPaymentOrder(models.Model):
return True
@api.model
def generate_fininst_postal_address(self, parent_node, bank):
def generate_fininst_postal_address(self, parent_node, bank, gen_args):
if not gen_args.get('pain_bank_address') or not bank:
return
# name is a required field on res.bank
name = etree.SubElement(parent_node, 'Nm')
name.text = self._prepare_field(
'Bank Name', 'bank.name',
{'bank': bank}, 140, gen_args=gen_args)
if not (bank.country or bank.city):
return
postal_address = etree.SubElement(parent_node, 'PstlAdr')
if bank.zip:
bankzip = etree.SubElement(postal_address, 'PstCd')
bankzip.text = self._prepare_field(
'Bank Zip', 'bank.zip',
{'bank': bank}, 16, gen_args=gen_args)
if bank.city:
etree.SubElement(postal_address, 'TwnNm').text = bank.city
city = etree.SubElement(postal_address, 'TwnNm')
city.text = self._prepare_field(
'Bank City', 'bank.city',
{'bank': bank}, 35, gen_args=gen_args)
if bank.country:
etree.SubElement(postal_address, 'Ctry').text = bank.country.code
country_code = etree.SubElement(postal_address, 'Ctry')
country_code.text = self._prepare_field(
'Bank Country Code', 'bank.country.code',
{'bank': bank}, 2, gen_args=gen_args)
if bank.street:
adrline1 = etree.SubElement(postal_address, 'AdrLine')
adrline1.text = self._prepare_field(
'Bank Address Line1', 'bank.street',
{'bank': bank}, 70, gen_args=gen_args)
if bank.street2:
adrline2 = etree.SubElement(postal_address, 'AdrLine')
adrline2.text = self._prepare_field(
'Bank Address Line2', 'bank.street2',
{'bank': bank}, 70, gen_args=gen_args)
@api.model
def generate_party_agent(
@@ -346,7 +374,7 @@ class AccountPaymentOrder(models.Model):
party_agent_institution, gen_args.get('bic_xml_tag'))
party_agent_bic.text = partner_bank.bank_bic
self.generate_fininst_postal_address(
party_agent_institution, partner_bank.bank_id)
party_agent_institution, partner_bank.bank_id, gen_args)
else:
if order == 'B' or (
order == 'C' and gen_args['payment_method'] == 'DD'):
@@ -355,7 +383,7 @@ class AccountPaymentOrder(models.Model):
party_agent_institution = etree.SubElement(
party_agent, 'FinInstnId')
self.generate_fininst_postal_address(
party_agent_institution, partner_bank.bank_id)
party_agent_institution, partner_bank.bank_id, gen_args)
party_agent_other = etree.SubElement(
party_agent_institution, 'Othr')
party_agent_other_identification = etree.SubElement(
@@ -445,7 +473,12 @@ class AccountPaymentOrder(models.Model):
if partner.street:
adrline1 = etree.SubElement(postal_address, 'AdrLine')
adrline1.text = self._prepare_field(
'Adress Line1', 'partner.street',
'Address Line1', 'partner.street',
{'partner': partner}, 70, gen_args=gen_args)
if partner.street2:
adrline2 = etree.SubElement(postal_address, 'AdrLine')
adrline2.text = self._prepare_field(
'Address Line2', 'partner.street2',
{'partner': partner}, 70, gen_args=gen_args)
self.generate_party_id(party, party_type, partner)

View File

@@ -11,6 +11,8 @@
<field name="pain_version"/>
<field name="convert_to_ascii"
attrs="{'invisible': [('pain_version', '=', False)]}"/>
<field name="pain_bank_address"
attrs="{'invisible': [('pain_version', '=', False)]}"/>
</field>
</field>
</record>

View File

@@ -28,10 +28,11 @@ class AccountPaymentOrder(models.Model):
def generate_payment_file(self):
"""Creates the SEPA Credit Transfer file. That's the important code!"""
self.ensure_one()
if self.payment_method_id.code != 'sepa_credit_transfer':
pay_method = self.payment_method_id
if pay_method.code != 'sepa_credit_transfer':
return super(AccountPaymentOrder, self).generate_payment_file()
pain_flavor = self.payment_method_id.pain_version
pain_flavor = pay_method.pain_version
if not pain_flavor:
pain_flavor = 'pain.001.001.03'
# We use pain_flavor.startswith('pain.001.001.xx')
@@ -71,11 +72,12 @@ class AccountPaymentOrder(models.Model):
else:
raise UserError(
_("PAIN version '%s' is not supported.") % pain_flavor)
xsd_file = self.payment_method_id.get_xsd_file_path()
xsd_file = pay_method.get_xsd_file_path()
gen_args = {
'bic_xml_tag': bic_xml_tag,
'name_maxsize': name_maxsize,
'convert_to_ascii': self.payment_method_id.convert_to_ascii,
'convert_to_ascii': pay_method.convert_to_ascii,
'pain_bank_address': pay_method.pain_bank_address,
'payment_method': 'TRF',
'file_prefix': 'sct_',
'pain_flavor': pain_flavor,

View File

@@ -14,9 +14,10 @@ class AccountPaymentOrder(models.Model):
def generate_payment_file(self):
"""Creates the SEPA Direct Debit file. That's the important code !"""
self.ensure_one()
if self.payment_method_id.code != 'sepa_direct_debit':
pay_method = self.payment_method_id
if pay_method.code != 'sepa_direct_debit':
return super(AccountPaymentOrder, self).generate_payment_file()
pain_flavor = self.payment_method_id.pain_version
pain_flavor = pay_method.pain_version
# We use pain_flavor.startswith('pain.008.001.xx')
# to support country-specific extensions such as
# pain.008.001.02.ch.01 (cf l10n_ch_sepa)
@@ -42,12 +43,12 @@ class AccountPaymentOrder(models.Model):
"Payment Type Code supported for SEPA Direct Debit are "
"'pain.008.001.02', 'pain.008.001.03' and "
"'pain.008.001.04'.") % pain_flavor)
pay_method = self.payment_mode_id.payment_method_id
xsd_file = pay_method.get_xsd_file_path()
gen_args = {
'bic_xml_tag': bic_xml_tag,
'name_maxsize': name_maxsize,
'convert_to_ascii': pay_method.convert_to_ascii,
'pain_bank_address': pay_method.pain_bank_address,
'payment_method': 'DD',
'file_prefix': 'sdd_',
'pain_flavor': pain_flavor,