mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-08-24 22:45:18 +02:00
An overdue claim whose reminder had already been sent, with that reminder's own payment deadline still running, fell through to the plain "überfällig" error finding whenever reminder_due's escalation check returned None to signal "not yet time for the next Mahnstufe" -- that None was indistinguishable from "never handled at all" to the caller, so it looked neglected even though a reminder was already out. Give that case its own low-priority "reminder_awaiting_deadline" finding instead of silently falling back to the overdue-error path. Birthday and membership-anniversary findings also kept firing for members whose status is "ended", which doesn't make sense once the membership itself is over. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
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"
|