from ccma.domain.dates import DateValidationError, parse_iso_date from ccma.rules.api import RuleContext, task from ccma.rules.scripts._shared import relative_title RULE_ID = "membership-anniversary" ORDER = 30 def evaluate(context: RuleContext): member = context.member if member.status == "ended": return [] try: started_at = parse_iso_date(member.membership_started_at, "Mitglied seit") except DateValidationError: return [] if not started_at: return [] actions = [] for interval in context.settings.anniversary_intervals: try: target = interval.target_date(started_at) except (OverflowError, ValueError): continue delta = (target - context.today).days if ( delta > context.settings.anniversary_days_before or delta < -context.settings.anniversary_days_after ): continue occasion = _anniversary_name(interval) actions.append( task( rule_id=RULE_ID, member=member, key_suffix=f"{interval.value}{interval.unit}", severity="info", title=relative_title(member.display_name, delta, occasion), detail=f"Mitglied seit {started_at:%d.%m.%Y}.", due_date=target, code="membership_anniversary", ) ) return actions def _anniversary_name(interval): if interval.unit == "D": return f"{interval.value}-Tage-Mitgliedsjubiläum" if interval.unit == "M": return f"{interval.value}-Monats-Mitgliedsjubiläum" return f"{interval.value}-jähriges Mitgliedsjubiläum"