impl/typescript.ts
1,368 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 Money, money } from "./money_amount.ts"; ← from money.amount ^1.0.0 · built alongside by fune
import { type RetainerApplication, type RetainerBill, type RetainerDrawdown } from "./legal_retainer_drawdown_types.ts";
/** Apply money on account to bills in the order given. */
export function retainerDrawdown(onAccount: Money, bills: readonly RetainerBill[]): RetainerDrawdown {
const currency = onAccount.currency;
if (onAccount.minor < 0) {
throw new RangeError(`onAccount must not be negative, received ${onAccount.minor}`);
}
let left = onAccount.minor;
let applied = 0;
let outstanding = 0;
const lines: RetainerApplication[] = [];
for (const bill of bills) {
if (bill.amount.currency !== currency) {
throw new RangeError(`currency mismatch: ${currency} and ${bill.amount.currency}`);
}
if (bill.amount.minor < 0) {
throw new RangeError(`bill "${bill.reference}" must not be negative, received ${bill.amount.minor}`);
}
const take = Math.min(left, bill.amount.minor);
left -= take;
applied += take;
outstanding += bill.amount.minor - take;
lines.push({ reference: bill.reference, billed: bill.amount, applied: money(take, currency), outstanding: money(bill.amount.minor - take, currency) });
}
return { bills: lines, applied: money(applied, currency), outstanding: money(outstanding, currency), balance: money(left, currency) };
}