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::add_days; ← from dates.add-days ^1.0.0 · built alongside by fune
use super::finance_payment_terms_due_date::{payment_due_date, payment_terms_from_value, PaymentTerms}; ← from finance.payment-terms-due-date ^1.0.0 · built alongside by fune
use super::money_add::subtract_money; ← from money.add ^1.0.0 · built alongside by fune
use super::money_amount::{money, 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
/// The settlement discount open on `payment_date`, and what is left to pay.
///
/// The window is inclusive and counted in calendar days from the invoice date,
/// so under 2/10 the tenth day after the invoice still earns the discount.
///
/// # Panics
/// Panics on a negative total, malformed dates or invalid terms.
pub fn early_payment_discount(
invoice_total: &Money,
invoice_date: &str,
terms: &PaymentTerms,
payment_date: &str,
) -> EarlyPaymentDiscount {
if invoice_total.minor < 0 {
panic!("invoice total must not be negative");
}
// Validates the terms, including a discount window that outlasts the due date.
let due_date = payment_due_date(invoice_date, terms);
// Validates the payment date; ISO dates then compare as strings.
add_days(payment_date, 0);
let deadline = if terms.discount_basis_points > 0 {
Some(add_days(invoice_date, terms.discount_days))
} else {
None
};
let available = match &deadline {
Some(last) => payment_date <= last.as_str(),
None => false,
};
let discount = if available {
apply_rate(invoice_total, terms.discount_basis_points, "half-up")
} else {
money(0, &invoice_total.currency)
};
EarlyPaymentDiscount {
available,
amount_to_pay: subtract_money(invoice_total, &discount),
discount,
discount_deadline: deadline,
due_date,
}
}
pub fn early_payment_discount_to_value(d: &EarlyPaymentDiscount) -> Value {
Value::obj(vec![
("available", Value::Bool(d.available)),
("discount", money_to_value(&d.discount)),
("amountToPay", money_to_value(&d.amount_to_pay)),
(
"discountDeadline",
match &d.discount_deadline {
Some(date) => Value::str(date),
None => Value::Null,
},
),
("dueDate", Value::str(&d.due_date)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
early_payment_discount_to_value(&early_payment_discount(
&money_from_value(&args[0]),
args[1].as_str(),
&payment_terms_from_value(&args[2]),
args[3].as_str(),
))
}