Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::money_amount::{money, money_from_value, money_to_value, Money}; ← from money.amount ^1.0.0 · built alongside by fune
use super::payroll_income_tax::income_tax; ← from payroll.income-tax ^1.0.0 · built alongside by fune
/// 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.
///
/// # Panics
/// Panics on a non-GBP or negative donation, a donation above pay, and
/// anything payroll.income-tax refuses.
pub fn payroll_giving(
tax_code: &str,
frequency: &str,
period: i64,
pay: &Money,
donation: &Money,
previous_pay_to_date: &Money,
previous_tax_to_date: &Money,
pay_date: &str,
) -> PayrollGiving {
if donation.currency != "GBP" {
panic!("payroll amounts must be in GBP, received {} for donation", donation.currency);
}
if donation.minor < 0 {
panic!("donation must not be negative, received {}", donation.minor);
}
if donation.minor > pay.minor {
panic!("donation of {} is more than pay of {}", donation.minor, pay.minor);
}
let taxable_pay = money(pay.minor - donation.minor, "GBP");
let without = income_tax(tax_code, frequency, period, pay, previous_pay_to_date, previous_tax_to_date, pay_date).tax.minor;
let with_giving =
income_tax(tax_code, frequency, period, &taxable_pay, previous_pay_to_date, previous_tax_to_date, pay_date).tax.minor;
PayrollGiving {
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"),
}
}
pub fn payroll_giving_to_value(g: &PayrollGiving) -> Value {
Value::obj(vec![
("taxablePay", money_to_value(&g.taxable_pay)),
("taxWithoutGiving", money_to_value(&g.tax_without_giving)),
("taxWithGiving", money_to_value(&g.tax_with_giving)),
("taxSaved", money_to_value(&g.tax_saved)),
("netCost", money_to_value(&g.net_cost)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
if let Value::Float(_) = args[2] {
panic!("period {} is not a tax period for {} pay", args[2].as_f64(), args[1].as_str());
}
payroll_giving_to_value(&payroll_giving(
args[0].as_str(),
args[1].as_str(),
args[2].as_i64(),
&money_from_value(&args[3]),
&money_from_value(&args[4]),
&money_from_value(&args[5]),
&money_from_value(&args[6]),
args[7].as_str(),
))
}