fix: incorrect material request quantity in Production Plan (#38566)
This commit is contained in:
parent
84ee50e492
commit
aaa9036eca
@ -1597,19 +1597,23 @@ def get_materials_from_other_locations(item, warehouses, new_mr_items, company):
|
|||||||
)
|
)
|
||||||
|
|
||||||
locations = get_available_item_locations(
|
locations = get_available_item_locations(
|
||||||
item.get("item_code"), warehouses, item.get("quantity"), company, ignore_validation=True
|
item.get("item_code"),
|
||||||
|
warehouses,
|
||||||
|
item.get("quantity") * item.get("conversion_factor"),
|
||||||
|
company,
|
||||||
|
ignore_validation=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
required_qty = item.get("quantity")
|
required_qty = item.get("quantity")
|
||||||
|
if item.get("conversion_factor") and item.get("purchase_uom") != item.get("stock_uom"):
|
||||||
|
# Convert qty to stock UOM
|
||||||
|
required_qty = required_qty * item.get("conversion_factor")
|
||||||
|
|
||||||
# get available material by transferring to production warehouse
|
# get available material by transferring to production warehouse
|
||||||
for d in locations:
|
for d in locations:
|
||||||
if required_qty <= 0:
|
if required_qty <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
conversion_factor = 1.0
|
|
||||||
if purchase_uom != stock_uom and purchase_uom == item["uom"]:
|
|
||||||
conversion_factor = get_uom_conversion_factor(item["item_code"], item["uom"])
|
|
||||||
|
|
||||||
new_dict = copy.deepcopy(item)
|
new_dict = copy.deepcopy(item)
|
||||||
quantity = required_qty if d.get("qty") > required_qty else d.get("qty")
|
quantity = required_qty if d.get("qty") > required_qty else d.get("qty")
|
||||||
|
|
||||||
@ -1619,10 +1623,11 @@ def get_materials_from_other_locations(item, warehouses, new_mr_items, company):
|
|||||||
"material_request_type": "Material Transfer",
|
"material_request_type": "Material Transfer",
|
||||||
"uom": new_dict.get("stock_uom"), # internal transfer should be in stock UOM
|
"uom": new_dict.get("stock_uom"), # internal transfer should be in stock UOM
|
||||||
"from_warehouse": d.get("warehouse"),
|
"from_warehouse": d.get("warehouse"),
|
||||||
|
"conversion_factor": 1.0,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
required_qty -= quantity / conversion_factor
|
required_qty -= quantity
|
||||||
new_mr_items.append(new_dict)
|
new_mr_items.append(new_dict)
|
||||||
|
|
||||||
# raise purchase request for remaining qty
|
# raise purchase request for remaining qty
|
||||||
@ -1634,7 +1639,7 @@ def get_materials_from_other_locations(item, warehouses, new_mr_items, company):
|
|||||||
if frappe.db.get_value("UOM", purchase_uom, "must_be_whole_number"):
|
if frappe.db.get_value("UOM", purchase_uom, "must_be_whole_number"):
|
||||||
required_qty = ceil(required_qty)
|
required_qty = ceil(required_qty)
|
||||||
|
|
||||||
item["quantity"] = required_qty
|
item["quantity"] = required_qty / item.get("conversion_factor")
|
||||||
|
|
||||||
new_mr_items.append(item)
|
new_mr_items.append(item)
|
||||||
|
|
||||||
|
@ -1283,12 +1283,14 @@ class TestProductionPlan(FrappeTestCase):
|
|||||||
for row in items:
|
for row in items:
|
||||||
row = frappe._dict(row)
|
row = frappe._dict(row)
|
||||||
if row.material_request_type == "Material Transfer":
|
if row.material_request_type == "Material Transfer":
|
||||||
|
self.assertTrue(row.uom == row.stock_uom)
|
||||||
self.assertTrue(row.from_warehouse in [wh1, wh2])
|
self.assertTrue(row.from_warehouse in [wh1, wh2])
|
||||||
self.assertEqual(row.quantity, 2)
|
self.assertEqual(row.quantity, 2)
|
||||||
|
|
||||||
if row.material_request_type == "Purchase":
|
if row.material_request_type == "Purchase":
|
||||||
|
self.assertTrue(row.uom != row.stock_uom)
|
||||||
self.assertTrue(row.warehouse == mrp_warhouse)
|
self.assertTrue(row.warehouse == mrp_warhouse)
|
||||||
self.assertEqual(row.quantity, 12)
|
self.assertEqual(row.quantity, 12.0)
|
||||||
|
|
||||||
def test_mr_qty_for_same_rm_with_different_sub_assemblies(self):
|
def test_mr_qty_for_same_rm_with_different_sub_assemblies(self):
|
||||||
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
||||||
@ -1404,6 +1406,58 @@ class TestProductionPlan(FrappeTestCase):
|
|||||||
|
|
||||||
self.assertEqual(after_qty, before_qty)
|
self.assertEqual(after_qty, before_qty)
|
||||||
|
|
||||||
|
def test_material_request_qty_purchase_and_material_transfer(self):
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
store_warehouse = create_warehouse("Store Warehouse", company="_Test Company")
|
||||||
|
rm_warehouse = create_warehouse("RM Warehouse", company="_Test Company")
|
||||||
|
|
||||||
|
make_stock_entry(
|
||||||
|
item_code=bom_item,
|
||||||
|
qty=60,
|
||||||
|
target=store_warehouse,
|
||||||
|
rate=99,
|
||||||
|
)
|
||||||
|
|
||||||
|
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": 10})
|
||||||
|
doc.save()
|
||||||
|
|
||||||
|
make_bom(item=fg_item, raw_materials=[bom_item], source_warehouse="_Test Warehouse - _TC")
|
||||||
|
|
||||||
|
pln = create_production_plan(
|
||||||
|
item_code=fg_item, planned_qty=10, stock_uom="_Test UOM 1", do_not_submit=1
|
||||||
|
)
|
||||||
|
|
||||||
|
pln.for_warehouse = rm_warehouse
|
||||||
|
items = get_items_for_material_requests(
|
||||||
|
pln.as_dict(), warehouses=[{"warehouse": store_warehouse}]
|
||||||
|
)
|
||||||
|
|
||||||
|
for row in items:
|
||||||
|
self.assertEqual(row.get("quantity"), 10.0)
|
||||||
|
self.assertEqual(row.get("material_request_type"), "Material Transfer")
|
||||||
|
self.assertEqual(row.get("uom"), "_Test UOM 1")
|
||||||
|
self.assertEqual(row.get("from_warehouse"), store_warehouse)
|
||||||
|
self.assertEqual(row.get("conversion_factor"), 1.0)
|
||||||
|
|
||||||
|
items = get_items_for_material_requests(
|
||||||
|
pln.as_dict(), warehouses=[{"warehouse": pln.for_warehouse}]
|
||||||
|
)
|
||||||
|
|
||||||
|
for row in items:
|
||||||
|
self.assertEqual(row.get("quantity"), 1.0)
|
||||||
|
self.assertEqual(row.get("material_request_type"), "Purchase")
|
||||||
|
self.assertEqual(row.get("uom"), "Nos")
|
||||||
|
self.assertEqual(row.get("conversion_factor"), 10.0)
|
||||||
|
|
||||||
|
|
||||||
def create_production_plan(**args):
|
def create_production_plan(**args):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user