mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-03 05:28:27 +00:00
test(manufacturing): add test to validate the sales order references for sub assembly items
(cherry picked from commit 341dc4be7a)
# Conflicts:
# erpnext/manufacturing/doctype/production_plan/test_production_plan.py
This commit is contained in:
@@ -565,6 +565,193 @@ class TestProductionPlan(FrappeTestCase):
|
||||
self.assertEqual(po_doc.items[0].fg_item, fg_item)
|
||||
self.assertEqual(po_doc.items[0].item_code, service_item)
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
po_doc.items[0].qty = 11
|
||||
po_doc.items[0].fg_item_qty = 11
|
||||
|
||||
# Test - 1 : Quantity of item cannot exceed quantity in production plan
|
||||
self.assertRaises(OverAllowanceError, po_doc.submit)
|
||||
|
||||
po_doc.cancel()
|
||||
po_doc = frappe.copy_doc(po_doc)
|
||||
po_doc.items[0].qty = 5
|
||||
po_doc.items[0].fg_item_qty = 5
|
||||
po_doc.submit()
|
||||
make_purchase_receipt_from_po(po_doc)
|
||||
|
||||
plan.reload()
|
||||
plan.make_work_order()
|
||||
po = frappe.db.get_value("Purchase Order Item", {"production_plan": plan.name}, "parent")
|
||||
po_doc = frappe.get_doc("Purchase Order", po)
|
||||
|
||||
# Test - 2 : Quantity of item in new PO should be the available quantity from Production Plan
|
||||
self.assertEqual(po_doc.items[0].qty, 5.0)
|
||||
|
||||
po_doc.submit()
|
||||
plan.make_work_order()
|
||||
|
||||
# Test - 3 : New POs should not be created since the quantity is already fulfilled
|
||||
self.assertEqual(
|
||||
frappe.db.count("Purchase Order Item", {"production_plan": plan.name, "docstatus": 1}), 2
|
||||
) # 2 since we have already created and submitted 2 POs
|
||||
|
||||
def test_sales_order_references_for_sub_assembly_items(self):
|
||||
"""
|
||||
Test that Sales Order and Sales Order Item references in Work Order and Purchase Order
|
||||
are correctly propagated from the Production Plan.
|
||||
"""
|
||||
|
||||
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
||||
|
||||
# Setup Test Items & BOM
|
||||
fg_item = "Test FG Good Item"
|
||||
sub_assembly_item1 = "Test Sub Assembly Item 1"
|
||||
sub_assembly_item2 = "Test Sub Assembly Item 2"
|
||||
|
||||
bom_tree = {
|
||||
fg_item: {
|
||||
sub_assembly_item1: {"Test Raw Material 1": {}},
|
||||
sub_assembly_item2: {"Test Raw Material 2": {}},
|
||||
}
|
||||
}
|
||||
|
||||
create_nested_bom(bom_tree, prefix="")
|
||||
|
||||
# Create Sales Order
|
||||
so = make_sales_order(item_code=fg_item, qty=10)
|
||||
so_item_row = so.items[0].name
|
||||
|
||||
# Create Production Plan from Sales Order
|
||||
production_plan = frappe.new_doc("Production Plan")
|
||||
production_plan.company = so.company
|
||||
production_plan.get_items_from = "Sales Order"
|
||||
production_plan.item_code = fg_item
|
||||
|
||||
production_plan.get_open_sales_orders()
|
||||
self.assertEqual(production_plan.sales_orders[0].sales_order, so.name)
|
||||
|
||||
production_plan.get_so_items()
|
||||
|
||||
production_plan.skip_available_sub_assembly_item = 0
|
||||
production_plan.get_sub_assembly_items()
|
||||
|
||||
self.assertEqual(len(production_plan.sub_assembly_items), 2)
|
||||
|
||||
# Validate Sales Order references in Sub Assembly Items
|
||||
for row in production_plan.sub_assembly_items:
|
||||
if row.production_item == sub_assembly_item1:
|
||||
row.supplier = "_Test Supplier"
|
||||
row.type_of_manufacturing = "Subcontract"
|
||||
|
||||
self.assertEqual(row.sales_order, so.name)
|
||||
self.assertEqual(row.sales_order_item, so_item_row)
|
||||
|
||||
# Submit Production Plan
|
||||
production_plan.save()
|
||||
production_plan.submit()
|
||||
production_plan.make_work_order()
|
||||
|
||||
# Validate Purchase Order (Subcontracted Item)
|
||||
po_items = frappe.get_all(
|
||||
"Purchase Order Item",
|
||||
{
|
||||
"production_plan": production_plan.name,
|
||||
"fg_item": sub_assembly_item1,
|
||||
},
|
||||
["sales_order", "sales_order_item"],
|
||||
)
|
||||
|
||||
self.assertTrue(po_items)
|
||||
self.assertEqual(po_items[0].sales_order, so.name)
|
||||
self.assertEqual(po_items[0].sales_order_item, so_item_row)
|
||||
|
||||
# Validate Work Order (In-house Item)
|
||||
work_orders = frappe.get_all(
|
||||
"Work Order",
|
||||
{
|
||||
"production_plan": production_plan.name,
|
||||
"production_item": sub_assembly_item2,
|
||||
},
|
||||
["sales_order", "sales_order_item"],
|
||||
)
|
||||
|
||||
self.assertTrue(work_orders)
|
||||
self.assertEqual(work_orders[0].sales_order, so.name)
|
||||
self.assertEqual(work_orders[0].sales_order_item, so_item_row)
|
||||
|
||||
def test_production_plan_for_mr_items(self):
|
||||
from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
|
||||
|
||||
def setup_item(fg_item):
|
||||
item_doc = frappe.get_doc("Item", fg_item)
|
||||
company = "_Test Company"
|
||||
|
||||
item_doc.is_sub_contracted_item = 1
|
||||
for row in item_doc.item_defaults:
|
||||
if row.company == company and not row.default_supplier:
|
||||
row.default_supplier = "_Test Supplier"
|
||||
|
||||
if not item_doc.item_defaults:
|
||||
item_doc.append("item_defaults", {"company": company, "default_supplier": "_Test Supplier"})
|
||||
|
||||
item_doc.save()
|
||||
|
||||
fg_item = "Test Motherboard 1"
|
||||
fg_item_2 = "Test CPU 1"
|
||||
bom_tree_1 = {
|
||||
"Test Laptop 1": {fg_item: {"Test Motherboard Wires 1": {}}, fg_item_2: {"Test Pins 1": {}}}
|
||||
}
|
||||
create_nested_bom(bom_tree_1, prefix="")
|
||||
|
||||
setup_item(fg_item)
|
||||
setup_item(fg_item_2)
|
||||
|
||||
plan = create_production_plan(
|
||||
item_code="Test Laptop 1", planned_qty=10, use_multi_level_bom=1, do_not_submit=True
|
||||
)
|
||||
plan.get_sub_assembly_items()
|
||||
plan.set_default_supplier_for_subcontracting_order()
|
||||
plan.submit()
|
||||
|
||||
plan.make_material_request()
|
||||
mr_item = frappe.db.get_value("Material Request Item", {"production_plan": plan.name}, "parent")
|
||||
mr_doc = frappe.get_doc("Material Request", mr_item)
|
||||
mr_doc.submit()
|
||||
plan.reload()
|
||||
plan.make_material_request()
|
||||
|
||||
# Test 1 : No more MRs should be created as quantity from Production Plan is fulfilled
|
||||
self.assertEqual(frappe.db.count("Material Request Item", {"production_plan": plan.name}), 2)
|
||||
|
||||
mr_doc.cancel()
|
||||
plan.reload()
|
||||
|
||||
# Test 2 : Requested quantity should be updated in Production Plan on cancellation of MR
|
||||
self.assertEqual(plan.mr_items[0].requested_qty, 0)
|
||||
|
||||
plan.make_material_request()
|
||||
mr_item = frappe.db.get_value("Material Request Item", {"production_plan": plan.name}, "parent")
|
||||
mr_doc = frappe.get_doc("Material Request", mr_item)
|
||||
mr_doc.items[0].qty = 5
|
||||
mr_doc.submit()
|
||||
plan.reload()
|
||||
plan.make_material_request()
|
||||
mr_item = frappe.db.get_value("Material Request Item", {"production_plan": plan.name}, "parent")
|
||||
mr_doc = frappe.get_doc("Material Request", mr_item)
|
||||
|
||||
# Test 3 : Since Item 2 has been fully requested, it should not be included in the new MR by default
|
||||
self.assertEqual(len(mr_doc.items), 1)
|
||||
|
||||
# Test 4 : Quantity in new MR should be the available quantity from Production Plan
|
||||
self.assertEqual(mr_doc.items[0].qty, 5.0)
|
||||
|
||||
mr_doc.items[0].qty = 6
|
||||
|
||||
# Test 5 : Quantity of item cannot exceed available quantity from Production Plan
|
||||
self.assertRaises(frappe.ValidationError, mr_doc.submit)
|
||||
|
||||
>>>>>>> 341dc4be7a (test(manufacturing): add test to validate the sales order references for sub assembly items)
|
||||
def test_production_plan_combine_subassembly(self):
|
||||
"""
|
||||
Test combining Sub assembly items belonging to the same BOM in Prod Plan.
|
||||
|
||||
Reference in New Issue
Block a user