mirror of
https://gitlab.com/flectra-community/bank-payment.git
synced 2024-11-22 13:42:07 +00:00
154 lines
5.5 KiB
Python
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,
|
|
}
|