///|
/// Fixed snapshots retain every quantity. The variable rule has no quantity;
/// its customer/period/limit come explicitly from request.
pub(all) struct BillQuotaInput {
fixed : Array[BillItem]
variable : Tariff
request : BudgetRequest
}
///|
pub(all) struct BillQuota {
request : BudgetRequest
variable_metric : String
bill : Bill
first_unaffordable : Bill?
} derive(Debug, Eq)
///|
pub extend BillQuota with Debug::{to_repr}
///|
pub extend BillQuota with Eq::{equal, not_equal}
///|
fn bill_quota_items(
input : BillQuotaInput,
q : BigInt,
) -> Array[BillItem] raise PricingError {
check_budget(input.request)
let info = tariff_info(input.variable)
let usage : Usage = {
customer: input.request.customer,
period: input.request.period,
metric: info.metric,
quantity: q.to_string(),
}
let items = input.fixed + [bind_tariff(input.variable, usage)]
ignore(check_bill(items[:]))
items
}
///|
fn variable_fits(
input : BillQuotaInput,
q : BigInt,
available : BigInt,
scale~ : Int32,
rounding~ : Rounding,
) -> Bool raise PricingError {
let info = tariff_info(input.variable)
let u : Usage = {
customer: input.request.customer,
period: input.request.period,
metric: info.metric,
quantity: q.to_string(),
}
let settlement = match input.variable {
MeteredTariff(p, minimum, zero_usage) =>
rate_charge(p, u, minimum~, zero_usage~, scale~, rounding~).settlement
PackageTariff(p) => rate_packages(p, u, scale~, rounding~).settlement
}
let step = BigInt::from_string("1" + "0".repeat(18 - scale))
BigInt::from_string(settlement.minor_units) * step <= available
}
///|
/// Keep 0..63 fixed metric snapshots and maximize a safe prefix for one variable
/// metric under the total settled bill budget, including explicit minimum rules.
///
/// ```mbt check
/// test {
/// let p = @jieheng.compile_package(
/// id="sms",
/// version="v1",
/// metric="messages",
/// unit="message",
/// currency="USD",
/// package_size="1000",
/// package_price="0.85",
/// )
/// let input : @jieheng.BillQuotaInput = {
/// fixed: [],
/// variable: PackageTariff(p),
/// request: {
/// customer: "acme",
/// period: "October",
/// budget: "3",
/// limit: "10000",
/// },
/// }
/// let q = @jieheng.quote_bill_quota(input, scale=2, rounding=HalfEven)
/// inspect(q.bill.totals.amount, content="2.55")
/// }
/// ```
pub fn quote_bill_quota(
input : BillQuotaInput,
scale~ : Int32,
rounding~ : Rounding,
) -> BillQuota raise PricingError {
ignore(bill_quota_items(input, 0N))
let info = tariff_info(input.variable)
ignore(settle_total(info.currency, "0", scale~, rounding~))
let budget = amount_atoms(input.request.budget, "bill_quota.budget")
let fixed_paid = if input.fixed.length() == 0 {
0N
} else {
amount_atoms(
rate_bill(input.fixed[:], scale~, rounding~).totals.amount,
"bill_quota.fixed",
)
}
if fixed_paid > budget {
invalid(
"infeasible", "bill_quota.budget", "fixed item settlements already exceed the budget",
)
}
let available = budget - fixed_paid
if !variable_fits(input, 0N, available, scale~, rounding~) {
invalid(
"infeasible", "bill_quota.budget", "zero variable usage already exceeds the remaining budget, including its minimum-spend policy",
)
}
let limit = natural(input.request.limit, "bill_quota.limit")
let mut quota = limit
match input.variable {
PackageTariff(_) =>
if search_quantity(0N, limit, q => {
variable_fits(input, q, available, scale~, rounding~)
})
is Some(q) {
quota = q
}
MeteredTariff(p, _, _) => {
// Zero-usage waiver is a distinct point. Every positive tier is monotone
// internally even after taking max(raw, contractual minimum).
let mut from = 1N
while from <= limit {
let (to, _, _) = curve_piece(p, from, limit)
if !variable_fits(input, from, available, scale~, rounding~) {
quota = from - 1N
break
}
if !variable_fits(input, to, available, scale~, rounding~) {
if search_quantity(from, to, q => {
variable_fits(input, q, available, scale~, rounding~)
})
is Some(q) {
quota = q
}
break
}
from = to + 1N
}
}
}
let bill = rate_bill(bill_quota_items(input, quota)[:], scale~, rounding~)
let first_unaffordable = if quota < limit {
Some(
rate_bill(bill_quota_items(input, quota + 1N)[:], scale~, rounding~) catch {
Invalid(code~, path~, message~) =>
raise Invalid(
code~,
path="bill_quota.first_unaffordable." + path,
message~,
)
},
)
} else {
None
}
let report = {
request: input.request,
variable_metric: info.metric,
bill,
first_unaffordable,
}
verify_bill_quota(input, report, scale~, rounding~)
report
}
///|
fn bill_evidence_usage(evidence : BillEvidence) -> Usage {
match evidence {
MeteredCharge(c) => c.calculation.usage
PackageCharge(c) => c.usage
}
}
///|
/// Verify fixed settlements, every model-specific witness and prefix safety.
/// Uses verified fixed amounts and rounding thresholds, never quota/rate producers.
pub fn verify_bill_quota(
input : BillQuotaInput,
report : BillQuota,
scale~ : Int32,
rounding~ : Rounding,
) -> Unit raise PricingError {
check_budget(input.request)
let info = tariff_info(input.variable)
if report.request != input.request ||
report.variable_metric != info.metric ||
report.bill.items.length() != input.fixed.length() + 1 {
invalid(
"identity", "bill_quota", "request, variable metric and complete fixed/variable item coverage must match trusted input",
)
}
let q = natural(
bill_evidence_usage(report.bill.items[input.fixed.length()]).quantity,
"bill_quota.quantity",
)
let limit = natural(input.request.limit, "bill_quota.limit")
if q > limit {
invalid(
"limit", "bill_quota.quantity", "quota exceeds trusted search limit",
)
}
verify_bill(bill_quota_items(input, q)[:], report.bill, scale~, rounding~)
let budget = amount_atoms(input.request.budget, "bill_quota.budget")
if amount_atoms(report.bill.totals.amount, "bill.amount") > budget {
invalid(
"budget", "bill_quota.quantity", "settled bill exceeds total budget",
)
}
let mut fixed_paid = 0N
for item in report.bill.items[:input.fixed.length()] {
fixed_paid += amount_atoms(bill_item_amounts(item).3, "bill_quota.fixed")
}
let available = budget - fixed_paid
match input.variable {
MeteredTariff(p, minimum, _) if p.mode == Volume => {
let floor = decimal(minimum, "bill_quota.minimum")
let mut previous = 0N
for tier in p.tiers {
let upper = match tier.up_to {
Some(n) => if n < q { n } else { q }
None => q
}
if upper > previous {
let raw = upper * tier.price
let charge = if raw > floor { raw } else { floor }
if !threshold_fits(charge, available, scale, rounding) {
invalid(
"prefix", "bill_quota.quantity", "an earlier positive volume quantity exceeds the whole-bill budget after its minimum is applied",
)
}
}
match tier.up_to {
Some(n) => previous = n
None => ()
}
if upper == q {
break
}
}
}
_ => () // Graduated+floor and package charges are nondecreasing.
}
if q == limit {
if report.first_unaffordable is Some(_) {
invalid(
"witness", "bill_quota.first_unaffordable", "no out-of-domain witness is accepted at the trusted limit",
)
}
} else {
guard report.first_unaffordable is Some(witness) else {
invalid(
"witness", "bill_quota.first_unaffordable", "a complete bill for exactly quota plus one is required",
)
return
}
verify_bill(bill_quota_items(input, q + 1N)[:], witness, scale~, rounding~) catch {
Invalid(code~, path~, message~) =>
raise Invalid(
code~,
path="bill_quota.first_unaffordable." + path,
message~,
)
}
if amount_atoms(witness.totals.amount, "bill.amount") <= budget {
invalid(
"witness", "bill_quota.first_unaffordable", "next complete bill is still affordable",
)
}
}
}