fix: validate FG Item and Qty
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 4da1e76..3576cd4 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -49,18 +49,6 @@
}
]
- def can_update_items(self) -> bool:
- result = True
-
- if self.is_subcontracted and not self.is_old_subcontracting_flow:
- # Check - 1: NOT ALLOWED if non-cancelled Subcontracting Order exists for this Purchase Order
- if frappe.db.exists(
- "Subcontracting Order", {"purchase_order": self.name, "docstatus": ["!=", 2]}
- ):
- return False
-
- return result
-
def onload(self):
supplier_tds = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category")
self.set_onload("supplier_tds", supplier_tds)
@@ -463,6 +451,17 @@
else:
self.db_set("per_received", 0, update_modified=False)
+ def can_update_items(self) -> bool:
+ result = True
+
+ if self.is_subcontracted and not self.is_old_subcontracting_flow:
+ if frappe.db.exists(
+ "Subcontracting Order", {"purchase_order": self.name, "docstatus": ["!=", 2]}
+ ):
+ result = False
+
+ return result
+
def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor=1.0):
"""get last purchase rate for an item"""
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 340ec01..081abe1 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -2855,6 +2855,27 @@
return update_supplied_items
+ def validate_fg_item_for_subcontracting(new_data, is_new):
+ if is_new:
+ if not new_data.get("fg_item"):
+ frappe.throw(
+ _("Finished Good Item is not specified for service item {0}").format(new_data["item_code"])
+ )
+ else:
+ is_sub_contracted_item, default_bom = frappe.db.get_value(
+ "Item", new_data["fg_item"], ["is_sub_contracted_item", "default_bom"]
+ )
+
+ if not is_sub_contracted_item:
+ frappe.throw(
+ _("Finished Good Item {0} must be a sub-contracted item").format(new_data["fg_item"])
+ )
+ elif not default_bom:
+ frappe.throw(_("Default BOM not found for FG Item {0}").format(new_data["fg_item"]))
+
+ if not new_data.get("fg_item_qty"):
+ frappe.throw(_("Finished Good Item {0} Qty can not be zero").format(new_data["fg_item"]))
+
data = json.loads(trans_items)
any_qty_changed = False # updated to true if any item's qty changes
@@ -2886,6 +2907,7 @@
prev_rate, new_rate = flt(child_item.get("rate")), flt(d.get("rate"))
prev_qty, new_qty = flt(child_item.get("qty")), flt(d.get("qty"))
+ prev_fg_qty, new_fg_qty = flt(child_item.get("fg_item_qty")), flt(d.get("fg_item_qty"))
prev_con_fac, new_con_fac = flt(child_item.get("conversion_factor")), flt(
d.get("conversion_factor")
)
@@ -2898,6 +2920,7 @@
rate_unchanged = prev_rate == new_rate
qty_unchanged = prev_qty == new_qty
+ fg_qty_unchanged = prev_fg_qty == new_fg_qty
uom_unchanged = prev_uom == new_uom
conversion_factor_unchanged = prev_con_fac == new_con_fac
any_conversion_factor_changed |= not conversion_factor_unchanged
@@ -2907,6 +2930,7 @@
if (
rate_unchanged
and qty_unchanged
+ and fg_qty_unchanged
and conversion_factor_unchanged
and uom_unchanged
and date_unchanged
@@ -2917,6 +2941,17 @@
if flt(child_item.get("qty")) != flt(d.get("qty")):
any_qty_changed = True
+ if (
+ parent.doctype == "Purchase Order"
+ and parent.is_subcontracted
+ and not parent.is_old_subcontracting_flow
+ ):
+ validate_fg_item_for_subcontracting(d, new_child_flag)
+ child_item.fg_item_qty = flt(d["fg_item_qty"])
+
+ if new_child_flag:
+ child_item.fg_item = d["fg_item"]
+
child_item.qty = flt(d.get("qty"))
rate_precision = child_item.precision("rate") or 2
conv_fac_precision = child_item.precision("conversion_factor") or 2
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 9116fd1..c11d123 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -579,7 +579,9 @@
"conversion_factor": d.conversion_factor,
"qty": d.qty,
"rate": d.rate,
- "uom": d.uom
+ "uom": d.uom,
+ "fg_item": d.fg_item,
+ "fg_item_qty": d.fg_item_qty,
}
});