test: SubcontractingReceipt
diff --git a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
index bc41dca..8680311 100644
--- a/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
+++ b/erpnext/subcontracting/doctype/subcontracting_receipt/test_subcontracting_receipt.py
@@ -1,9 +1,309 @@
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
-# import frappe
+
+import copy
+
+import frappe
from frappe.tests.utils import FrappeTestCase
+from frappe.utils import flt
+
+from erpnext.controllers.tests.test_subcontracting_controller import (
+ get_rm_items,
+ get_subcontracting_order,
+ make_bom_for_subcontracted_items,
+ make_raw_materials,
+ make_service_items,
+ make_stock_in_entry,
+ make_stock_transfer_entry,
+ make_subcontracted_item,
+ make_subcontracted_items,
+ set_backflush_based_on,
+)
+from erpnext.stock.doctype.item.test_item import make_item
+from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
+from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import make_subcontracting_receipt
class TestSubcontractingReceipt(FrappeTestCase):
- pass
+ def setUp(self):
+ make_subcontracted_items()
+ make_raw_materials()
+ make_service_items()
+ make_bom_for_subcontracted_items()
+
+ def test_subcontracting(self):
+ set_backflush_based_on("BOM")
+ make_stock_entry(
+ item_code="_Test Item", qty=100, target="_Test Warehouse 1 - _TC", basic_rate=100
+ )
+ make_stock_entry(
+ item_code="_Test Item Home Desktop 100",
+ qty=100,
+ target="_Test Warehouse 1 - _TC",
+ basic_rate=100,
+ )
+ service_items = [
+ {
+ "warehouse": "_Test Warehouse - _TC",
+ "item_code": "Subcontracted Service Item 1",
+ "qty": 10,
+ "rate": 100,
+ "fg_item": "_Test FG Item",
+ "fg_item_qty": 10,
+ },
+ ]
+ sco = get_subcontracting_order(service_items=service_items)
+ rm_items = get_rm_items(sco.supplied_items)
+ itemwise_details = make_stock_in_entry(rm_items=rm_items)
+ make_stock_transfer_entry(
+ sco_no=sco.name,
+ rm_items=rm_items,
+ itemwise_details=copy.deepcopy(itemwise_details),
+ )
+ scr = make_subcontracting_receipt(sco.name)
+ scr.save()
+ scr.submit()
+ rm_supp_cost = sum(item.amount for item in scr.get("supplied_items"))
+ self.assertEqual(scr.get("items")[0].rm_supp_cost, flt(rm_supp_cost))
+
+ def test_subcontracting_gle_fg_item_rate_zero(self):
+ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries
+
+ set_backflush_based_on("BOM")
+ make_stock_entry(
+ item_code="_Test Item",
+ target="Work In Progress - TCP1",
+ qty=100,
+ basic_rate=100,
+ company="_Test Company with perpetual inventory",
+ )
+ make_stock_entry(
+ item_code="_Test Item Home Desktop 100",
+ target="Work In Progress - TCP1",
+ qty=100,
+ basic_rate=100,
+ company="_Test Company with perpetual inventory",
+ )
+ service_items = [
+ {
+ "warehouse": "_Test Warehouse - _TC",
+ "item_code": "Subcontracted Service Item 1",
+ "qty": 10,
+ "rate": 0,
+ "fg_item": "_Test FG Item",
+ "fg_item_qty": 10,
+ },
+ ]
+ sco = get_subcontracting_order(service_items=service_items)
+ rm_items = get_rm_items(sco.supplied_items)
+ itemwise_details = make_stock_in_entry(rm_items=rm_items)
+ make_stock_transfer_entry(
+ sco_no=sco.name,
+ rm_items=rm_items,
+ itemwise_details=copy.deepcopy(itemwise_details),
+ )
+ scr = make_subcontracting_receipt(sco.name)
+ scr.save()
+ scr.submit()
+
+ gl_entries = get_gl_entries("Subcontracting Receipt", scr.name)
+ self.assertFalse(gl_entries)
+
+ def test_subcontracting_over_receipt(self):
+ """
+ Behaviour: Raise multiple SCRs against one SCO that in total
+ receive more than the required qty in the SCO.
+ Expected Result: Error Raised for Over Receipt against SCO.
+ """
+ from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import (
+ make_rm_stock_entry as make_subcontract_transfer_entry,
+ )
+ from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import (
+ make_subcontracting_receipt,
+ )
+ from erpnext.subcontracting.doctype.subcontracting_order.test_subcontracting_order import (
+ make_subcontracted_item,
+ )
+
+ set_backflush_based_on("Material Transferred for Subcontract")
+ item_code = "_Test Subcontracted FG Item 1"
+ make_subcontracted_item(item_code=item_code)
+ service_items = [
+ {
+ "warehouse": "_Test Warehouse - _TC",
+ "item_code": "Subcontracted Service Item 1",
+ "qty": 1,
+ "rate": 100,
+ "fg_item": "_Test Subcontracted FG Item 1",
+ "fg_item_qty": 1,
+ },
+ ]
+ sco = get_subcontracting_order(
+ service_items=service_items,
+ include_exploded_items=0,
+ )
+
+ # stock raw materials in a warehouse before transfer
+ make_stock_entry(
+ target="_Test Warehouse - _TC", item_code="Test Extra Item 1", qty=10, basic_rate=100
+ )
+ make_stock_entry(
+ target="_Test Warehouse - _TC", item_code="_Test FG Item", qty=1, basic_rate=100
+ )
+ make_stock_entry(
+ target="_Test Warehouse - _TC", item_code="Test Extra Item 2", qty=1, basic_rate=100
+ )
+
+ rm_items = [
+ {
+ "item_code": item_code,
+ "rm_item_code": sco.supplied_items[0].rm_item_code,
+ "item_name": "_Test FG Item",
+ "qty": sco.supplied_items[0].required_qty,
+ "warehouse": "_Test Warehouse - _TC",
+ "stock_uom": "Nos",
+ },
+ {
+ "item_code": item_code,
+ "rm_item_code": sco.supplied_items[1].rm_item_code,
+ "item_name": "Test Extra Item 1",
+ "qty": sco.supplied_items[1].required_qty,
+ "warehouse": "_Test Warehouse - _TC",
+ "stock_uom": "Nos",
+ },
+ ]
+ ste = frappe.get_doc(make_subcontract_transfer_entry(sco.name, rm_items))
+ ste.to_warehouse = "_Test Warehouse 1 - _TC"
+ ste.save()
+ ste.submit()
+
+ scr1 = make_subcontracting_receipt(sco.name)
+ scr2 = make_subcontracting_receipt(sco.name)
+
+ scr1.submit()
+ self.assertRaises(frappe.ValidationError, scr2.submit)
+
+ def test_subcontracted_scr_for_multi_transfer_batches(self):
+ from erpnext.subcontracting.doctype.subcontracting_order.subcontracting_order import (
+ make_rm_stock_entry,
+ make_subcontracting_receipt,
+ )
+
+ set_backflush_based_on("Material Transferred for Subcontract")
+ item_code = "_Test Subcontracted FG Item 3"
+
+ make_item(
+ "Sub Contracted Raw Material 3",
+ {"is_stock_item": 1, "is_sub_contracted_item": 1, "has_batch_no": 1, "create_new_batch": 1},
+ )
+
+ make_subcontracted_item(
+ item_code=item_code, has_batch_no=1, raw_materials=["Sub Contracted Raw Material 3"]
+ )
+
+ order_qty = 500
+ service_items = [
+ {
+ "warehouse": "_Test Warehouse - _TC",
+ "item_code": "Subcontracted Service Item 3",
+ "qty": order_qty,
+ "rate": 100,
+ "fg_item": "_Test Subcontracted FG Item 3",
+ "fg_item_qty": order_qty,
+ },
+ ]
+ sco = get_subcontracting_order(service_items=service_items)
+
+ ste1 = make_stock_entry(
+ target="_Test Warehouse - _TC",
+ item_code="Sub Contracted Raw Material 3",
+ qty=300,
+ basic_rate=100,
+ )
+ ste2 = make_stock_entry(
+ target="_Test Warehouse - _TC",
+ item_code="Sub Contracted Raw Material 3",
+ qty=200,
+ basic_rate=100,
+ )
+
+ transferred_batch = {ste1.items[0].batch_no: 300, ste2.items[0].batch_no: 200}
+
+ rm_items = [
+ {
+ "item_code": item_code,
+ "rm_item_code": "Sub Contracted Raw Material 3",
+ "item_name": "_Test Item",
+ "qty": 300,
+ "warehouse": "_Test Warehouse - _TC",
+ "stock_uom": "Nos",
+ "name": sco.supplied_items[0].name,
+ },
+ {
+ "item_code": item_code,
+ "rm_item_code": "Sub Contracted Raw Material 3",
+ "item_name": "_Test Item",
+ "qty": 200,
+ "warehouse": "_Test Warehouse - _TC",
+ "stock_uom": "Nos",
+ "name": sco.supplied_items[0].name,
+ },
+ ]
+
+ se = frappe.get_doc(make_rm_stock_entry(sco.name, rm_items))
+ self.assertEqual(len(se.items), 2)
+ se.items[0].batch_no = ste1.items[0].batch_no
+ se.items[1].batch_no = ste2.items[0].batch_no
+ se.submit()
+
+ supplied_qty = frappe.db.get_value(
+ "Subcontracting Order Supplied Item",
+ {"parent": sco.name, "rm_item_code": "Sub Contracted Raw Material 3"},
+ "supplied_qty",
+ )
+
+ self.assertEqual(supplied_qty, 500.00)
+
+ scr = make_subcontracting_receipt(sco.name)
+ scr.save()
+ self.assertEqual(len(scr.supplied_items), 2)
+
+ for row in scr.supplied_items:
+ self.assertEqual(transferred_batch.get(row.batch_no), row.consumed_qty)
+
+
+def get_items(**args):
+ args = frappe._dict(args)
+ return [
+ {
+ "conversion_factor": 1.0,
+ "description": "_Test Item",
+ "doctype": "Subcontracting Receipt Item",
+ "item_code": "_Test Item",
+ "item_name": "_Test Item",
+ "parentfield": "items",
+ "qty": 5.0,
+ "rate": 50.0,
+ "received_qty": 5.0,
+ "rejected_qty": 0.0,
+ "stock_uom": "_Test UOM",
+ "warehouse": args.warehouse or "_Test Warehouse - _TC",
+ "cost_center": args.cost_center or "Main - _TC",
+ },
+ {
+ "conversion_factor": 1.0,
+ "description": "_Test Item Home Desktop 100",
+ "doctype": "Subcontracting Receipt Item",
+ "item_code": "_Test Item Home Desktop 100",
+ "item_name": "_Test Item Home Desktop 100",
+ "parentfield": "items",
+ "qty": 5.0,
+ "rate": 50.0,
+ "received_qty": 5.0,
+ "rejected_qty": 0.0,
+ "stock_uom": "_Test UOM",
+ "warehouse": args.warehouse or "_Test Warehouse 1 - _TC",
+ "cost_center": args.cost_center or "Main - _TC",
+ },
+ ]