Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
import { type Money, money } from "./money_amount.ts"; ← from money.amount ^1.0.0 · built alongside by fune
import { applyRate } from "./money_apply_rate.ts"; ← from money.apply-rate ^1.0.0 · built alongside by fune
import { ISSUE_FEES, ISSUE_FEES_HISTORY } from "./legal_court_fee_data.ts"; ← this capability’s own data, compiled from data/issue-fees.json into the same file by fune build
import { type FilingChannel } from "./legal_court_fee_types.ts";
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
/** The fee to issue a money claim, from the bands in force on the issue date. */
export function courtFee(claim: Money, channel: FilingChannel, onDate: string): Money {
if (claim.currency !== "GBP") {
throw new RangeError(`court fees are set for claims in GBP, received ${claim.currency}`);
}
if (claim.minor <= 0) {
throw new RangeError("claim must be greater than zero");
}
if (channel !== "paper" && channel !== "online") {
throw new RangeError(`unknown filing channel "${channel}": expected paper or online`);
}
if (!ISO_DATE.test(onDate)) {
throw new RangeError(`onDate must be an ISO date (YYYY-MM-DD), received "${onDate}"`);
}
let inForce = 0;
let earliest: string | null = null;
for (const row of ISSUE_FEES) {
if (row.channel !== channel) continue;
if (earliest === null || row.validFrom < earliest) earliest = row.validFrom;
if (onDate < row.validFrom || (row.validTo !== null && onDate > row.validTo)) continue;
inForce += 1;
if (claim.minor <= row.overMinor || (row.upToMinor !== null && claim.minor > row.upToMinor)) continue;
if (row.feeMinor !== null) return money(row.feeMinor, "GBP");
// gov.uk: "round down the result to the nearest 1 pence".
return applyRate(claim, row.basisPoints as number, "down");
}
if (inForce > 0) {
throw new RangeError(`a claim of ${claim.minor} pence cannot be issued ${channel} on ${onDate}: online claims are limited to GBP 100,000`);
}
if (ISSUE_FEES_HISTORY !== "full" && earliest !== null && onDate < earliest) {
throw new RangeError(
`no ${channel} court fee on ${onDate}: this build was installed with history=${ISSUE_FEES_HISTORY}, so it only carries fees from ${earliest}. Reinstall with history=full for older claims.`,
);
}
throw new RangeError(`no ${channel} court fee in force on ${onDate}`);
}