l10n-switzerland-flectra/l10n_ch_base_bank/models/partner_bank.py
Raphael Ritter bc2374f0d9 moved to f2
2021-06-30 08:39:40 +02:00

132 lines
4.9 KiB
Python

# Copyright 2012-2019 Camptocamp
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from flectra import _, api, models
class ResPartnerBank(models.Model):
"""Inherit res.partner.bank class in order to add swiss specific fields
and state controls
Statements:
acc_type could be of 3 types:
- postal
- iban
- bank
if account has postal number and acc_type = 'postal' we dropped acc_number
and compute it based on postal number, and partner
if acc_number given in 'iban' format just transform to iban format, but no
further modification on it, and acc_type = 'iban'
it means that postal number in account is a number directly identifying
the partner acc_number can contains the postal number
if given bank account is 'bank' and l10n_ch_postal is set
if given bank type is a 'bank' then postal number in account should be
acc_number recomputed
acc_number in this case recomputed by as partner_name + l10n_ch_postal
"""
_inherit = "res.partner.bank"
def is_isr_issuer(self):
"""Supplier will provide ISR/QRR reference numbers in two cases:
- postal account number starting by 01 or 03
- QR-IBAN
"""
# acc_type can be bank for isrb
if self.acc_type in ["bank", "postal"] and self.l10n_ch_postal:
return self.l10n_ch_postal[:2] in ["01", "03"]
return self.acc_type == "iban" and self._is_qr_iban()
def _get_ch_bank_from_iban(self):
"""Extract clearing number from CH iban to find the bank"""
if self.acc_type != "iban" and self.acc_number[:2] != "CH":
return False
clearing = self.sanitized_acc_number[4:9].lstrip("0")
return clearing and self.env["res.bank"].search(
[("clearing", "=", clearing)], limit=1
)
@api.onchange("acc_number", "acc_type")
def _onchange_acc_number_set_swiss_bank(self):
"""Deduce information from IBAN
Bank is defined as:
- Found bank by clearing when using iban
"""
bank = self.bank_id
if self.acc_type == "iban":
bank = self._get_ch_bank_from_iban()
self.bank_id = bank
@api.onchange("l10n_ch_postal")
def _onchange_postal_set_acc_number(self):
"""Set acc_number from postal field"""
if self.acc_type != "iban" and self.l10n_ch_postal:
self._update_acc_number()
@api.onchange("partner_id")
def onchange_partner_set_acc_number(self):
# When acc_number was computed automatically we call regeneration
# as partner name is part of acc_number
# This is only required for ISR subscription numbers
if self.l10n_ch_postal and self.l10n_ch_postal[:2] in ["01", "03"]:
self._update_acc_number()
def _update_acc_number(self):
"""Compute value for field acc_number
based on an postal account or ISR subscription number"""
part_name = self.partner_id.name
if not part_name and self.env.context.get("default_partner_id"):
partner_id = self.env.context.get("default_partner_id")
part_name = self.env["res.partner"].browse(partner_id)[0].name
self.acc_number = self._compute_name_from_postal_number(
part_name, self.l10n_ch_postal
)
@api.model
def _compute_name_from_postal_number(self, partner_name, postal_number):
"""This method makes sure to generate a unique name"""
if postal_number and postal_number[:2] in ["01", "03"]:
if partner_name:
acc_name = _("ISR {} {}").format(postal_number, partner_name)
else:
acc_name = _("ISR {}").format(postal_number)
else:
return postal_number
exist_count = self.env["res.partner.bank"].search_count(
[("acc_number", "=like", acc_name)]
)
# if acc_number not unique iterate on bank_accounts while not get
# unique number
if exist_count:
name_exist = exist_count
while name_exist:
new_name = acc_name + " #{}".format(exist_count)
name_exist = self.env["res.partner.bank"].search_count(
[("acc_number", "=", new_name)]
)
exist_count += 1
acc_name = new_name
return acc_name
@api.model
def create(self, vals):
"""
acc_number is mandatory for model, but in localization it could be not
mandatory when we have postal number, so we compute acc_number in
onchange methods and check it here also
"""
if not vals.get("acc_number") and vals.get("l10n_ch_postal"):
partner = self.env["res.partner"].browse(vals.get("partner_id"))
vals["acc_number"] = self._compute_name_from_postal_number(
partner.name, vals["l10n_ch_postal"]
)
return super().create(vals)