bank-payment/account_banking_sepa_direct_debit/models/account_banking_mandate.py
2024-05-03 10:36:50 +02:00

154 lines
5.5 KiB
Python

# Copyright 2020 Akretion - Alexis de Lattre
# Copyright 2014 Tecnativa - Pedro M. Baeza
# Copyright 2024 Tecnativa - Carolina Fernandez
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import logging
from datetime import datetime
from dateutil.relativedelta import relativedelta
from flectra import _, api, fields, models
from flectra.exceptions import UserError
NUMBER_OF_UNUSED_MONTHS_BEFORE_EXPIRY = 36
logger = logging.getLogger(__name__)
class AccountBankingMandate(models.Model):
"""SEPA Direct Debit Mandate"""
_inherit = "account.banking.mandate"
_rec_name = "display_name"
format = fields.Selection(
selection_add=[("sepa", "Sepa Mandate")],
default="sepa",
ondelete={"sepa": "set default"},
)
type = fields.Selection(
selection_add=[("recurrent", "Recurrent"), ("oneoff", "One-Off")],
default="recurrent",
ondelete={"recurrent": "set null", "oneoff": "set null"},
)
recurrent_sequence_type = fields.Selection(
[("first", "First"), ("recurring", "Recurring"), ("final", "Final")],
string="Sequence Type for Next Debit",
tracking=70,
help="This field is only used for Recurrent mandates, not for "
"One-Off mandates.",
default="first",
)
scheme = fields.Selection(
[("CORE", "Basic (CORE)"), ("B2B", "Enterprise (B2B)")],
default="CORE",
tracking=80,
)
unique_mandate_reference = fields.Char(size=35) # cf ISO 20022
display_name = fields.Char(compute="_compute_display_name2", store=True)
is_sent = fields.Boolean()
@api.constrains("type", "recurrent_sequence_type")
def _check_recurring_type(self):
for mandate in self:
if mandate.type == "recurrent" and not mandate.recurrent_sequence_type:
raise UserError(
_("The recurrent mandate '%s' must have a sequence type.")
% mandate.unique_mandate_reference
)
@api.depends("unique_mandate_reference", "recurrent_sequence_type")
def _compute_display_name2(self):
for mandate in self:
if mandate.format == "sepa":
mandate.display_name = "{} ({})".format(
mandate.unique_mandate_reference, mandate.recurrent_sequence_type
)
else:
mandate.display_name = mandate.unique_mandate_reference
@api.onchange("partner_bank_id")
def mandate_partner_bank_change(self):
super().mandate_partner_bank_change()
res = {}
if (
self.state == "valid"
and self.partner_bank_id
and self.type == "recurrent"
and self.recurrent_sequence_type != "first"
):
self.recurrent_sequence_type = "first"
res["warning"] = {
"title": _("Mandate update"),
"message": _(
"As you changed the bank account attached "
"to this mandate, the 'Sequence Type' has "
"been set back to 'First'."
),
}
return res
def _sdd_mandate_set_state_to_expired(self):
logger.info("Searching for SDD Mandates that must be set to Expired")
expire_limit_date = datetime.today() + relativedelta(
months=-NUMBER_OF_UNUSED_MONTHS_BEFORE_EXPIRY
)
expired_mandates = self.search(
[
"|",
("last_debit_date", "=", False),
("last_debit_date", "<=", expire_limit_date),
("state", "=", "valid"),
("signature_date", "<=", expire_limit_date),
]
)
if expired_mandates:
expired_mandates.write({"state": "expired"})
for mandate in expired_mandates:
mandate.message_post(
body=_(
"Mandate automatically set to"
" expired after %d months without use."
)
% NUMBER_OF_UNUSED_MONTHS_BEFORE_EXPIRY
)
logger.info(
"%d SDD Mandate set to expired: IDs %s"
% (len(expired_mandates), expired_mandates.ids)
)
else:
logger.info("0 SDD Mandates had to be set to Expired")
def print_report(self):
self.ensure_one()
xmlid = "account_banking_sepa_direct_debit.report_sepa_direct_debit_mandate"
action = self.env.ref(xmlid).report_action(self)
return action
def action_mandate_send(self):
"""Opens a wizard to compose an email,
with relevant mail template loaded by default"""
self.ensure_one()
template_id = self.env["ir.model.data"]._xmlid_to_res_id(
"account_banking_sepa_direct_debit.email_template_sepa_mandate",
raise_if_not_found=False,
)
ctx = {
"default_model": "account.banking.mandate",
"default_res_ids": self.ids,
"default_use_template": bool(template_id),
"default_template_id": template_id,
"default_composition_mode": "comment",
"is_sent": True,
"force_email": True,
}
return {
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "mail.compose.message",
"views": [(False, "form")],
"view_id": False,
"target": "new",
"context": ctx,
}