Functional Weave
Code in Python

legal.limitation-date@1.0.1

impl/python.py

2,225 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

from typing import Optional

from .dates_add_days import parse_iso_date  ← from dates.add-days ^1.0.0 · built alongside by fune
from .dates_add_months import add_months  ← from dates.add-months ^1.0.0 · built alongside by fune
from .legal_limitation_date_data import LIMITATION_PERIODS, LIMITATION_PERIODS_HISTORY  ← this capability’s own data, compiled from data/limitation-periods.json into the same file by fune build
from .legal_limitation_date_types import LimitationPeriod


def limitation_date(claim_type: str, accrual_date: str, knowledge_date: Optional[str]) -> LimitationPeriod:
    """The last day to bring a claim: the anniversary of the accrual date (or the
    later date of knowledge) the period's number of years on, the accrual day
    itself excluded, and the month's last day where no anniversary exists.
    """
    parse_iso_date(accrual_date)
    rows = [r for r in LIMITATION_PERIODS if r.claim_type == claim_type]
    if not rows:
        known = ", ".join(dict.fromkeys(r.claim_type for r in LIMITATION_PERIODS))
        raise ValueError('unknown claim type "%s": expected one of %s' % (claim_type, known))
    rule = next(
        (r for r in rows if accrual_date >= r.valid_from and (r.valid_to is None or accrual_date <= r.valid_to)),
        None,
    )
    if rule is None:
        earliest = min(r.valid_from for r in rows)
        if LIMITATION_PERIODS_HISTORY != "full" and accrual_date < earliest:
            raise ValueError(
                "no limitation rule for %s accruing on %s: this build was installed with history=%s, so it only carries rules from %s. "
                "Reinstall with history=full for older claims." % (claim_type, accrual_date, LIMITATION_PERIODS_HISTORY, earliest)
            )
        raise ValueError("no limitation rule for %s accruing on %s" % (claim_type, accrual_date))
    runs_from = accrual_date
    if knowledge_date is not None:
        if not rule.from_knowledge:
            raise ValueError("a %s claim runs from accrual under %s; knowledgeDate must be null" % (claim_type, rule.section))
        parse_iso_date(knowledge_date)
        if knowledge_date > accrual_date:
            runs_from = knowledge_date
    # The corresponding date rule: the anniversary, clamped to the month end.
    expiry = add_months(runs_from, rule.years * 12)
    return LimitationPeriod(claim_type=claim_type, years=rule.years, section=rule.section, runs_from=runs_from, expiry=expiry)