Functional Weave
Code in Rust

finance.tax.add-vat@1.0.0

impl/rust.rs

1,370 bytes · the Rust 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.

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::finance_tax_vat_rate::vat_rate;  ← from finance.tax.vat-rate ^1.0.0 · built alongside by fune
use super::money_add::add_money;  ← from money.add ^1.0.0 · built alongside by fune
use super::money_amount::{money_from_value, money_to_value, Money};  ← from money.amount ^1.0.0 · built alongside by fune
use super::money_apply_rate::apply_rate;  ← from money.apply-rate ^1.0.0 · built alongside by fune

/// 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(),
    ))
}