2021-06-30 06:38:22 +00:00
|
|
|
# copyright 2016 Akretion (www.akretion.com)
|
|
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
|
|
|
|
2021-07-21 11:01:38 +00:00
|
|
|
from flectra import models, api, _
|
2021-06-30 06:39:40 +00:00
|
|
|
from flectra.exceptions import UserError
|
2021-07-21 11:01:38 +00:00
|
|
|
from lxml import etree
|
2021-06-30 06:38:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
class AccountPaymentOrder(models.Model):
|
2021-07-21 11:01:38 +00:00
|
|
|
_inherit = 'account.payment.order'
|
2021-06-30 06:38:22 +00:00
|
|
|
|
|
|
|
def compute_sepa_final_hook(self, sepa):
|
|
|
|
self.ensure_one()
|
|
|
|
sepa = super().compute_sepa_final_hook(sepa)
|
|
|
|
pain_flavor = self.payment_mode_id.payment_method_id.pain_version
|
2021-07-21 11:01:38 +00:00
|
|
|
|
|
|
|
if pain_flavor and '.ch.' in pain_flavor:
|
|
|
|
# If all payments are made to Swiss IBANs, it's a domestic order
|
|
|
|
acc_numbers = self.payment_line_ids.mapped(
|
|
|
|
'partner_bank_id.acc_number')
|
|
|
|
acc_numbers = list(set([x[0:2] for x in acc_numbers]))
|
|
|
|
if acc_numbers == ['CH']:
|
|
|
|
return False
|
|
|
|
|
|
|
|
# ISR orders cannot be SEPA orders
|
|
|
|
instrs = self.payment_line_ids.mapped('local_instrument')
|
|
|
|
if 'CH01' in instrs:
|
|
|
|
return False
|
2021-06-30 06:38:22 +00:00
|
|
|
return sepa
|
|
|
|
|
|
|
|
def generate_pain_nsmap(self):
|
|
|
|
self.ensure_one()
|
|
|
|
nsmap = super().generate_pain_nsmap()
|
|
|
|
pain_flavor = self.payment_mode_id.payment_method_id.pain_version
|
2021-07-21 11:01:38 +00:00
|
|
|
if pain_flavor in ['pain.001.001.03.ch.02', 'pain.008.001.02.ch.01']:
|
|
|
|
nsmap[None] = 'http://www.six-interbank-clearing.com/de/'\
|
|
|
|
'%s.xsd' % pain_flavor
|
2021-06-30 06:38:22 +00:00
|
|
|
|
|
|
|
return nsmap
|
|
|
|
|
|
|
|
def generate_pain_attrib(self):
|
|
|
|
self.ensure_one()
|
|
|
|
pain_flavor = self.payment_mode_id.payment_method_id.pain_version
|
2021-07-21 11:01:38 +00:00
|
|
|
if pain_flavor in ['pain.001.001.03.ch.02', 'pain.008.001.02.ch.01']:
|
2021-06-30 06:38:22 +00:00
|
|
|
attrib = {
|
2021-07-21 11:01:38 +00:00
|
|
|
"{http://www.w3.org/2001/XMLSchema-instance}schemaLocation":
|
|
|
|
"http://www.six-interbank-clearing.com/de/"
|
2021-06-30 06:38:22 +00:00
|
|
|
"%s.xsd %s.xsd" % (pain_flavor, pain_flavor)
|
2021-07-21 11:01:38 +00:00
|
|
|
}
|
2021-06-30 06:38:22 +00:00
|
|
|
return attrib
|
|
|
|
else:
|
|
|
|
return super().generate_pain_attrib()
|
|
|
|
|
|
|
|
@api.model
|
|
|
|
def generate_start_payment_info_block(
|
2021-07-21 11:01:38 +00:00
|
|
|
self, parent_node, payment_info_ident,
|
|
|
|
priority, local_instrument, category_purpose, sequence_type,
|
|
|
|
requested_date, eval_ctx, gen_args):
|
|
|
|
if gen_args.get('pain_flavor') == 'pain.001.001.03.ch.02':
|
|
|
|
gen_args['local_instrument_type'] = 'proprietary'
|
|
|
|
gen_args['structured_remittance_issuer'] = False
|
2021-06-30 06:38:22 +00:00
|
|
|
return super().generate_start_payment_info_block(
|
2021-07-21 11:01:38 +00:00
|
|
|
parent_node, payment_info_ident, priority, local_instrument,
|
|
|
|
category_purpose, sequence_type, requested_date, eval_ctx,
|
2021-06-30 06:38:22 +00:00
|
|
|
gen_args,
|
|
|
|
)
|
|
|
|
|
|
|
|
@api.model
|
|
|
|
def generate_party_agent(
|
2021-07-21 11:01:38 +00:00
|
|
|
self, parent_node, party_type, order, partner_bank, gen_args,
|
|
|
|
bank_line=None):
|
|
|
|
if (
|
|
|
|
gen_args.get('pain_flavor') == 'pain.001.001.03.ch.02' and
|
|
|
|
bank_line and
|
|
|
|
bank_line.communication_type == 'isr'):
|
|
|
|
if bank_line.local_instrument == 'CH01':
|
2021-06-30 06:38:22 +00:00
|
|
|
# Don't set the creditor agent on ISR/CH01 payments
|
|
|
|
return True
|
|
|
|
elif not partner_bank.bank_bic:
|
2021-07-21 11:01:38 +00:00
|
|
|
raise UserError(_(
|
|
|
|
"For pain.001.001.03.ch.02, for non-ISR payments, "
|
|
|
|
"the BIC is required on the bank '%s' related to the "
|
|
|
|
"bank account '%s'") % (
|
|
|
|
partner_bank.bank_id.name,
|
|
|
|
partner_bank.acc_number))
|
2021-06-30 06:38:22 +00:00
|
|
|
return super().generate_party_agent(
|
2021-07-21 11:01:38 +00:00
|
|
|
parent_node, party_type, order, partner_bank, gen_args,
|
2021-06-30 06:38:22 +00:00
|
|
|
bank_line=bank_line,
|
|
|
|
)
|
|
|
|
|
|
|
|
@api.model
|
2021-07-21 11:01:38 +00:00
|
|
|
def generate_party_acc_number(self, parent_node, party_type, order,
|
|
|
|
partner_bank, gen_args, bank_line=None):
|
|
|
|
if (gen_args.get('pain_flavor') == 'pain.001.001.03.ch.02' and
|
|
|
|
bank_line and
|
|
|
|
bank_line.communication_type == 'isr' and
|
|
|
|
bank_line.local_instrument == 'CH01'):
|
|
|
|
if not partner_bank.ccp:
|
|
|
|
raise UserError(_(
|
|
|
|
"The field 'CCP/CP-Konto' is not set on the bank "
|
|
|
|
"account '%s'.") % partner_bank.acc_number)
|
|
|
|
party_account = etree.SubElement(
|
|
|
|
parent_node, '%sAcct' % party_type)
|
|
|
|
party_account_id = etree.SubElement(party_account, 'Id')
|
|
|
|
party_account_other = etree.SubElement(
|
|
|
|
party_account_id, 'Othr')
|
|
|
|
party_account_other_id = etree.SubElement(
|
|
|
|
party_account_other, 'Id')
|
|
|
|
party_account_other_id.text = partner_bank.ccp
|
2021-06-30 06:38:22 +00:00
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return super().generate_party_acc_number(
|
2021-07-21 11:01:38 +00:00
|
|
|
parent_node, party_type, order, partner_bank, gen_args,
|
|
|
|
bank_line=bank_line)
|
2021-06-30 06:38:22 +00:00
|
|
|
|
|
|
|
@api.model
|
2021-07-21 11:01:38 +00:00
|
|
|
def generate_address_block(
|
|
|
|
self, parent_node, partner, gen_args):
|
2021-06-30 06:38:22 +00:00
|
|
|
"""Generate the piece of the XML corresponding to PstlAdr"""
|
|
|
|
if partner.country_id:
|
2021-07-21 11:01:38 +00:00
|
|
|
postal_address = etree.SubElement(parent_node, 'PstlAdr')
|
2021-06-30 06:38:22 +00:00
|
|
|
|
2021-07-21 11:01:38 +00:00
|
|
|
country = etree.SubElement(postal_address, 'Ctry')
|
2021-06-30 06:38:22 +00:00
|
|
|
country.text = self._prepare_field(
|
2021-07-21 11:01:38 +00:00
|
|
|
'Country', 'partner.country_id.code',
|
|
|
|
{'partner': partner}, 2, gen_args=gen_args)
|
2021-06-30 06:38:22 +00:00
|
|
|
|
|
|
|
if partner.street or partner.street2:
|
2021-07-21 11:01:38 +00:00
|
|
|
adrline1 = etree.SubElement(postal_address, 'AdrLine')
|
|
|
|
adrline1.text = ', '.join(
|
2021-06-30 06:38:22 +00:00
|
|
|
filter(None, [partner.street, partner.street2])
|
|
|
|
)
|
|
|
|
|
|
|
|
if partner.zip and partner.city:
|
2021-07-21 11:01:38 +00:00
|
|
|
adrline2 = etree.SubElement(postal_address, 'AdrLine')
|
|
|
|
adrline2.text = ' '.join([partner.zip, partner.city])
|
2021-06-30 06:38:22 +00:00
|
|
|
|
|
|
|
return True
|