Functional Weave
Code in Rust

charity.payroll-giving@1.0.0

impl/python.py

1,740 bytes · the Python 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.

from .charity_payroll_giving_types import PayrollGiving
from .money_amount import Money, money  ← from money.amount ^1.0.0 · built alongside by fune
from .payroll_income_tax import income_tax  ← from payroll.income-tax ^1.0.0 · built alongside by fune
from .payroll_tax_period_types import PayFrequency


def payroll_giving(
    tax_code: str,
    frequency: PayFrequency,
    period: int,
    pay: Money,
    donation: Money,
    previous_pay_to_date: Money,
    previous_tax_to_date: Money,
    pay_date: str,
) -> PayrollGiving:
    """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. PAYE rounds
    taxable pay down to whole pounds, so a 50p donation can save nothing.
    """
    if donation.currency != "GBP":
        raise ValueError("payroll amounts must be in GBP, received %s for donation" % (donation.currency,))
    if donation.minor < 0:
        raise ValueError("donation must not be negative, received %d" % (donation.minor,))
    if donation.minor > pay.minor:
        raise ValueError("donation of %d is more than pay of %d" % (donation.minor, pay.minor))
    taxable_pay = money(pay.minor - donation.minor, "GBP")
    without = income_tax(tax_code, frequency, period, pay, previous_pay_to_date, previous_tax_to_date, pay_date).tax.minor
    with_giving = income_tax(
        tax_code, frequency, period, taxable_pay, previous_pay_to_date, previous_tax_to_date, pay_date
    ).tax.minor
    return PayrollGiving(
        taxable_pay=taxable_pay,
        tax_without_giving=money(without, "GBP"),
        tax_with_giving=money(with_giving, "GBP"),
        tax_saved=money(without - with_giving, "GBP"),
        net_cost=money(donation.minor - (without - with_giving), "GBP"),
    )