refactor: use frappe.db.bulk_update instead of Case queries in subcon… (#55232)

This commit is contained in:
Mihir Kandoi
2026-05-24 15:06:45 +05:30
committed by GitHub
parent 004818e0ac
commit c1a4c3d053

View File

@@ -651,20 +651,25 @@ class SubcontractingInwardController:
).update_manufacturing_qty_fields()
elif self.purpose in ["Subcontracting Delivery", "Subcontracting Return"]:
fieldname = "delivered_qty" if self.purpose == "Subcontracting Delivery" else "returned_qty"
qty_map = defaultdict(lambda: defaultdict(float))
for item in self.items:
doctype = (
"Subcontracting Inward Order Item"
if not item.type and not item.is_legacy_scrap_item
else "Subcontracting Inward Order Secondary Item"
)
frappe.db.set_value(
doctype,
item.scio_detail,
fieldname,
frappe.get_value(doctype, item.scio_detail, fieldname)
+ (item.transfer_qty if self._action == "submit" else -item.transfer_qty),
qty_map[doctype][item.scio_detail] += (
item.transfer_qty if self._action == "submit" else -item.transfer_qty
)
for doctype, item_qty_map in qty_map.items():
table = frappe.qb.DocType(doctype)
field = table[fieldname]
doc_updates = {
scio_detail: {fieldname: field + qty} for scio_detail, qty in item_qty_map.items()
}
frappe.db.bulk_update(doctype, doc_updates, chunk_size=len(doc_updates))
def update_inward_order_received_items(self):
if self.subcontracting_inward_order:
match self.purpose:
@@ -679,14 +684,18 @@ class SubcontractingInwardController:
else -item.transfer_qty
for item in self.items
}
case_expr = Case()
table = frappe.qb.DocType("Subcontracting Inward Order Received Item")
for scio_rm_name, qty in scio_rm_names.items():
case_expr = case_expr.when(table.name == scio_rm_name, table.returned_qty + qty)
frappe.qb.update(table).set(table.returned_qty, case_expr).where(
(table.name.isin(list(scio_rm_names.keys()))) & (table.docstatus == 1)
).run()
doc_updates = {
scio_rm_name: {"returned_qty": table.returned_qty + qty}
for scio_rm_name, qty in scio_rm_names.items()
}
if doc_updates:
frappe.db.bulk_update(
"Subcontracting Inward Order Received Item",
doc_updates,
chunk_size=len(doc_updates),
update_modified=False,
)
def update_inward_order_received_items_for_raw_materials_receipt(self):
data = frappe._dict()
@@ -738,9 +747,7 @@ class SubcontractingInwardController:
fields=["rate", "name", "required_qty", "received_qty"],
)
deleted_docs = []
table = frappe.qb.DocType("Subcontracting Inward Order Received Item")
case_expr_qty, case_expr_rate = Case(), Case()
doc_updates = {}
for d in result:
current_qty = flt(data[d.name].transfer_qty) * (1 if self._action == "submit" else -1)
current_rate = flt(data[d.name].rate)
@@ -755,16 +762,17 @@ class SubcontractingInwardController:
)
if not d.required_qty and not d.received_qty:
deleted_docs.append(d.name)
frappe.delete_doc("Subcontracting Inward Order Received Item", d.name)
else:
case_expr_qty = case_expr_qty.when(table.name == d.name, d.received_qty)
case_expr_rate = case_expr_rate.when(table.name == d.name, d.rate)
doc_updates[d.name] = {"received_qty": d.received_qty, "rate": d.rate}
if final_list := list(set(data.keys()) - set(deleted_docs)):
frappe.qb.update(table).set(table.received_qty, case_expr_qty).set(
table.rate, case_expr_rate
).where((table.name.isin(final_list)) & (table.docstatus == 1)).run()
if doc_updates:
frappe.db.bulk_update(
"Subcontracting Inward Order Received Item",
doc_updates,
chunk_size=len(doc_updates),
update_modified=False,
)
def update_inward_order_received_items_for_manufacture(self):
customer_warehouse = frappe.get_cached_value(
@@ -816,8 +824,8 @@ class SubcontractingInwardController:
)
if data := data.run(as_dict=True):
deleted_docs, used_item_wh = [], []
case_expr = Case()
used_item_wh = []
doc_updates = {}
for d in data:
if not d.warehouse:
d.warehouse = next(
@@ -829,15 +837,17 @@ class SubcontractingInwardController:
qty = d.consumed_qty + item_code_wh[(d.rm_item_code, d.warehouse)]
if qty or d.is_customer_provided_item or not d.is_additional_item:
case_expr = case_expr.when((table.name == d.name), qty)
doc_updates[d.name] = {"consumed_qty": qty}
else:
deleted_docs.append(d.name)
frappe.delete_doc("Subcontracting Inward Order Received Item", d.name)
if final_list := list(set([d.name for d in data]) - set(deleted_docs)):
frappe.qb.update(table).set(table.consumed_qty, case_expr).where(
(table.name.isin(final_list)) & (table.docstatus == 1)
).run()
if doc_updates:
frappe.db.bulk_update(
"Subcontracting Inward Order Received Item",
doc_updates,
chunk_size=len(doc_updates),
update_modified=False,
)
main_item_code = next(fg for fg in self.items if fg.is_finished_item).item_code
for extra_item in [
@@ -910,27 +920,25 @@ class SubcontractingInwardController:
for d in result
}
)
deleted_docs = []
case_expr = Case()
table = frappe.qb.DocType("Subcontracting Inward Order Secondary Item")
doc_updates = {}
for key, value in secondary_items_dict.items():
if (
self._action == "cancel"
and value.produced_qty - abs(secondary_items.get(key)) == 0
):
deleted_docs.append(value.name)
frappe.delete_doc("Subcontracting Inward Order Secondary Item", value.name)
else:
case_expr = case_expr.when(
table.name == value.name, value.produced_qty + secondary_items.get(key)
)
doc_updates[value.name] = {
"produced_qty": value.produced_qty + secondary_items.get(key)
}
if final_list := list(
set([v.name for v in secondary_items_dict.values()]) - set(deleted_docs)
):
frappe.qb.update(table).set(table.produced_qty, case_expr).where(
(table.name.isin(final_list)) & (table.docstatus == 1)
).run()
if doc_updates:
frappe.db.bulk_update(
"Subcontracting Inward Order Secondary Item",
doc_updates,
chunk_size=len(doc_updates),
update_modified=False,
)
fg_item_code = next(fg for fg in self.items if fg.is_finished_item).item_code
for secondary_item in [