# 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