use super::funejson::Value; use super::finance_tax_vat_rate::vat_rate; use super::money_add::add_money; use super::money_amount::{money_from_value, money_to_value, Money}; use super::money_apply_rate::apply_rate; /// Add VAT to a net amount at the rate in force on the date of supply. /// /// Returns the whole breakdown rather than just the tax: an invoice needs net, /// tax and gross together, and deriving the third from the other two in caller /// code is where rounding bugs are born. pub fn add_vat(net: &Money, jurisdiction: &str, category: &str, on_date: &str) -> VatBreakdown { let rate = vat_rate(jurisdiction, category, on_date); let tax = apply_rate(net, rate.basis_points, "half-up"); VatBreakdown { net: net.clone(), gross: add_money(net, &tax), tax, basis_points: rate.basis_points, } } pub fn vat_breakdown_to_value(breakdown: &VatBreakdown) -> Value { Value::obj(vec![ ("net", money_to_value(&breakdown.net)), ("tax", money_to_value(&breakdown.tax)), ("gross", money_to_value(&breakdown.gross)), ("basisPoints", Value::Int(breakdown.basis_points)), ]) } pub fn fune_vector(args: &[Value]) -> Value { vat_breakdown_to_value(&add_vat( &money_from_value(&args[0]), args[1].as_str(), args[2].as_str(), args[3].as_str(), )) }