Functional Weave
Code in Python

finance.tax.vat-rate@1.2.2

impl/python.py

3,155 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.

import re
from typing import List, Optional

from .finance_tax_vat_rate_data import VAT_RULES, VAT_RULES_HISTORY  ← this capability’s own data, compiled from data/vat-rules.json into the same file by fune build
from .finance_tax_vat_rate_types import VatRate


ISO_DATE = re.compile(r"[0-9]{4}-[0-9]{2}-[0-9]{2}")


def vat_rate(jurisdiction: str, category: str, on_date: str) -> VatRate:
    """The VAT rate in force for a jurisdiction and category on a given date.

    The date matters. A credit note against a 2009 invoice has to use the rate
    that applied in 2009, not the one that applies today, and a system that
    hardcodes 0.20 cannot do that at all.

    ISO dates compare correctly as strings, so this needs no date library.
    """
    if not isinstance(on_date, str) or not ISO_DATE.fullmatch(on_date):
        raise ValueError('onDate must be an ISO date (YYYY-MM-DD), received "%s"' % (on_date,))

    best: Optional[VatRate] = None
    for rule in VAT_RULES:
        if rule.jurisdiction != jurisdiction or rule.category != category:
            continue
        if on_date < rule.valid_from:
            continue
        if rule.valid_to is not None and on_date > rule.valid_to:
            continue
        if best is None or rule.valid_from > best.valid_from:
            best = VatRate(
                jurisdiction=rule.jurisdiction,
                category=rule.category,
                basis_points=rule.basis_points,
                valid_from=rule.valid_from,
                valid_to=rule.valid_to,
            )

    if best is None:
        # A build installed with history=current carries only the rules still in
        # force. Answering an older date with today's rate would be the exact
        # failure this capability exists to prevent, so say what happened instead.
        # The horizon that matters is this jurisdiction and category's own
        # earliest surviving rule, not the registry-wide one.
        if VAT_RULES_HISTORY != "full":
            earliest = None
            for rule in VAT_RULES:
                if rule.jurisdiction != jurisdiction or rule.category != category:
                    continue
                if earliest is None or rule.valid_from < earliest:
                    earliest = rule.valid_from
            if earliest is not None and on_date < earliest:
                raise ValueError(
                    "no VAT rule for %s/%s on %s: this build was installed with history=%s, "
                    "so it only carries rules from %s. Reinstall with history=full to reprint older invoices."
                    % (jurisdiction, category, on_date, VAT_RULES_HISTORY, earliest)
                )
        raise ValueError("no VAT rule for %s/%s on %s" % (jurisdiction, category, on_date))
    return best


def vat_categories(jurisdiction: str, on_date: str) -> List[str]:
    """Every category this registry knows a rate for, for a jurisdiction and date."""
    seen = set()
    for rule in VAT_RULES:
        if rule.jurisdiction != jurisdiction:
            continue
        if on_date < rule.valid_from:
            continue
        if rule.valid_to is not None and on_date > rule.valid_to:
            continue
        seen.add(rule.category)
    return sorted(seen)