use super::funejson::Value; use super::finance_tax_add_vat::{vat_breakdown_to_value, VatBreakdown}; use super::finance_tax_vat_rate::vat_rate; use super::math_round_div::round_div; use super::money_amount::{money, money_from_value, Money}; /// Extract the VAT already included in a gross amount. /// /// Taking 20% off a gross price is the classic error: the VAT inside a 120.00 /// gross price is 20.00, not 24.00. The net is gross x 10000 / (10000 + rate), /// and the tax is the remainder, so the parts always add back to exactly the /// gross with no stray penny. pub fn remove_vat( gross: &Money, jurisdiction: &str, category: &str, on_date: &str, ) -> VatBreakdown { let rate = vat_rate(jurisdiction, category, on_date); let net = money( round_div(gross.minor * 10000, 10000 + rate.basis_points, "half-up"), &gross.currency, ); VatBreakdown { tax: money(gross.minor - net.minor, &gross.currency), net, gross: gross.clone(), basis_points: rate.basis_points, } } pub fn fune_vector(args: &[Value]) -> Value { vat_breakdown_to_value(&remove_vat( &money_from_value(&args[0]), args[1].as_str(), args[2].as_str(), args[3].as_str(), )) }