addons-cm/membership_expiry_reminder/models/res_partner.py

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