feat: warn when ordered qty exceeds min order qty only by UOM rounding

A minimum order qty defined in stock UOM often has no exact
representation in the purchase UOM, so the smallest valid order slightly
exceeds the minimum. Surface that overage on the Purchase Order with a
toast on first save when an item's ordered stock qty is above its
minimum by less than one purchase-UOM step, so the buyer sees the
marginal increase before sending the order. Sub-precision dust stays
silent.
This commit is contained in:
Mihir Kandoi
2026-08-07 22:34:06 +05:30
parent e4b66dc731
commit 1aa6f8d1a7

View File

@@ -319,6 +319,38 @@ class PurchaseOrder(BuyingController):
).format(item_code, flt(qty, precision), itemwise_min_order_qty.get(item_code))
)
self.warn_marginal_min_order_qty(itemwise_qty, itemwise_min_order_qty)
def warn_marginal_min_order_qty(self, itemwise_qty, itemwise_min_order_qty):
"""Toast when an item's ordered qty exceeds its minimum only by purchase UOM rounding."""
if not self.is_new():
return
precision = self.items[0].precision("stock_qty")
itemwise_step = frappe._dict()
itemwise_stock_uom = frappe._dict()
for d in self.get("items"):
step = 10 ** -d.precision("qty") * flt(d.conversion_factor)
itemwise_step[d.item_code] = max(itemwise_step.get(d.item_code, 0), step)
itemwise_stock_uom[d.item_code] = d.stock_uom
for item_code, qty in itemwise_qty.items():
min_order_qty = flt(itemwise_min_order_qty.get(item_code))
overage = flt(qty) - min_order_qty
if min_order_qty and flt(overage, precision) > 0 and overage < itemwise_step[item_code]:
frappe.toast(
_(
"Item {0}: Ordered qty {1} {2} exceeds the minimum order qty {3} {2} by {4} {2} due to purchase UOM rounding."
).format(
item_code,
flt(qty, precision),
itemwise_stock_uom[item_code],
min_order_qty,
flt(overage, precision),
),
indicator="orange",
)
def get_schedule_dates(self):
for d in self.get("items"):
if d.material_request_item and not d.schedule_date: