88 lines
2.9 KiB
Python
88 lines
2.9 KiB
Python
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
import logging
|
|
from datetime import timedelta
|
|
|
|
from odoo import fields, models
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ResPartner(models.Model):
|
|
_inherit = "res.partner"
|
|
|
|
membership_expiry_reminder_sent = fields.Boolean(
|
|
string="Expiry Reminder Sent",
|
|
default=False,
|
|
copy=False,
|
|
help="Checked when the membership renewal reminder email has been sent "
|
|
"for the current membership period. Reset automatically when the "
|
|
"membership is renewed.",
|
|
)
|
|
|
|
def _cron_send_membership_expiry_reminders(self):
|
|
"""Daily cron: find members whose membership expires within the next N days
|
|
and who have not yet received a reminder. This catches up on any members
|
|
that were missed on previous runs."""
|
|
days = int(
|
|
self.env["ir.config_parameter"]
|
|
.sudo()
|
|
.get_param("membership_expiry_reminder.days_before_expiry", 30)
|
|
)
|
|
if not days:
|
|
_logger.info(
|
|
"membership_expiry_reminder: disabled (days_before_expiry = 0)"
|
|
)
|
|
return
|
|
|
|
template = self.env.ref(
|
|
"membership_expiry_reminder.email_template_membership_expiry",
|
|
raise_if_not_found=False,
|
|
)
|
|
if not template:
|
|
_logger.warning(
|
|
"membership_expiry_reminder: email template not found, skipping."
|
|
)
|
|
return
|
|
|
|
today = fields.Date.today()
|
|
deadline = today + timedelta(days=days)
|
|
|
|
partners = self.search(
|
|
[
|
|
("membership_state", "=", "paid"),
|
|
("membership_stop", ">=", today),
|
|
("membership_stop", "<=", deadline),
|
|
("membership_expiry_reminder_sent", "=", False),
|
|
("email", "!=", False),
|
|
]
|
|
)
|
|
|
|
_logger.info(
|
|
"membership_expiry_reminder: sending reminders to %d partner(s) "
|
|
"(expiry between today and %s, i.e. within %d days)",
|
|
len(partners),
|
|
deadline,
|
|
days,
|
|
)
|
|
|
|
for partner in partners:
|
|
try:
|
|
template.send_mail(partner.id, force_send=True)
|
|
partner.membership_expiry_reminder_sent = True
|
|
except Exception:
|
|
_logger.exception(
|
|
"membership_expiry_reminder: failed to send email to partner %d (%s)",
|
|
partner.id,
|
|
partner.email,
|
|
)
|
|
|
|
def write(self, vals):
|
|
# Reset the reminder flag when the membership is renewed
|
|
# (i.e., when member_lines changes, which updates membership_stop)
|
|
result = super().write(vals)
|
|
if "membership_stop" in vals:
|
|
self.filtered("membership_expiry_reminder_sent").write(
|
|
{"membership_expiry_reminder_sent": False}
|
|
)
|
|
return result
|