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::dates_add_days::{days_between, parse_iso_date}; ← from dates.add-days ^1.0.0 · built alongside by fune
use super::dates_uk_tax_year::uk_tax_year; ← from dates.uk-tax-year ^1.0.0 · built alongside by fune
/// The tax week, tax month and payroll period a pay date falls in.
///
/// The tax year is 365 or 366 days, which is 52 weeks and one or two days over.
/// Those spare days are week 53, and they are the reason `period` exists: HMRC
/// numbers the extra payday 53, 54 or 56 by frequency and taxes it
/// non-cumulatively, so a payroll that just counts weeks gets it wrong.
///
/// # Panics
/// Panics on a malformed date or an unknown frequency.
pub fn tax_period(pay_date: &str, frequency: &str) -> TaxPeriod {
if !matches!(frequency, "weekly" | "fortnightly" | "four-weekly" | "monthly") {
panic!("unknown pay frequency \"{}\"", frequency);
}
let year = uk_tax_year(pay_date);
let week = days_between(&year.start, pay_date) / 7 + 1;
// Tax months run from the 6th to the 5th, so the calendar month moves on
// five days before the tax month does.
let date = parse_iso_date(pay_date);
let mut month = if date.day >= 6 { date.month - 3 } else { date.month - 4 };
if month <= 0 {
month += 12;
}
let period = if frequency == "monthly" {
month
} else if week < 53 {
week
} else {
match frequency {
"weekly" => 53,
"fortnightly" => 54,
_ => 56,
}
};
TaxPeriod {
tax_year: year.label,
tax_year_start: year.start,
week,
month,
period,
}
}
pub fn tax_period_to_value(p: &TaxPeriod) -> Value {
Value::obj(vec![
("taxYear", Value::str(&p.tax_year)),
("taxYearStart", Value::str(&p.tax_year_start)),
("week", Value::Int(p.week)),
("month", Value::Int(p.month)),
("period", Value::Int(p.period)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
tax_period_to_value(&tax_period(args[0].as_str(), args[1].as_str()))
}