///|
/// A single-store replenishment run: safety stock, an open purchase order and a
/// minimum-multiple policy. The bucket table is checked against an independent
/// inventory recurrence so the example doubles as an end-to-end assertion.
fn q(units : Int) -> @mrp.Qty {
@mrp.Qty::int(units)
}
///|
fn main raise {
let horizon = 6
let request : @mrp.Request = {
horizon,
items: [
{
sku: "LABEL",
unit: "EA",
on_hand: q(3),
safety: @mrp.SafetyStock::Fixed(q(2)),
max_stock: @mrp.Qty::zero(),
phantom: false,
lead_time: 1,
yield_per_mille: 1000,
lot: @mrp.MinimumMultiple(q(10), q(4)),
},
],
bom: [],
demands: [
{ id: "store-a", item: "LABEL", bucket: 2, quantity: q(9), },
{ id: "store-b", item: "LABEL", bucket: 3, quantity: q(3), },
],
receipts: [{ id: "open-po", item: "LABEL", bucket: 1, quantity: q(2), }],
conversions: [],
policy: @mrp.Strict,
}
let plan = request |> @mrp.plan |> Result::unwrap
println(
"1 store replenishment (minimum 10, multiple 4, safety stock 2, lead time 1)",
)
println(" bucket gross scheduled net receipt received release projected")
let mut inventory = request.items[0].on_hand
for bucket in plan.items[0].buckets {
println(
" " +
bucket.index.to_string() +
" " +
bucket.gross.to_string() +
" " +
bucket.scheduled.to_string() +
" " +
bucket.net.to_string() +
" " +
bucket.planned_receipt.to_string() +
" " +
bucket.received.to_string() +
" " +
bucket.planned_release.to_string() +
" " +
bucket.projected.to_string(),
)
inventory = inventory
.add(bucket.scheduled)
.add(bucket.received)
.sub(bucket.gross)
assert_eq(inventory, bucket.projected)
}
assert_eq(plan.orders.length(), 1)
let order = plan.orders[0]
assert_eq(order.receipt_bucket, 2)
assert_eq(order.release_bucket, 1)
assert_eq(order.quantity, q(12))
println(
" order: LABEL quantity=" +
order.quantity.to_string() +
" receipt=" +
order.receipt_bucket.to_string() +
" release=" +
order.release_bucket.to_string(),
)
println("2 policy applied without a plan")
for net in [0, 1, 11, 12] {
let rounded = @mrp.order_quantity(q(net), @mrp.MinimumMultiple(q(10), q(4))).unwrap()
println(
" order_quantity(" +
net.to_string() +
", MinimumMultiple(10,4)) = " +
rounded.to_string(),
)
}
println(
"3 conservation held for every bucket and the JSON stays string-typed",
)
let json = plan.to_json().stringify()
assert_true(json.contains("\"quantity\":\"12\""))
assert_true(json.contains("\"schema\":\"moon-mrp.plan.v3\""))
println(" ok")
}