fix: do not rely on client side to update quantities during partial d… (#54804)

fix: do not rely on client side to update quantities during partial dropship
This commit is contained in:
Mihir Kandoi
2026-05-11 11:47:54 +05:30
committed by GitHub
parent 3deda25d21
commit 03acbc3dc9
2 changed files with 64 additions and 55 deletions

View File

@@ -777,61 +777,26 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends (
},
],
primary_action: (values) => {
const data = values.items.filter((item) => item.__checked);
if (!data.length) {
frappe.throw(__("Please select at least one item to update delivered quantity."));
}
data.forEach((item) => {
if (!item.qty_change) {
frappe.throw(
__(
"Item {0} has no changes in delivered quantity. Please unselect the row if you do not wish to update its quantity.",
[item.item_code.bold()]
)
);
}
if (item.qty_change < 0 && Math.abs(item.qty_change) > item.delivered_qty) {
frappe.throw(
__("Delivered Qty cannot be reduced by more than {0} for item {1}", [
item.delivered_qty,
item.item_code.bold(),
])
);
}
if (item.qty_change > 0 && item.delivered_qty + item.qty_change > item.qty) {
frappe.throw(
__("Delivered Qty cannot be increased by more than {0} for item {1}", [
item.qty - item.delivered_qty,
item.item_code.bold(),
])
);
}
});
data.forEach((item) => {
frappe.model.set_value(
"Purchase Order Item",
item.name,
"received_qty",
item.delivered_qty + item.qty_change
);
});
const frm = this.frm;
frm.dirty();
frm.save("Update", () => {
frappe.call({
doc: frm.doc,
method: "update_receiving_percentage",
callback: function (r) {
if (!r.exc) {
dialog.hide();
frappe.toast(__("Quantities updated successfully."));
frm.reload_doc();
}
},
});
frappe.call({
doc: frm.doc,
method: "update_dropship_received_qty",
args: {
data: values.items
.filter((item) => item.__checked)
.map((item) => ({
name: item.name,
current_qty: item.delivered_qty,
qty_change: item.qty_change,
})),
},
callback: function (r) {
if (!r.exc) {
frm.reload_doc();
frappe.toast(__("Quantities updated successfully."));
dialog.hide();
}
},
});
},
});

View File

@@ -552,13 +552,57 @@ class PurchaseOrder(BuyingController):
def has_drop_ship_item(self):
return any(d.delivered_by_supplier for d in self.items)
@frappe.whitelist()
def update_dropship_received_qty(self, data: list[dict]):
if not data:
frappe.throw(_("Please select at least one item to update delivered quantity."))
for d in data:
item = next((item for item in self.items if item.name == d.get("name")), None)
if not item:
frappe.throw(
_("Item with name {0} not found in the Purchase Order").format(frappe.bold(d.get("name")))
)
if not item.has_permlevel_access_to("received_qty", permission_type="write"):
frappe.throw(
_("You don't have permission to update Received Qty DocField for item {0}").format(
frappe.bold(item.item_code)
)
)
if not d.get("qty_change"):
frappe.throw(
_(
"Item {0} has no changes in delivered quantity. Please unselect the row if you do not wish to update its quantity."
).format(frappe.bold(item.item_code))
)
if d.get("qty_change") < 0 and abs(d.get("qty_change")) > item.received_qty:
frappe.throw(
_("Delivered Qty cannot be reduced by more than {0} for item {1}").format(
item.received_qty, frappe.bold(item.item_code)
)
)
if d.get("qty_change") > 0 and item.received_qty + d.get("qty_change") > item.qty:
frappe.throw(
_("Delivered Qty cannot be increased by more than {0} for item {1}").format(
item.qty - item.received_qty, frappe.bold(item.item_code)
)
)
item.received_qty += d.get("qty_change")
self.update_receiving_percentage()
self.save()
def is_against_so(self):
return any(d.sales_order for d in self.items if d.sales_order)
def is_against_pp(self):
return any(d.production_plan for d in self.items if d.production_plan)
@frappe.whitelist()
def update_receiving_percentage(self):
total_qty, received_qty = 0.0, 0.0
for item in self.items: