def test_create_two_quotations(self): from erpbee.stock.doctype.item.test_item import make_item first_item = make_item("_Test Laptop", {"is_stock_item": 1}) second_item = make_item("_Test CPU", {"is_stock_item": 1}) qo_item1 = [{ "item_code": first_item.item_code, "warehouse": "", "qty": 2, "rate": 400, "delivered_by_supplier": 1, "supplier": '_Test Supplier' }] qo_item2 = [{ "item_code": second_item.item_code, "warehouse": "_Test Warehouse - _TC", "qty": 2, "rate": 300, "conversion_factor": 1.0 }] first_qo = make_quotation(item_list=qo_item1, do_not_submit=True) first_qo.submit() sec_qo = make_quotation(item_list=qo_item2, do_not_submit=True) sec_qo.submit()
def setup_bom(**args): from erpbee.manufacturing.doctype.production_plan.test_production_plan import make_bom args = frappe._dict(args) if not frappe.db.exists('Item', args.item_code): make_item(args.item_code, {'is_stock_item': 1}) if not args.raw_materials: if not frappe.db.exists('Item', "Test Extra Item 1"): make_item("Test Extra Item N-1", { 'is_stock_item': 1, }) args.raw_materials = ['Test Extra Item N-1'] name = frappe.db.get_value('BOM', {'item': args.item_code}, 'name') if not name: bom_doc = make_bom(item=args.item_code, raw_materials=args.get("raw_materials"), routing=args.routing, with_operations=1) else: bom_doc = frappe.get_doc("BOM", name) return bom_doc
def test_work_order_with_non_transfer_item(self): items = { 'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0 } for item, allow_transfer in items.items(): make_item(item, {'include_item_in_manufacturing': allow_transfer}) fg_item = 'Finished Good Transfer Item' test_stock_entry.make_stock_entry(item_code="_Test FG Item", target="_Test Warehouse - _TC", qty=1, basic_rate=100) test_stock_entry.make_stock_entry(item_code="_Test FG Item 1", target="_Test Warehouse - _TC", qty=1, basic_rate=100) if not frappe.db.get_value('BOM', {'item': fg_item}): make_bom(item=fg_item, raw_materials=['_Test FG Item', '_Test FG Item 1']) wo = make_wo_order_test_record(production_item=fg_item) ste = frappe.get_doc( make_stock_entry(wo.name, "Material Transfer for Manufacture", 1)) ste.insert() ste.submit() self.assertEqual(len(ste.items), 1) ste1 = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1)) self.assertEqual(len(ste1.items), 3)
def test_mixed_conditions_for_item_group(self): for item in ["Mixed Cond Item 1", "Mixed Cond Item 2"]: make_item(item, {"item_group": "Products"}) make_item_price(item, "_Test Price List", 100) test_record = { "doctype": "Pricing Rule", "title": "_Test Pricing Rule for Item Group", "apply_on": "Item Group", "item_groups": [ { "item_group": "Products", }, { "item_group": "Seed", }, ], "selling": 1, "mixed_conditions": 1, "currency": "USD", "rate_or_discount": "Discount Percentage", "discount_percentage": 10, "applicable_for": "Customer Group", "customer_group": "All Customer Groups", "company": "_Test Company" } frappe.get_doc(test_record.copy()).insert() args = frappe._dict({ "item_code": "Mixed Cond Item 1", "item_group": "Products", "company": "_Test Company", "price_list": "_Test Price List", "currency": "_Test Currency", "doctype": "Sales Order", "conversion_rate": 1, "price_list_currency": "_Test Currency", "plc_conversion_rate": 1, "order_type": "Sales", "customer": "_Test Customer", "customer_group": "_Test Customer Group", "name": None }) details = get_item_details(args) self.assertEquals(details.get("discount_percentage"), 10)
def test_operation_time_with_batch_size(self): fg_item = "Test Batch Size Item For BOM" rm1 = "Test Batch Size Item RM 1 For BOM" for item in [ "Test Batch Size Item For BOM", "Test Batch Size Item RM 1 For BOM" ]: make_item(item, { "include_item_in_manufacturing": 1, "is_stock_item": 1 }) bom_name = frappe.db.get_value("BOM", { "item": fg_item, "is_active": 1, "with_operations": 1 }, "name") if not bom_name: bom = make_bom(item=fg_item, rate=1000, raw_materials=[rm1], do_not_save=True) bom.with_operations = 1 bom.append( "operations", { "operation": "_Test Operation 1", "workstation": "_Test Workstation 1", "description": "Test Data", "operating_cost": 100, "time_in_mins": 40, "batch_size": 5 }) bom.save() bom.submit() bom_name = bom.name work_order = make_wo_order_test_record(item=fg_item, planned_start_date=now(), qty=1, do_not_save=True) work_order.set_work_order_operations() work_order.save() self.assertEqual(work_order.operations[0].time_in_mins, 8.0) work_order1 = make_wo_order_test_record(item=fg_item, planned_start_date=now(), qty=5, do_not_save=True) work_order1.set_work_order_operations() work_order1.save() self.assertEqual(work_order1.operations[0].time_in_mins, 40.0)
def create_items(): items = [ "_Test Item for Reposting", "_Test Finished Item for Reposting", "_Test Subcontracted Item for Reposting", "_Test Bundled Item for Reposting" ] for d in items: properties = {"valuation_method": "FIFO"} if d == "_Test Bundled Item for Reposting": properties.update({"is_stock_item": 0}) elif d == "_Test Subcontracted Item for Reposting": properties.update({"is_sub_contracted_item": 1}) make_item(d, properties=properties) return items
def test_sales_return_for_non_bundled_items_full(self): from erpbee.stock.doctype.item.test_item import make_item company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company') make_item("Box", {'is_stock_item': 1}) make_stock_entry(item_code="Box", target="Stores - TCP1", qty=10, basic_rate=100) dn = create_delivery_note(item_code="Box", qty=5, rate=500, warehouse="Stores - TCP1", company=company, expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1") #return entry dn1 = create_delivery_note(item_code="Box", is_return=1, return_against=dn.name, qty=-5, rate=500, company=company, warehouse="Stores - TCP1", expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1", do_not_submit=1) dn1.items[0].dn_detail = dn.items[0].name dn1.submit() # hack because new_doc isn't considering is_return portion of status_updater returned = frappe.get_doc("Delivery Note", dn1.name) returned.update_prevdoc_status() dn.load_from_db() # Check if Original DN updated self.assertEqual(dn.items[0].returned_qty, 5) self.assertEqual(dn.per_returned, 100) self.assertEqual(dn.status, 'Return Issued')
def test_pricing_rule_for_transaction(self): make_item("Water Flask 1") frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule') make_pricing_rule(selling=1, min_qty=5, price_or_product_discount="Product", apply_on="Transaction", free_item="Water Flask 1", free_qty=1, free_item_rate=10) si = create_sales_invoice(qty=5, do_not_submit=True) self.assertEquals(len(si.items), 2) self.assertEquals(si.items[1].rate, 10) si1 = create_sales_invoice(qty=2, do_not_submit=True) self.assertEquals(len(si1.items), 1) for doc in [si, si1]: doc.delete()
def test_work_order_with_non_stock_item(self): items = { 'Finished Good Test Item For non stock': 1, '_Test FG Item': 1, '_Test FG Non Stock Item': 0 } for item, is_stock_item in items.items(): make_item(item, {'is_stock_item': is_stock_item}) if not frappe.db.get_value('Item Price', {'item_code': '_Test FG Non Stock Item'}): frappe.get_doc({ 'doctype': 'Item Price', 'item_code': '_Test FG Non Stock Item', 'price_list_rate': 1000, 'price_list': 'Standard Buying' }).insert(ignore_permissions=True) fg_item = 'Finished Good Test Item For non stock' test_stock_entry.make_stock_entry(item_code="_Test FG Item", target="_Test Warehouse - _TC", qty=1, basic_rate=100) if not frappe.db.get_value('BOM', {'item': fg_item}): make_bom( item=fg_item, rate=1000, raw_materials=['_Test FG Item', '_Test FG Non Stock Item']) wo = make_wo_order_test_record(production_item=fg_item) se = frappe.get_doc( make_stock_entry(wo.name, "Material Transfer for Manufacture", 1)) se.insert() se.submit() ste = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1)) ste.insert() self.assertEqual(len(ste.additional_costs), 1) self.assertEqual(ste.total_additional_costs, 1000)
def make_subcontracted_item(**args): from erpbee.manufacturing.doctype.production_plan.test_production_plan import make_bom args = frappe._dict(args) if not frappe.db.exists('Item', args.item_code): make_item( args.item_code, { 'is_stock_item': 1, 'is_sub_contracted_item': 1, 'has_batch_no': args.get("has_batch_no") or 0 }) if not args.raw_materials: if not frappe.db.exists('Item', "Test Extra Item 1"): make_item("Test Extra Item 1", { 'is_stock_item': 1, }) if not frappe.db.exists('Item', "Test Extra Item 2"): make_item("Test Extra Item 2", { 'is_stock_item': 1, }) args.raw_materials = ['_Test FG Item', 'Test Extra Item 1'] if not frappe.db.get_value('BOM', {'item': args.item_code}, 'name'): make_bom(item=args.item_code, raw_materials=args.get("raw_materials"))
def test_make_multi_uom_supplier_quotation(self): item_code = "_Test Multi UOM RFQ Item" if not frappe.db.exists('Item', item_code): item = make_item(item_code, {'stock_uom': '_Test UOM'}) row = item.append('uoms', {'uom': 'Kg', 'conversion_factor': 2}) row.db_update() rfq = make_request_for_quotation(item_code="_Test Multi UOM RFQ Item", uom="Kg", conversion_factor=2) rfq.get('items')[0].rate = 100 rfq.supplier = rfq.suppliers[0].supplier self.assertEqual(rfq.items[0].stock_qty, 10) supplier_quotation_name = create_supplier_quotation(rfq) supplier_quotation = frappe.get_doc('Supplier Quotation', supplier_quotation_name) self.assertEqual(supplier_quotation.items[0].qty, 5) self.assertEqual(supplier_quotation.items[0].stock_qty, 10)
def test_item_price_with_pricing_rule(self): item = make_item("Water Flask") make_item_price("Water Flask", "_Test Price List", 100) pricing_rule_record = { "doctype": "Pricing Rule", "title": "_Test Water Flask Rule", "apply_on": "Item Code", "items": [{ "item_code": "Water Flask", }], "selling": 1, "currency": "INR", "rate_or_discount": "Rate", "rate": 0, "margin_type": "Percentage", "margin_rate_or_amount": 2, "company": "_Test Company" } rule = frappe.get_doc(pricing_rule_record) rule.insert() si = create_sales_invoice(do_not_save=True, item_code="Water Flask") si.selling_price_list = "_Test Price List" si.save() # If rate in Rule is 0, give preference to Item Price if it exists self.assertEqual(si.items[0].price_list_rate, 100) self.assertEqual(si.items[0].margin_rate_or_amount, 2) self.assertEqual(si.items[0].rate_with_margin, 102) self.assertEqual(si.items[0].rate, 102) si.delete() rule.delete() frappe.get_doc("Item Price", {"item_code": "Water Flask"}).delete() item.delete()
def test_backflushed_based_on_for_multiple_batches(self): item_code = "_Test Subcontracted FG Item 2" make_item('Sub Contracted Raw Material 2', { 'is_stock_item': 1, 'is_sub_contracted_item': 1 }) make_subcontracted_item( item_code=item_code, has_batch_no=1, create_new_batch=1, raw_materials=["Sub Contracted Raw Material 2"]) update_backflush_based_on("Material Transferred for Subcontract") order_qty = 500 po = create_purchase_order( item_code=item_code, qty=order_qty, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") make_stock_entry(target="_Test Warehouse - _TC", item_code="Sub Contracted Raw Material 2", qty=552, basic_rate=100) rm_items = [{ "item_code": item_code, "rm_item_code": "Sub Contracted Raw Material 2", "item_name": "_Test Item", "qty": 552, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }] rm_item_string = json.dumps(rm_items) se = frappe.get_doc( make_subcontract_transfer_entry(po.name, rm_item_string)) se.submit() for batch in ["ABCD1", "ABCD2", "ABCD3", "ABCD4"]: make_new_batch(batch_id=batch, item_code=item_code) pr = make_purchase_receipt(po.name) # partial receipt pr.get('items')[0].qty = 30 pr.get('items')[0].batch_no = "ABCD1" purchase_order = po.name purchase_order_item = po.items[0].name for batch_no, qty in {"ABCD2": 60, "ABCD3": 70, "ABCD4": 40}.items(): pr.append( "items", { "item_code": pr.get('items')[0].item_code, "item_name": pr.get('items')[0].item_name, "uom": pr.get('items')[0].uom, "stock_uom": pr.get('items')[0].stock_uom, "warehouse": pr.get('items')[0].warehouse, "conversion_factor": pr.get('items')[0].conversion_factor, "cost_center": pr.get('items')[0].cost_center, "rate": pr.get('items')[0].rate, "qty": qty, "batch_no": batch_no, "purchase_order": purchase_order, "purchase_order_item": purchase_order_item }) pr.submit() pr1 = make_purchase_receipt(po.name) pr1.get('items')[0].qty = 300 pr1.get('items')[0].batch_no = "ABCD1" pr1.save() pr_key = ("Sub Contracted Raw Material 2", po.name) consumed_qty = get_backflushed_subcontracted_raw_materials( [po.name]).get(pr_key) self.assertTrue(pr1.supplied_items[0].consumed_qty > 0) self.assertTrue(pr1.supplied_items[0].consumed_qty, flt(552.0) - flt(consumed_qty)) update_backflush_based_on("BOM")
def test_subcontractor_sourced_item(self): item_code = "_Test Subcontracted FG Item 1" if not frappe.db.exists('Item', item_code): make_item( item_code, { 'is_stock_item': 1, 'is_sub_contracted_item': 1, 'stock_uom': 'Nos' }) if not frappe.db.exists('Item', "Test Extra Item 1"): make_item("Test Extra Item 1", { 'is_stock_item': 1, 'stock_uom': 'Nos' }) if not frappe.db.exists('Item', "Test Extra Item 2"): make_item("Test Extra Item 2", { 'is_stock_item': 1, 'stock_uom': 'Nos' }) if not frappe.db.exists('Item', "Test Extra Item 3"): make_item("Test Extra Item 3", { 'is_stock_item': 1, 'stock_uom': 'Nos' }) bom = frappe.get_doc({ 'doctype': 'BOM', 'is_default': 1, 'item': item_code, 'currency': 'USD', 'quantity': 1, 'company': '_Test Company' }) for item in ["Test Extra Item 1", "Test Extra Item 2"]: item_doc = frappe.get_doc('Item', item) bom.append( 'items', { 'item_code': item, 'qty': 1, 'uom': item_doc.stock_uom, 'stock_uom': item_doc.stock_uom, 'rate': item_doc.valuation_rate }) bom.append( 'items', { 'item_code': "Test Extra Item 3", 'qty': 1, 'uom': item_doc.stock_uom, 'stock_uom': item_doc.stock_uom, 'rate': 0, 'sourced_by_supplier': 1 }) bom.insert(ignore_permissions=True) bom.update_cost() bom.submit() # test that sourced_by_supplier rate is zero even after updating cost self.assertEqual(bom.items[2].rate, 0) # test in Purchase Order sourced_by_supplier is not added to Supplied Item po = create_purchase_order( item_code=item_code, qty=1, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") bom_items = sorted( [d.item_code for d in bom.items if d.sourced_by_supplier != 1]) supplied_items = sorted([d.rm_item_code for d in po.supplied_items]) self.assertEquals(bom_items, supplied_items)
def test_supplied_qty_against_subcontracted_po(self): item_code = "_Test Subcontracted FG Item 5" make_item('Sub Contracted Raw Material 4', { 'is_stock_item': 1, 'is_sub_contracted_item': 1 }) make_subcontracted_item( item_code=item_code, raw_materials=["Sub Contracted Raw Material 4"]) update_backflush_based_on("Material Transferred for Subcontract") order_qty = 250 po = create_purchase_order( item_code=item_code, qty=order_qty, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC", do_not_save=True) # Add same subcontracted items multiple times po.append( "items", { "item_code": item_code, "qty": order_qty, "schedule_date": add_days(nowdate(), 1), "warehouse": "_Test Warehouse - _TC" }) po.set_missing_values() po.submit() # Material receipt entry for the raw materials which will be send to supplier make_stock_entry(target="_Test Warehouse - _TC", item_code="Sub Contracted Raw Material 4", qty=500, basic_rate=100) rm_items = [ { "item_code": item_code, "rm_item_code": "Sub Contracted Raw Material 4", "item_name": "_Test Item", "qty": 250, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos", "name": po.supplied_items[0].name }, { "item_code": item_code, "rm_item_code": "Sub Contracted Raw Material 4", "item_name": "_Test Item", "qty": 250, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, ] # Raw Materials transfer entry from stores to supplier's warehouse rm_item_string = json.dumps(rm_items) se = frappe.get_doc( make_subcontract_transfer_entry(po.name, rm_item_string)) se.submit() # Test po_detail field has value or not for item_row in se.items: self.assertEqual(item_row.po_detail, po.supplied_items[item_row.idx - 1].name) po_doc = frappe.get_doc("Purchase Order", po.name) for row in po_doc.supplied_items: # Valid that whether transferred quantity is matching with supplied qty or not in the purchase order self.assertEqual(row.supplied_qty, 250.0) update_backflush_based_on("BOM")
def test_gstr_3b_report(self): month_number_mapping = { 1: "January", 2: "February", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "August", 9: "September", 10: "October", 11: "November", 12: "December" } frappe.set_user("Administrator") frappe.db.sql( "delete from `tabSales Invoice` where company='_Test Company GST'") frappe.db.sql( "delete from `tabPurchase Invoice` where company='_Test Company GST'" ) frappe.db.sql( "delete from `tabGSTR 3B Report` where company='_Test Company GST'" ) make_company() make_item("Milk", properties={ "is_nil_exempt": 1, "standard_rate": 0.000000 }) set_account_heads() make_customers() make_suppliers() make_sales_invoice() create_purchase_invoices() if frappe.db.exists("GSTR 3B Report", "GSTR3B-March-2019-_Test Address-Billing"): report = frappe.get_doc("GSTR 3B Report", "GSTR3B-March-2019-_Test Address-Billing") report.save() else: report = frappe.get_doc({ "doctype": "GSTR 3B Report", "company": "_Test Company GST", "company_address": "_Test Address-Billing", "year": getdate().year, "month": month_number_mapping.get(getdate().month) }).insert() output = json.loads(report.json_output) self.assertEqual(output["sup_details"]["osup_det"]["iamt"], 36), self.assertEqual(output["sup_details"]["osup_zero"]["iamt"], 18), self.assertEqual(output["inter_sup"]["unreg_details"][0]["iamt"], 18), self.assertEqual(output["sup_details"]["osup_nil_exmp"]["txval"], 100), self.assertEqual(output["inward_sup"]["isup_details"][0]["inter"], 250) self.assertEqual(output["itc_elg"]["itc_avl"][4]["samt"], 22.50) self.assertEqual(output["itc_elg"]["itc_avl"][4]["camt"], 22.50)
def make_batch_item(cls, item_name): from erpbee.stock.doctype.item.test_item import make_item if not frappe.db.exists(item_name): return make_item( item_name, dict(has_batch_no=1, create_new_batch=1, is_stock_item=1))
def test_update_child_with_tax_template(self): """ Test Action: Create a PO with one item having its tax account head already in the PO. Add the same item + new item with tax template via Update Items. Expected result: First Item's tax row is updated. New tax row is added for second Item. """ if not frappe.db.exists("Item", "Test Item with Tax"): make_item("Test Item with Tax", { 'is_stock_item': 1, }) if not frappe.db.exists("Item Tax Template", {"title": 'Test Update Items Template'}): frappe.get_doc({ 'doctype': 'Item Tax Template', 'title': 'Test Update Items Template', 'company': '_Test Company', 'taxes': [{ 'tax_type': "_Test Account Service Tax - _TC", 'tax_rate': 10, }] }).insert() new_item_with_tax = frappe.get_doc("Item", "Test Item with Tax") new_item_with_tax.append( "taxes", { "item_tax_template": "Test Update Items Template", "valid_from": nowdate() }) new_item_with_tax.save() tax_template = "_Test Account Excise Duty @ 10" item = "_Test Item Home Desktop 100" if not frappe.db.exists("Item Tax", { "parent": item, "item_tax_template": tax_template }): item_doc = frappe.get_doc("Item", item) item_doc.append("taxes", { "item_tax_template": tax_template, "valid_from": nowdate() }) item_doc.save() else: # update valid from frappe.db.sql( """UPDATE `tabItem Tax` set valid_from = CURDATE() where parent = %(item)s and item_tax_template = %(tax)s""", { "item": item, "tax": tax_template }) po = create_purchase_order(item_code=item, qty=1, do_not_save=1) po.append( "taxes", { "account_head": "_Test Account Excise Duty - _TC", "charge_type": "On Net Total", "cost_center": "_Test Cost Center - _TC", "description": "Excise Duty", "doctype": "Purchase Taxes and Charges", "rate": 10 }) po.insert() po.submit() self.assertEqual(po.taxes[0].tax_amount, 50) self.assertEqual(po.taxes[0].total, 550) items = json.dumps([ { 'item_code': item, 'rate': 500, 'qty': 1, 'docname': po.items[0].name }, { 'item_code': item, 'rate': 100, 'qty': 1 }, # added item whose tax account head already exists in PO { 'item_code': new_item_with_tax.name, 'rate': 100, 'qty': 1 } # added item whose tax account head is missing in PO ]) update_child_qty_rate('Purchase Order', items, po.name) po.reload() self.assertEqual(po.taxes[0].tax_amount, 70) self.assertEqual(po.taxes[0].total, 770) self.assertEqual(po.taxes[1].account_head, "_Test Account Service Tax - _TC") self.assertEqual(po.taxes[1].tax_amount, 70) self.assertEqual(po.taxes[1].total, 840) # teardown frappe.db.sql( """UPDATE `tabItem Tax` set valid_from = NULL where parent = %(item)s and item_tax_template = %(tax)s""", { "item": item, "tax": tax_template }) po.cancel() po.delete() new_item_with_tax.delete() frappe.get_doc("Item Tax Template", "Test Update Items Template").delete()
def test_backflush_based_on_stock_entry(self): item_code = "_Test Subcontracted FG Item 1" make_subcontracted_item(item_code=item_code) make_item('Sub Contracted Raw Material 1', { 'is_stock_item': 1, 'is_sub_contracted_item': 1 }) update_backflush_based_on("Material Transferred for Subcontract") order_qty = 5 po = create_purchase_order( item_code=item_code, qty=order_qty, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100", qty=10, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="Test Extra Item 1", qty=100, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="Test Extra Item 2", qty=10, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="Sub Contracted Raw Material 1", qty=10, basic_rate=100) rm_items = [{ "item_code": item_code, "rm_item_code": "Sub Contracted Raw Material 1", "item_name": "_Test Item", "qty": 10, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { "item_code": item_code, "rm_item_code": "_Test Item Home Desktop 100", "item_name": "_Test Item Home Desktop 100", "qty": 20, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { "item_code": item_code, "rm_item_code": "Test Extra Item 1", "item_name": "Test Extra Item 1", "qty": 10, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { 'item_code': item_code, 'rm_item_code': 'Test Extra Item 2', 'stock_uom': 'Nos', 'qty': 10, 'warehouse': '_Test Warehouse - _TC', 'item_name': 'Test Extra Item 2' }] rm_item_string = json.dumps(rm_items) se = frappe.get_doc( make_subcontract_transfer_entry(po.name, rm_item_string)) se.submit() pr = make_purchase_receipt(po.name) received_qty = 2 # partial receipt pr.get('items')[0].qty = received_qty pr.save() pr.submit() transferred_items = sorted([ d.item_code for d in se.get('items') if se.purchase_order == po.name ]) issued_items = sorted( [d.rm_item_code for d in pr.get('supplied_items')]) self.assertEquals(transferred_items, issued_items) self.assertEquals(pr.get('items')[0].rm_supp_cost, 2000) transferred_rm_map = frappe._dict() for item in rm_items: transferred_rm_map[item.get('rm_item_code')] = item for item in pr.get('supplied_items'): self.assertEqual( item.get('required_qty'), (transferred_rm_map[item.get('rm_item_code')].get('qty') / order_qty) * received_qty) update_backflush_based_on("BOM")