Functional Weave
Code in Rust

finance.tax.vat-rate@1.1.0

impl/typescript.ts

2,902 bytes · the TypeScript 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 { VAT_RULES, VAT_RULES_HISTORY } from "./finance_tax_vat_rate_data.ts";  ← this capability’s own data, compiled from data/vat-rules.json into the same file by fune build
import { type VatRate } from "./finance_tax_vat_rate_types.ts";

const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;

/**
 * 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.
 */
export function vatRate(jurisdiction: string, category: string, onDate: string): VatRate {
  if (!ISO_DATE.test(onDate)) {
    throw new RangeError(`onDate must be an ISO date (YYYY-MM-DD), received "${onDate}"`);
  }

  let best: VatRate | null = null;
  for (const rule of VAT_RULES) {
    if (rule.jurisdiction !== jurisdiction || rule.category !== category) continue;
    if (onDate < rule.validFrom) continue;
    if (rule.validTo !== null && onDate > rule.validTo) continue;
    if (best === null || rule.validFrom > best.validFrom) {
      best = {
        jurisdiction: rule.jurisdiction,
        category: rule.category,
        basisPoints: rule.basisPoints,
        validFrom: rule.validFrom,
        validTo: rule.validTo,
      };
    }
  }

  if (best === null) {
    // 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") {
      let earliest: string | null = null;
      for (const rule of VAT_RULES) {
        if (rule.jurisdiction !== jurisdiction || rule.category !== category) continue;
        if (earliest === null || rule.validFrom < earliest) earliest = rule.validFrom;
      }
      if (earliest !== null && onDate < earliest) {
        throw new RangeError(
          `no VAT rule for ${jurisdiction}/${category} on ${onDate}: this build was installed with history=${VAT_RULES_HISTORY}, ` +
            `so it only carries rules from ${earliest}. Reinstall with history=full to reprint older invoices.`
        );
      }
    }
    throw new RangeError(`no VAT rule for ${jurisdiction}/${category} on ${onDate}`);
  }
  return best;
}

/** Every category this registry knows a rate for, for a jurisdiction and date. */
export function vatCategories(jurisdiction: string, onDate: string): string[] {
  const seen = new Set<string>();
  for (const rule of VAT_RULES) {
    if (rule.jurisdiction !== jurisdiction) continue;
    if (onDate < rule.validFrom) continue;
    if (rule.validTo !== null && onDate > rule.validTo) continue;
    seen.add(rule.category);
  }
  return [...seen].sort();
}