Merge pull request #36168 from frappe/mergify/bp/develop/pr-36162
fix: incorrect Reserved Qty for Production Plan in BIN for the multi-uom case (backport #36162)
This commit is contained in:
commit
55d5469740
@ -1539,7 +1539,7 @@ def get_reserved_qty_for_production_plan(item_code, warehouse):
|
|||||||
frappe.qb.from_(table)
|
frappe.qb.from_(table)
|
||||||
.inner_join(child)
|
.inner_join(child)
|
||||||
.on(table.name == child.parent)
|
.on(table.name == child.parent)
|
||||||
.select(Sum(child.required_bom_qty * IfNull(child.conversion_factor, 1.0)))
|
.select(Sum(child.quantity * IfNull(child.conversion_factor, 1.0)))
|
||||||
.where(
|
.where(
|
||||||
(table.docstatus == 1)
|
(table.docstatus == 1)
|
||||||
& (child.item_code == item_code)
|
& (child.item_code == item_code)
|
||||||
|
@ -933,6 +933,54 @@ class TestProductionPlan(FrappeTestCase):
|
|||||||
|
|
||||||
self.assertEqual(after_qty, before_qty)
|
self.assertEqual(after_qty, before_qty)
|
||||||
|
|
||||||
|
def test_resered_qty_for_production_plan_for_material_requests_with_multi_UOM(self):
|
||||||
|
from erpnext.stock.utils import get_or_make_bin
|
||||||
|
|
||||||
|
fg_item = make_item(properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1"}).name
|
||||||
|
bom_item = make_item(
|
||||||
|
properties={"is_stock_item": 1, "stock_uom": "_Test UOM 1", "purchase_uom": "Nos"}
|
||||||
|
).name
|
||||||
|
|
||||||
|
if not frappe.db.exists("UOM Conversion Detail", {"parent": bom_item, "uom": "Nos"}):
|
||||||
|
doc = frappe.get_doc("Item", bom_item)
|
||||||
|
doc.append("uoms", {"uom": "Nos", "conversion_factor": 25})
|
||||||
|
doc.save()
|
||||||
|
|
||||||
|
make_bom(item=fg_item, raw_materials=[bom_item], source_warehouse="_Test Warehouse - _TC")
|
||||||
|
|
||||||
|
bin_name = get_or_make_bin(bom_item, "_Test Warehouse - _TC")
|
||||||
|
before_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
|
||||||
|
|
||||||
|
pln = create_production_plan(
|
||||||
|
item_code=fg_item, planned_qty=100, ignore_existing_ordered_qty=1, stock_uom="_Test UOM 1"
|
||||||
|
)
|
||||||
|
|
||||||
|
for row in pln.mr_items:
|
||||||
|
self.assertEqual(row.uom, "Nos")
|
||||||
|
self.assertEqual(row.quantity, 4)
|
||||||
|
|
||||||
|
reserved_qty = flt(frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan"))
|
||||||
|
self.assertEqual(reserved_qty - before_qty, 100.0)
|
||||||
|
|
||||||
|
pln.submit_material_request = 1
|
||||||
|
pln.make_work_order()
|
||||||
|
|
||||||
|
for work_order in frappe.get_all(
|
||||||
|
"Work Order",
|
||||||
|
fields=["name"],
|
||||||
|
filters={"production_plan": pln.name},
|
||||||
|
):
|
||||||
|
wo_doc = frappe.get_doc("Work Order", work_order.name)
|
||||||
|
wo_doc.source_warehouse = "_Test Warehouse - _TC"
|
||||||
|
wo_doc.wip_warehouse = "_Test Warehouse 1 - _TC"
|
||||||
|
wo_doc.fg_warehouse = "_Test Warehouse - _TC"
|
||||||
|
wo_doc.submit()
|
||||||
|
|
||||||
|
reserved_qty_after_mr = flt(
|
||||||
|
frappe.db.get_value("Bin", bin_name, "reserved_qty_for_production_plan")
|
||||||
|
)
|
||||||
|
self.assertEqual(reserved_qty_after_mr, before_qty)
|
||||||
|
|
||||||
def test_skip_available_qty_for_sub_assembly_items(self):
|
def test_skip_available_qty_for_sub_assembly_items(self):
|
||||||
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
||||||
|
|
||||||
|
@ -118,8 +118,8 @@ class MaterialRequest(BuyingController):
|
|||||||
self.title = _("{0} Request for {1}").format(_(self.material_request_type), items)[:100]
|
self.title = _("{0} Request for {1}").format(_(self.material_request_type), items)[:100]
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.update_requested_qty()
|
|
||||||
self.update_requested_qty_in_production_plan()
|
self.update_requested_qty_in_production_plan()
|
||||||
|
self.update_requested_qty()
|
||||||
if self.material_request_type == "Purchase":
|
if self.material_request_type == "Purchase":
|
||||||
self.validate_budget()
|
self.validate_budget()
|
||||||
|
|
||||||
@ -178,8 +178,8 @@ class MaterialRequest(BuyingController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.update_requested_qty()
|
|
||||||
self.update_requested_qty_in_production_plan()
|
self.update_requested_qty_in_production_plan()
|
||||||
|
self.update_requested_qty()
|
||||||
|
|
||||||
def get_mr_items_ordered_qty(self, mr_items):
|
def get_mr_items_ordered_qty(self, mr_items):
|
||||||
mr_items_ordered_qty = {}
|
mr_items_ordered_qty = {}
|
||||||
@ -270,7 +270,13 @@ class MaterialRequest(BuyingController):
|
|||||||
item_wh_list.append([d.item_code, d.warehouse])
|
item_wh_list.append([d.item_code, d.warehouse])
|
||||||
|
|
||||||
for item_code, warehouse in item_wh_list:
|
for item_code, warehouse in item_wh_list:
|
||||||
update_bin_qty(item_code, warehouse, {"indented_qty": get_indented_qty(item_code, warehouse)})
|
update_bin_qty(
|
||||||
|
item_code,
|
||||||
|
warehouse,
|
||||||
|
{
|
||||||
|
"indented_qty": get_indented_qty(item_code, warehouse),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def update_requested_qty_in_production_plan(self):
|
def update_requested_qty_in_production_plan(self):
|
||||||
production_plans = []
|
production_plans = []
|
||||||
|
Loading…
Reference in New Issue
Block a user