Functional Weave
Code in Rust

charity.payroll-giving@1.0.0

impl/typescript.ts

1,792 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 { incomeTax } from "./payroll_income_tax.ts";  ← from payroll.income-tax ^1.0.0 · built alongside by fune
import { type PayFrequency } from "./payroll_tax_period_types.ts";
import { type PayrollGiving } from "./charity_payroll_giving_types.ts";

/**
 * Payroll Giving (ITEPA 2003 s713): the donation is deducted from pay before
 * PAYE is worked out, so the relief is whatever PAYE the lower pay saves, by
 * the same tax table routines the payroll uses. That is not simply the
 * donation times the marginal rate: PAYE rounds taxable pay down to whole
 * pounds, so a 50p donation can save nothing and a £5 one exactly £1.
 */
export function payrollGiving(
  taxCode: string,
  frequency: PayFrequency,
  period: number,
  pay: Money,
  donation: Money,
  previousPayToDate: Money,
  previousTaxToDate: Money,
  payDate: string
): PayrollGiving {
  if (donation.currency !== "GBP") {
    throw new RangeError(`payroll amounts must be in GBP, received ${donation.currency} for donation`);
  }
  if (donation.minor < 0) throw new RangeError(`donation must not be negative, received ${donation.minor}`);
  if (donation.minor > pay.minor) {
    throw new RangeError(`donation of ${donation.minor} is more than pay of ${pay.minor}`);
  }
  const taxablePay = money(pay.minor - donation.minor, "GBP");
  const without = incomeTax(taxCode, frequency, period, pay, previousPayToDate, previousTaxToDate, payDate).tax.minor;
  const withGiving = incomeTax(taxCode, frequency, period, taxablePay, previousPayToDate, previousTaxToDate, payDate).tax.minor;
  return {
    taxablePay,
    taxWithoutGiving: money(without, "GBP"),
    taxWithGiving: money(withGiving, "GBP"),
    taxSaved: money(without - withGiving, "GBP"),
    netCost: money(donation.minor - (without - withGiving), "GBP"),
  };
}