Functional Weave
Code in TypeScript

energy.climate-change-levy@1.0.2

impl/typescript.ts

2,824 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 { type RoundingMode, roundDiv } from "./math_round_div.ts";  ← from math.round-div ^1.0.0 · built alongside by fune
import { money } from "./money_amount.ts";  ← from money.amount ^1.0.0 · built alongside by fune
import { CCL_RATES, CCL_RATES_HISTORY } from "./energy_climate_change_levy_data.ts";  ← this capability’s own data, compiled from data/ccl-rates.json into the same file by fune build
import { type ClimateChangeLevy, type CclCommodity } from "./energy_climate_change_levy_types.ts";

const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
// quantity (thousandths of a unit) x rate (thousandths of a penny) is in
// millionths of a penny.
const DIVISOR = 1_000_000;

/**
 * The Climate Change Levy on one supply, at the main rate in force on
 * `onDate`. A qualifying-use supply (domestic, charity non-business or
 * de minimis) is outside the levy and comes back excluded, with a zero levy.
 */
export function climateChangeLevy(
  commodity: CclCommodity,
  quantity: number,
  onDate: string,
  qualifyingUse: boolean,
  mode: RoundingMode
): ClimateChangeLevy {
  if (!ISO_DATE.test(onDate)) {
    throw new RangeError(`onDate must be an ISO date (YYYY-MM-DD), received "${onDate}"`);
  }
  if (!Number.isInteger(quantity) || quantity < 0) {
    throw new RangeError(`quantity must be a whole number of thousandths of a unit, 0 or more, received ${quantity}`);
  }
  if (!CCL_RATES.some((r) => r.commodity === commodity)) {
    throw new RangeError(`unknown commodity "${commodity}": expected electricity, gas, lpg or other`);
  }
  let best: (typeof CCL_RATES)[number] | null = null;
  for (const r of CCL_RATES) {
    if (r.commodity !== commodity || onDate < r.validFrom) continue;
    if (r.validTo !== null && onDate > r.validTo) continue;
    if (best === null || r.validFrom > best.validFrom) best = r;
  }
  if (best === null) {
    // A pruned build must not answer an old date with a newer rate.
    if (CCL_RATES_HISTORY !== "full") {
      let earliest: string | null = null;
      for (const r of CCL_RATES) {
        if (r.commodity === commodity && (earliest === null || r.validFrom < earliest)) earliest = r.validFrom;
      }
      if (earliest !== null && onDate < earliest) {
        throw new RangeError(
          `no Climate Change Levy rate for ${commodity} on ${onDate}: this build was installed with history=${CCL_RATES_HISTORY}, ` +
            `so it only carries rates from ${earliest}. Reinstall with history=full for older supplies.`
        );
      }
    }
    throw new RangeError(`no Climate Change Levy rate for ${commodity} on ${onDate}`);
  }
  let pence = 0;
  if (!qualifyingUse) {
    const product = quantity * best.rate;
    if (product > Number.MAX_SAFE_INTEGER) {
      throw new RangeError("levy too large to calculate exactly");
    }
    pence = roundDiv(product, DIVISOR, mode);
  }
  return {
    commodity,
    unit: best.unit,
    rate: best.rate,
    excluded: qualifyingUse,
    levy: money(pence, "GBP"),
    validFrom: best.validFrom,
    validTo: best.validTo,
  };
}