fix: validate qty that can be disassembled from source stock entry.

(cherry picked from commit 6394dead72)

# Conflicts:
#	erpnext/manufacturing/doctype/work_order/work_order.py
This commit is contained in:
Smit Vora
2026-03-30 15:46:37 +05:30
committed by Mergify
parent 1c4b2a7148
commit 1237f9a0b1
2 changed files with 35 additions and 11 deletions

View File

@@ -2433,24 +2433,27 @@ def make_stock_entry(
@frappe.whitelist() @frappe.whitelist()
<<<<<<< HEAD <<<<<<< HEAD
<<<<<<< HEAD
def get_default_warehouse(company): def get_default_warehouse(company):
======= =======
def get_disassembly_available_qty(stock_entry_name: str) -> float: def get_disassembly_available_qty(stock_entry_name: str) -> float:
=======
def get_disassembly_available_qty(stock_entry_name: str, current_se_name: str | None = None) -> float:
>>>>>>> 6394dead72 (fix: validate qty that can be disassembled from source stock entry.)
se = frappe.db.get_value("Stock Entry", stock_entry_name, ["fg_completed_qty"], as_dict=True) se = frappe.db.get_value("Stock Entry", stock_entry_name, ["fg_completed_qty"], as_dict=True)
if not se: if not se:
return 0.0 return 0.0
already_disassembled = flt( filters = {
frappe.db.get_value( "source_stock_entry": stock_entry_name,
"Stock Entry", "purpose": "Disassemble",
{ "docstatus": 1,
"source_stock_entry": stock_entry_name, }
"purpose": "Disassemble",
"docstatus": 1, if current_se_name:
}, filters["name"] = ("!=", current_se_name)
[{"SUM": "fg_completed_qty"}],
) already_disassembled = flt(frappe.db.get_value("Stock Entry", filters, [{"SUM": "fg_completed_qty"}]))
)
return flt(se.fg_completed_qty) - already_disassembled return flt(se.fg_completed_qty) - already_disassembled

View File

@@ -247,6 +247,7 @@ class StockEntry(StockController, SubcontractingInwardController):
self.validate_warehouse() self.validate_warehouse()
self.validate_warehouse_of_sabb() self.validate_warehouse_of_sabb()
self.validate_work_order() self.validate_work_order()
self.validate_source_stock_entry()
self.validate_bom() self.validate_bom()
self.set_process_loss_qty() self.set_process_loss_qty()
self.validate_purchase_order() self.validate_purchase_order()
@@ -847,6 +848,26 @@ class StockEntry(StockController, SubcontractingInwardController):
elif self.purpose != "Material Transfer": elif self.purpose != "Material Transfer":
self.work_order = None self.work_order = None
def validate_source_stock_entry(self):
if not self.get("source_stock_entry"):
return
from erpnext.manufacturing.doctype.work_order.work_order import get_disassembly_available_qty
available_qty = get_disassembly_available_qty(self.source_stock_entry, self.name)
if flt(self.fg_completed_qty) > available_qty:
frappe.throw(
_(
"Cannot disassemble {0} qty against Stock Entry {1}. Only {2} qty available to disassemble."
).format(
self.fg_completed_qty,
self.source_stock_entry,
available_qty,
),
title=_("Excess Disassembly"),
)
def check_if_operations_completed(self): def check_if_operations_completed(self):
"""Check if Time Sheets are completed against before manufacturing to capture operating costs.""" """Check if Time Sheets are completed against before manufacturing to capture operating costs."""
prod_order = frappe.get_doc("Work Order", self.work_order) prod_order = frappe.get_doc("Work Order", self.work_order)