diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index 7994770eaa5..90d4dfab63c 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -1034,6 +1034,13 @@ class PurchaseReceipt(BuyingController): return production_plan_references = self.get_production_plan_references() + if not production_plan_references: + return + + reservable_plans = self.get_reservable_production_plans(production_plan_references) + if not reservable_plans: + return + production_plan_items = [] self.reload() @@ -1041,6 +1048,9 @@ class PurchaseReceipt(BuyingController): for row in self.items: if row.material_request_item and row.material_request_item in production_plan_references: _ref = production_plan_references[row.material_request_item] + if _ref.production_plan not in reservable_plans: + continue + docnames.append(_ref.production_plan) row.update( { @@ -1066,6 +1076,25 @@ class PurchaseReceipt(BuyingController): docnames, from_doctype="Production Plan", to_doctype="Work Order" ) + def get_reservable_production_plans(self, production_plan_references) -> set: + """Production Plans that opted into stock reservation (``reserve_stock``). + + A Production Plan only gets this flag set if "Auto Reserve Stock" was enabled in + Stock Settings when it was created, or the user ticked "Reserve Stock" manually. + Without this check, a Purchase Receipt would auto-reserve stock for every + Production Plan whenever "Enable Stock Reservation" is on, ignoring both of those. + """ + plan_names = {ref.production_plan for ref in production_plan_references.values()} + return { + p.name + for p in frappe.get_all( + "Production Plan", + filters={"name": ["in", list(plan_names)]}, + fields=["name", "reserve_stock"], + ) + if p.reserve_stock + } + def get_production_plan_references(self): production_plan_references = frappe._dict() material_request_items = []