Functional Weave
Code in Rust

retail.oss-vat@1.0.1

impl/python.py

4,075 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 .money_amount import Money, money  ← from money.amount ^1.0.0 · built alongside by fune
from .money_apply_rate import apply_rate  ← from money.apply-rate ^1.0.0 · built alongside by fune
from .retail_oss_vat_data import OSS_RULES, OSS_RULES_HISTORY  ← this capability’s own data, compiled from data/oss-rules.json into the same file by fune build
from .retail_oss_vat_types import OssVat

_ISO_DATE = re.compile(r"[0-9]{4}-[0-9]{2}-[0-9]{2}")
_COUNTRY = re.compile(r"[A-Z]{2}")


def _country(code: str, name: str) -> str:
    # The EU writes Greece as EL in VAT matters; ISO 3166 says GR. Accept both.
    if not isinstance(code, str) or not _COUNTRY.fullmatch(code):
        raise ValueError('%s must be an ISO 3166-1 alpha-2 code, received "%s"' % (name, code))
    return "GR" if code == "EL" else code


def _is_member(code: str) -> bool:
    return any(r.rule == "standard-rate" and r.country == code for r in OSS_RULES)


def _lookup(rule: str, where: str, on_date: str) -> int:
    best = None
    for r in OSS_RULES:
        if r.rule != rule or r.country != where:
            continue
        if on_date < r.valid_from or (r.valid_to is not None and on_date > r.valid_to):
            continue
        if best is None or r.valid_from > best.valid_from:
            best = r
    if best is not None:
        return best.value
    # A history=current build carries only the rules still in force; answering
    # an older date with today's rate is the failure the dates exist to prevent.
    if OSS_RULES_HISTORY != "full":
        earliest = None
        for r in OSS_RULES:
            if r.rule == rule and r.country == where and (earliest is None or r.valid_from < earliest):
                earliest = r.valid_from
        if earliest is not None and on_date < earliest:
            raise ValueError(
                'no OSS rule "%s" for %s on %s: this build was installed with history=%s, '
                "so it only carries rules from %s. Reinstall with history=full for older supplies."
                % (rule, where, on_date, OSS_RULES_HISTORY, earliest)
            )
    raise ValueError('no OSS rule "%s" for %s on %s' % (rule, where, on_date))


def oss_vat(
    net: Money,
    seller_country: str,
    customer_country: str,
    eu_sales_previous_year: Money,
    eu_sales_this_year: Money,
    opted_in: bool,
    on_date: str,
) -> OssVat:
    """VAT on a business-to-consumer sale to another EU member state: the
    seller's own rate while its cross-border sales stay within EUR 10,000 (and
    it has not opted in), the customer's state's rate through the One Stop Shop
    once they exceed it, and always the customer's for sellers outside the EU.
    """
    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,))
    seller = _country(seller_country, "sellerCountry")
    customer = _country(customer_country, "customerCountry")
    if not _is_member(customer):
        raise ValueError('customer country "%s" is not an EU member state' % customer_country)
    for name, amount in (("euSalesPreviousYear", eu_sales_previous_year), ("euSalesThisYear", eu_sales_this_year)):
        if amount.currency != "EUR":
            raise ValueError("%s must be in EUR, received %s" % (name, amount.currency))
        if amount.minor < 0:
            raise ValueError("%s must not be negative, received %d" % (name, amount.minor))

    threshold = _lookup("distance-selling-threshold", "EU", on_date)
    threshold_exceeded = eu_sales_previous_year.minor > threshold or eu_sales_this_year.minor > threshold

    if seller == customer:
        scheme, tax_country = "domestic", customer
    elif _is_member(seller) and not threshold_exceeded and not opted_in:
        scheme, tax_country = "origin", seller
    else:
        scheme, tax_country = "oss", customer

    basis_points = _lookup("standard-rate", tax_country, on_date)
    vat = apply_rate(net, basis_points, "half-up")
    return OssVat(
        tax_country=tax_country,
        scheme=scheme,
        basis_points=basis_points,
        threshold_exceeded=threshold_exceeded,
        net=net,
        vat=vat,
        gross=money(net.minor + vat.minor, net.currency),
    )