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
/// Apply money on account to bills in the order given.
///
/// # Panics
/// Panics on a negative amount on account, a negative bill or mixed currencies.
pub fn retainer_drawdown(on_account: &Money, bills: &[RetainerBill]) -> RetainerDrawdown {
let currency = on_account.currency.as_str();
if on_account.minor < 0 {
panic!("onAccount must not be negative, received {}", on_account.minor);
}
let mut left = on_account.minor;
let mut applied = 0;
let mut outstanding = 0;
let mut lines: Vec<RetainerApplication> = Vec::new();
for bill in bills {
if bill.amount.currency != currency {
panic!("currency mismatch: {} and {}", currency, bill.amount.currency);
}
if bill.amount.minor < 0 {
panic!("bill \"{}\" must not be negative, received {}", bill.reference, bill.amount.minor);
}
let take = left.min(bill.amount.minor);
left -= take;
applied += take;
outstanding += bill.amount.minor - take;
lines.push(RetainerApplication {
reference: bill.reference.clone(),
billed: bill.amount.clone(),
applied: money(take, currency),
outstanding: money(bill.amount.minor - take, currency),
});
}
RetainerDrawdown {
bills: lines,
applied: money(applied, currency),
outstanding: money(outstanding, currency),
balance: money(left, currency),
}
}
pub fn retainer_bill_from_value(v: &Value) -> RetainerBill {
RetainerBill { reference: v.get("reference").as_str().to_string(), amount: money_from_value(v.get("amount")) }
}
pub fn retainer_drawdown_to_value(d: &RetainerDrawdown) -> Value {
Value::obj(vec![
(
"bills",
Value::Arr(
d.bills
.iter()
.map(|b| {
Value::obj(vec![
("reference", Value::str(&b.reference)),
("billed", money_to_value(&b.billed)),
("applied", money_to_value(&b.applied)),
("outstanding", money_to_value(&b.outstanding)),
])
})
.collect(),
),
),
("applied", money_to_value(&d.applied)),
("outstanding", money_to_value(&d.outstanding)),
("balance", money_to_value(&d.balance)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
let bills: Vec<RetainerBill> = args[1].as_arr().iter().map(retainer_bill_from_value).collect();
retainer_drawdown_to_value(&retainer_drawdown(&money_from_value(&args[0]), &bills))
}