def test_subcontracting_over_receipt(self): """ Behaviour: Raise multiple PRs against one PO that in total receive more than the required qty in the PO. Expected Result: Error Raised for Over Receipt against PO. """ from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.buying.doctype.purchase_order.test_purchase_order import (update_backflush_based_on, make_subcontracted_item, create_purchase_order) from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, make_rm_stock_entry as make_subcontract_transfer_entry) update_backflush_based_on("Material Transferred for Subcontract") item_code = "_Test Subcontracted FG Item 1" make_subcontracted_item(item_code=item_code) po = create_purchase_order(item_code=item_code, qty=1, include_exploded_items=0, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") #stock raw materials in a warehouse before transfer se1 = make_stock_entry(target="_Test Warehouse - _TC", item_code = "Test Extra Item 1", qty=10, basic_rate=100) se2 = make_stock_entry(target="_Test Warehouse - _TC", item_code = "_Test FG Item", qty=1, basic_rate=100) rm_items = [ { "item_code": item_code, "rm_item_code": po.supplied_items[0].rm_item_code, "item_name": "_Test FG Item", "qty": po.supplied_items[0].required_qty, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { "item_code": item_code, "rm_item_code": po.supplied_items[1].rm_item_code, "item_name": "Test Extra Item 1", "qty": po.supplied_items[1].required_qty, "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.to_warehouse = "_Test Warehouse 1 - _TC" se.save() se.submit() pr1 = make_purchase_receipt(po.name) pr2 = make_purchase_receipt(po.name) pr1.submit() self.assertRaises(frappe.ValidationError, pr2.submit) pr1.cancel() se.cancel() se1.cancel() se2.cancel() po.reload() po.cancel()
def test_po_to_pi_and_po_to_pr_worflow_partial(self): """Test following behaviour: - Create PO - Create partial PI from PO and submit - Create PR from PO and submit """ from erpnext.buying.doctype.purchase_order import test_purchase_order from erpnext.buying.doctype.purchase_order import purchase_order po = test_purchase_order.create_purchase_order() pi = purchase_order.make_purchase_invoice(po.name) pi.items[0].qty /= 2 # roughly 50%, ^ this function only creates PI with 1 item. pi.submit() pr = purchase_order.make_purchase_receipt(po.name) pr.save() # per_billed is only updated after submission. self.assertEqual(flt(pr.per_billed), 0) pr.submit() pi.load_from_db() pr.load_from_db() self.assertEqual(pr.status, "To Bill") self.assertAlmostEqual(pr.per_billed, 50.0, places=2)
def test_pending_and_received_qty(self): po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes') make_stock_entry(item_code='_Test Item', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) transfer_subcontracted_raw_materials(po.name) col, data = execute(filters=frappe._dict({ 'supplier': po.supplier, 'from_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=-10)), 'to_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=10)) })) self.assertEqual(data[0]['purchase_order'], po.name) self.assertIn(data[0]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100']) self.assertIn(data[0]['p_qty'], [9, 18]) self.assertIn(data[0]['t_qty'], [1, 2]) self.assertEqual(data[1]['purchase_order'], po.name) self.assertIn(data[1]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100']) self.assertIn(data[1]['p_qty'], [9, 18]) self.assertIn(data[1]['t_qty'], [1, 2])
def test_subcontracted_pr_for_multi_transfer_batches(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.buying.doctype.purchase_order.purchase_order import make_rm_stock_entry, make_purchase_receipt from erpnext.buying.doctype.purchase_order.test_purchase_order import (update_backflush_based_on, create_purchase_order) update_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 }) create_subcontracted_item(item_code=item_code, has_batch_no=1, raw_materials=["Sub Contracted Raw Material 3"]) order_qty = 500 po = create_purchase_order(item_code=item_code, qty=order_qty, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") 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": po.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": po.supplied_items[0].name} ] rm_item_string = json.dumps(rm_items) se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string)) 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("Purchase Order Item Supplied", {"parent": po.name, "rm_item_code": "Sub Contracted Raw Material 3"}, "supplied_qty") self.assertEqual(supplied_qty, 500.00) pr = make_purchase_receipt(po.name) pr.save() self.assertEqual(len(pr.supplied_items), 2) for row in pr.supplied_items: self.assertEqual(transferred_batch.get(row.batch_no), row.consumed_qty) update_backflush_based_on("BOM")
def test_pending_and_received_qty(self): po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes") transfer_param = [] make_stock_entry(item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100) make_stock_entry( item_code="_Test Item Home Desktop 100", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100, ) make_purchase_receipt_against_po(po.name) po.reload() col, data = execute(filters=frappe._dict({ "supplier": po.supplier, "from_date": frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=-10)), "to_date": frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=10)), })) self.assertEqual(data[0]["pending_qty"], 5) self.assertEqual(data[0]["received_qty"], 5) self.assertEqual(data[0]["purchase_order"], po.name) self.assertEqual(data[0]["supplier"], po.supplier)
def test_make_purchase_invoice_from_pr_for_returned_qty(self): from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order, create_pr_against_po po = create_purchase_order() pr = create_pr_against_po(po.name) pr1 = make_purchase_receipt(is_return=1, return_against=pr.name, qty=-1, do_not_submit=True) pr1.items[0].purchase_order = po.name pr1.items[0].purchase_order_item = po.items[0].name pr1.submit() pi = make_purchase_invoice(pr.name) self.assertEquals(pi.items[0].qty, 3)
def test_make_purchase_invoice_from_pr_for_returned_qty(self): from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order, create_pr_against_po po = create_purchase_order() pr = create_pr_against_po(po.name) pr1 = make_purchase_receipt(is_return=1, return_against=pr.name, qty=-1, do_not_submit=True) pr1.items[0].purchase_order = po.name pr1.items[0].purchase_order_item = po.items[0].name pr1.submit() pi = make_purchase_invoice(pr.name) self.assertEquals(pi.items[0].qty, 3)
def test_pr_billing_status(self): # PO -> PR1 -> PI and PO -> PI and PO -> PR2 from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order from erpnext.buying.doctype.purchase_order.purchase_order \ import make_purchase_receipt, make_purchase_invoice as make_purchase_invoice_from_po po = create_purchase_order() pr1 = make_purchase_receipt(po.name) pr1.posting_date = today() pr1.posting_time = "10:00" pr1.get("items")[0].received_qty = 2 pr1.get("items")[0].qty = 2 pr1.submit() pi1 = make_purchase_invoice(pr1.name) pi1.submit() pr1.load_from_db() self.assertEqual(pr1.per_billed, 100) pi2 = make_purchase_invoice_from_po(po.name) pi2.get("items")[0].qty = 4 pi2.submit() pr2 = make_purchase_receipt(po.name) pr2.posting_date = today() pr2.posting_time = "08:00" pr2.get("items")[0].received_qty = 5 pr2.get("items")[0].qty = 5 pr2.submit() pr1.load_from_db() self.assertEqual(pr1.get("items")[0].billed_amt, 1000) self.assertEqual(pr1.per_billed, 100) self.assertEqual(pr1.status, "Completed") pr2.load_from_db() self.assertEqual(pr2.get("items")[0].billed_amt, 2000) self.assertEqual(pr2.per_billed, 80) self.assertEqual(pr2.status, "To Bill") pr2.cancel() pi2.reload() pi2.cancel() pi1.reload() pi1.cancel() pr1.reload() pr1.cancel() po.reload() po.cancel()
def test_permission_for_custom_doctype(self): create_user("Supplier 1", "*****@*****.**") create_user("Supplier 2", "*****@*****.**") create_supplier_with_contact("Supplier1", "All Supplier Groups", "Supplier 1", "*****@*****.**") create_supplier_with_contact("Supplier2", "All Supplier Groups", "Supplier 2", "*****@*****.**") po1 = create_purchase_order(supplier="Supplier1") po2 = create_purchase_order(supplier="Supplier2") create_custom_doctype() create_webform() create_order_assignment(supplier="Supplier1", po=po1.name) create_order_assignment(supplier="Supplier2", po=po2.name) frappe.set_user("Administrator") # checking if data consist of all order assignment of Supplier1 and Supplier2 self.assertTrue( "Supplier1" and "Supplier2" in [data.supplier for data in get_data()]) frappe.set_user("*****@*****.**") # checking if data only consist of order assignment of Supplier1 self.assertTrue("Supplier1" in [data.supplier for data in get_data()]) self.assertFalse([ data.supplier for data in get_data() if data.supplier != "Supplier1" ]) frappe.set_user("*****@*****.**") # checking if data only consist of order assignment of Supplier2 self.assertTrue("Supplier2" in [data.supplier for data in get_data()]) self.assertFalse([ data.supplier for data in get_data() if data.supplier != "Supplier2" ]) frappe.set_user("Administrator")
def test_supplier_disabled(self): make_test_records("Item") frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 1) from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order po = create_purchase_order(do_not_save=True) self.assertRaises(PartyDisabled, po.save) frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 0) po.save()
def test_supplier_disabled(self): make_test_records("Item") frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 1) from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order po = create_purchase_order(do_not_save=True) self.assertRaises(PartyDisabled, po.save) frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 0) po.save()
def test_pending_and_received_qty(self): po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes') transfer_param = [] make_stock_entry(item_code='_Test Item', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) make_purchase_receipt_against_po(po.name) po.reload() col, data = execute(filters=frappe._dict({'supplier': po.supplier, 'from_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=-10)), 'to_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=10))})) self.assertEqual(data[0]['pending_qty'], 5) self.assertEqual(data[0]['received_qty'], 5) self.assertEqual(data[0]['purchase_order'], po.name) self.assertEqual(data[0]['supplier'], po.supplier)
def test_alternative_item_for_subcontract_rm(self): create_stock_reconciliation(item_code='Alternate Item For A RW 1', warehouse='_Test Warehouse - _TC', qty=5, rate=2000) create_stock_reconciliation(item_code='Test FG A RW 2', warehouse='_Test Warehouse - _TC', qty=5, rate=2000) supplier_warehouse = "Test Supplier Warehouse - _TC" po = create_purchase_order(item = "Test Finished Goods - A", is_subcontracted='Yes', qty=5, rate=3000, supplier_warehouse=supplier_warehouse) rm_item = [{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 1", "item_name":"Test FG A RW 1", "qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"}, {"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 2", "item_name":"Test FG A RW 2", "qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"}] rm_item_string = json.dumps(rm_item) reserved_qty_for_sub_contract = frappe.db.get_value('Bin', {'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract') se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string)) se.to_warehouse = supplier_warehouse se.insert() doc = frappe.get_doc('Stock Entry', se.name) for item in doc.items: if item.item_code == 'Test FG A RW 1': item.item_code = 'Alternate Item For A RW 1' item.item_name = 'Alternate Item For A RW 1' item.description = 'Alternate Item For A RW 1' item.original_item = 'Test FG A RW 1' doc.save() doc.submit() after_transfer_reserved_qty_for_sub_contract = frappe.db.get_value('Bin', {'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract') self.assertEqual(after_transfer_reserved_qty_for_sub_contract, flt(reserved_qty_for_sub_contract - 5)) pr = make_purchase_receipt(po.name) pr.save() pr = frappe.get_doc('Purchase Receipt', pr.name) status = False for d in pr.supplied_items: if d.rm_item_code == 'Alternate Item For A RW 1': status = True self.assertEqual(status, True)
def test_alternative_item_for_subcontract_rm(self): create_stock_reconciliation(item_code='Alternate Item For A RW 1', warehouse='_Test Warehouse - _TC', qty=5, rate=2000) create_stock_reconciliation(item_code='Test FG A RW 2', warehouse='_Test Warehouse - _TC', qty=5, rate=2000) supplier_warehouse = "Test Supplier Warehouse - _TC" po = create_purchase_order(item = "Test Finished Goods - A", is_subcontracted='Yes', qty=5, rate=3000, supplier_warehouse=supplier_warehouse) rm_item = [{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 1", "item_name":"Test FG A RW 1", "qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"}, {"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 2", "item_name":"Test FG A RW 2", "qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"}] rm_item_string = json.dumps(rm_item) reserved_qty_for_sub_contract = frappe.db.get_value('Bin', {'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract') se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string)) se.to_warehouse = supplier_warehouse se.insert() doc = frappe.get_doc('Stock Entry', se.name) for item in doc.items: if item.item_code == 'Test FG A RW 1': item.item_code = 'Alternate Item For A RW 1' item.item_name = 'Alternate Item For A RW 1' item.description = 'Alternate Item For A RW 1' item.original_item = 'Test FG A RW 1' doc.save() doc.submit() after_transfer_reserved_qty_for_sub_contract = frappe.db.get_value('Bin', {'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract') self.assertEqual(after_transfer_reserved_qty_for_sub_contract, flt(reserved_qty_for_sub_contract - 5)) pr = make_purchase_receipt(po.name) pr.save() pr = frappe.get_doc('Purchase Receipt', pr.name) status = False for d in pr.supplied_items: if d.rm_item_code == 'Alternate Item For A RW 1': status = True self.assertEqual(status, True)
def test_pending_and_transferred_qty(self): po = create_purchase_order( item_code='_Test FG Item', is_subcontracted='Yes', supplier_warehouse="_Test Warehouse 1 - _TC") # Material Receipt of RMs make_stock_entry(item_code='_Test Item', target='_Test Warehouse - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse - _TC', qty=100, basic_rate=100) se = transfer_subcontracted_raw_materials(po) col, data = execute(filters=frappe._dict({ 'supplier': po.supplier, 'from_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=-10)), 'to_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=10)) })) po.reload() po_data = [row for row in data if row.get('purchase_order') == po.name] # Alphabetically sort to be certain of order po_data = sorted(po_data, key=lambda i: i['rm_item_code']) self.assertEqual(len(po_data), 2) self.assertEqual(po_data[0]['purchase_order'], po.name) self.assertEqual(po_data[0]['rm_item_code'], '_Test Item') self.assertEqual(po_data[0]['p_qty'], 8) self.assertEqual(po_data[0]['transferred_qty'], 2) self.assertEqual(po_data[1]['rm_item_code'], '_Test Item Home Desktop 100') self.assertEqual(po_data[1]['p_qty'], 19) self.assertEqual(po_data[1]['transferred_qty'], 1) se.cancel() po.cancel()
def test_monthly_budget_crossed_for_po(self): budget = make_budget(applicable_on_purchase_order=1, action_if_accumulated_monthly_budget_exceeded_on_po="Stop", budget_against="Cost Center") fiscal_year = get_fiscal_year(nowdate())[0] frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop") frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year) po = create_purchase_order(transaction_date=nowdate(), do_not_submit=True) po.set_missing_values() self.assertRaises(BudgetError, po.submit) budget.load_from_db() budget.cancel()
def test_monthly_budget_crossed_for_po(self): budget = make_budget(applicable_on_purchase_order=1, action_if_accumulated_monthly_budget_exceeded_on_po="Stop", budget_against="Cost Center") fiscal_year = get_fiscal_year(nowdate())[0] frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop") frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year) po = create_purchase_order(transaction_date=nowdate(), do_not_submit=True) po.set_missing_values() self.assertRaises(BudgetError, po.submit) budget.load_from_db() budget.cancel()
def test_pending_and_transferred_qty(self): po = create_purchase_order( item_code="_Test FG Item", is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC" ) # Material Receipt of RMs make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=100, basic_rate=100) make_stock_entry( item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=100, basic_rate=100 ) se = transfer_subcontracted_raw_materials(po) col, data = execute( filters=frappe._dict( { "supplier": po.supplier, "from_date": frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=-10) ), "to_date": frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=10)), } ) ) po.reload() po_data = [row for row in data if row.get("purchase_order") == po.name] # Alphabetically sort to be certain of order po_data = sorted(po_data, key=lambda i: i["rm_item_code"]) self.assertEqual(len(po_data), 2) self.assertEqual(po_data[0]["purchase_order"], po.name) self.assertEqual(po_data[0]["rm_item_code"], "_Test Item") self.assertEqual(po_data[0]["p_qty"], 8) self.assertEqual(po_data[0]["transferred_qty"], 2) self.assertEqual(po_data[1]["rm_item_code"], "_Test Item Home Desktop 100") self.assertEqual(po_data[1]["p_qty"], 19) self.assertEqual(po_data[1]["transferred_qty"], 1) se.cancel() po.cancel()
def test_pr_billing_status(self): # PO -> PR1 -> PI and PO -> PI and PO -> PR2 from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order from erpnext.buying.doctype.purchase_order.purchase_order import ( make_purchase_receipt, make_purchase_invoice as make_purchase_invoice_from_po, ) po = create_purchase_order() pr1 = make_purchase_receipt(po.name) pr1.posting_date = today() pr1.posting_time = "10:00" pr1.get("items")[0].received_qty = 2 pr1.get("items")[0].qty = 2 pr1.submit() pi1 = make_purchase_invoice(pr1.name) pi1.submit() pr1.load_from_db() self.assertEqual(pr1.per_billed, 100) pi2 = make_purchase_invoice_from_po(po.name) pi2.get("items")[0].qty = 4 pi2.submit() pr2 = make_purchase_receipt(po.name) pr2.posting_date = today() pr2.posting_time = "08:00" pr2.get("items")[0].received_qty = 5 pr2.get("items")[0].qty = 5 pr2.submit() pr1.load_from_db() self.assertEqual(pr1.get("items")[0].billed_amt, 1000) self.assertEqual(pr1.per_billed, 100) self.assertEqual(pr1.status, "Completed") self.assertEqual(pr2.get("items")[0].billed_amt, 2000) self.assertEqual(pr2.per_billed, 80) self.assertEqual(pr2.status, "To Bill")
def test_incorrect_serial_no_components_based_on_material_transfer(self): """ - Set backflush based on Material Transferred for Subcontract - Create subcontracted PO for the item Subcontracted Item SA2. - Transfer the serialized componenets to the supplier. - Create purchase receipt and change the serial no which is not transferred. - System should throw the error and not allowed to save the purchase receipt. """ set_backflush_based_on("Material Transferred for Subcontract") item_code = "Subcontracted Item SA2" items = [{ "warehouse": "_Test Warehouse - _TC", "item_code": item_code, "qty": 10, "rate": 100 }] rm_items = [{"item_code": "Subcontracted SRM Item 2", "qty": 10}] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted=1, supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d["po_detail"] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details), ) pr1 = make_purchase_receipt(po.name) pr1.save() pr1.supplied_items[0].serial_no = "ABCD" self.assertRaises(frappe.ValidationError, pr1.save) pr1.delete()
def test_po_to_pi_and_po_to_pr_worflow_full(self): """Test following behaviour: - Create PO - Create PI from PO and submit - Create PR from PO and submit """ from erpnext.buying.doctype.purchase_order import test_purchase_order from erpnext.buying.doctype.purchase_order import purchase_order po = test_purchase_order.create_purchase_order() pi = purchase_order.make_purchase_invoice(po.name) pi.submit() pr = purchase_order.make_purchase_receipt(po.name) pr.submit() pr.load_from_db() self.assertEqual(pr.status, "Completed") self.assertEqual(pr.per_billed, 100)
def test_incorrect_serial_no_components_based_on_material_transfer(self): ''' - Set backflush based on Material Transferred for Subcontract - Create subcontracted PO for the item Subcontracted Item SA2. - Transfer the serialized componenets to the supplier. - Create purchase receipt and change the serial no which is not transferred. - System should throw the error and not allowed to save the purchase receipt. ''' set_backflush_based_on('Material Transferred for Subcontract') item_code = 'Subcontracted Item SA2' items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100 }] rm_items = [{'item_code': 'Subcontracted SRM Item 2', 'qty': 10}] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.save() pr1.supplied_items[0].serial_no = 'ABCD' self.assertRaises(frappe.ValidationError, pr1.save) pr1.delete()
def test_subcontractor_sourced_item(self): item_code = "_Test Subcontracted FG Item 1" set_backflush_based_on("Material Transferred for Subcontract") 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=1, 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.assertEqual(bom_items, supplied_items)
def test_alternative_item_for_subcontract_rm(self): frappe.db.set_value("Buying Settings", None, "backflush_raw_materials_of_subcontract_based_on", "BOM") create_stock_reconciliation(item_code="Alternate Item For A RW 1", warehouse="_Test Warehouse - _TC", qty=5, rate=2000) create_stock_reconciliation(item_code="Test FG A RW 2", warehouse="_Test Warehouse - _TC", qty=5, rate=2000) supplier_warehouse = "Test Supplier Warehouse - _TC" po = create_purchase_order( item="Test Finished Goods - A", is_subcontracted="Yes", qty=5, rate=3000, supplier_warehouse=supplier_warehouse, ) rm_item = [ { "item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 1", "item_name": "Test FG A RW 1", "qty": 5, "warehouse": "_Test Warehouse - _TC", "rate": 2000, "amount": 10000, "stock_uom": "Nos", }, { "item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 2", "item_name": "Test FG A RW 2", "qty": 5, "warehouse": "_Test Warehouse - _TC", "rate": 2000, "amount": 10000, "stock_uom": "Nos", }, ] rm_item_string = json.dumps(rm_item) reserved_qty_for_sub_contract = frappe.db.get_value( "Bin", { "item_code": "Test FG A RW 1", "warehouse": "_Test Warehouse - _TC" }, "reserved_qty_for_sub_contract", ) se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string)) se.to_warehouse = supplier_warehouse se.insert() doc = frappe.get_doc("Stock Entry", se.name) for item in doc.items: if item.item_code == "Test FG A RW 1": item.item_code = "Alternate Item For A RW 1" item.item_name = "Alternate Item For A RW 1" item.description = "Alternate Item For A RW 1" item.original_item = "Test FG A RW 1" doc.save() doc.submit() after_transfer_reserved_qty_for_sub_contract = frappe.db.get_value( "Bin", { "item_code": "Test FG A RW 1", "warehouse": "_Test Warehouse - _TC" }, "reserved_qty_for_sub_contract", ) self.assertEqual(after_transfer_reserved_qty_for_sub_contract, flt(reserved_qty_for_sub_contract - 5)) pr = make_purchase_receipt(po.name) pr.save() pr = frappe.get_doc("Purchase Receipt", pr.name) status = False for d in pr.supplied_items: if d.rm_item_code == "Alternate Item For A RW 1": status = True self.assertEqual(status, True) frappe.db.set_value( "Buying Settings", None, "backflush_raw_materials_of_subcontract_based_on", "Material Transferred for Subcontract", )
def test_po_with_material_transfer(self): ''' - Set backflush based on Material Transfer - Create subcontracted PO for the item Subcontracted Item SA1 and Subcontracted Item SA5. - Transfer the components from Stores to Supplier warehouse with batch no and serial nos. - Transfer extra item Subcontracted SRM Item 4 for the subcontract item Subcontracted Item SA5. - Create partial purchase receipt against the PO and check serial nos and batch no. ''' set_backflush_based_on('Material Transferred for Subcontract') items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': 'Subcontracted Item SA1', 'qty': 5, 'rate': 100 }, { 'warehouse': '_Test Warehouse - _TC', 'item_code': 'Subcontracted Item SA5', 'qty': 6, 'rate': 100 }] rm_items = [{ 'item_code': 'Subcontracted SRM Item 1', 'qty': 5, 'main_item_code': 'Subcontracted Item SA1' }, { 'item_code': 'Subcontracted SRM Item 2', 'qty': 5, 'main_item_code': 'Subcontracted Item SA1' }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 5, 'main_item_code': 'Subcontracted Item SA1' }, { 'item_code': 'Subcontracted SRM Item 5', 'qty': 6, 'main_item_code': 'Subcontracted Item SA5' }, { 'item_code': 'Subcontracted SRM Item 4', 'qty': 6, 'main_item_code': 'Subcontracted Item SA5' }] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name if d.get( 'qty') == 5 else po.items[1].name make_stock_transfer_entry( po_no=po.name, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.remove(pr1.items[1]) pr1.submit() for key, value in get_supplied_items(pr1).items(): transferred_detais = itemwise_details.get(key) for field in ['qty', 'serial_no', 'batch_no']: if value.get(field): self.assertEqual(value.get(field), transferred_detais.get(field)) pr2 = make_purchase_receipt(po.name) pr2.submit() for key, value in get_supplied_items(pr2).items(): transferred_detais = itemwise_details.get(key) for field in ['qty', 'serial_no', 'batch_no']: if value.get(field): self.assertEqual(value.get(field), transferred_detais.get(field))
def test_jv_against_purchase_order(self): from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order purchase_order = create_purchase_order(do_not_save=True) base_jv = frappe.copy_doc(test_records[1]) self.jv_against_voucher_testcase(base_jv, purchase_order)
def test_return_non_consumed_materials(self): ''' - Set backflush based on Material Transfer - Create subcontracted PO for the item Subcontracted Item SA2. - Transfer the components from Stores to Supplier warehouse with serial nos. - Transfer extra qty of component for the subcontracted item Subcontracted Item SA2. - Create purchase receipt for full qty against the PO and change the qty of raw material. - After that return the non consumed material back to the store from supplier's warehouse. ''' set_backflush_based_on('Material Transferred for Subcontract') items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': 'Subcontracted Item SA2', 'qty': 5, 'rate': 100 }] rm_items = [{ 'item_code': 'Subcontracted SRM Item 2', 'qty': 6, 'main_item_code': 'Subcontracted Item SA2' }] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.save() pr1.supplied_items[0].consumed_qty = 5 pr1.supplied_items[0].serial_no = '\n'.join( sorted( itemwise_details.get('Subcontracted SRM Item 2').get( 'serial_no')[0:5])) pr1.submit() for key, value in get_supplied_items(pr1).items(): transferred_detais = itemwise_details.get(key) self.assertEqual(value.qty, 5) self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get('serial_no')[0:5])) po.load_from_db() self.assertEqual(po.supplied_items[0].consumed_qty, 5) doc = get_materials_from_supplier(po.name, [d.name for d in po.supplied_items]) self.assertEqual(doc.items[0].qty, 1) self.assertEqual(doc.items[0].s_warehouse, '_Test Warehouse 1 - _TC') self.assertEqual(doc.items[0].t_warehouse, '_Test Warehouse - _TC') self.assertEqual( get_serial_nos(doc.items[0].serial_no), itemwise_details.get(doc.items[0].item_code)['serial_no'][5:6])
def test_po_with_bom(self): ''' - Set backflush based on BOM - Create subcontracted PO for the item Subcontracted Item SA1 and add same item two times. - Transfer the components from Stores to Supplier warehouse with batch no and serial nos. - Create purchase receipt against the PO and check serial nos and batch no. ''' set_backflush_based_on('BOM') item_code = 'Subcontracted Item SA1' items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 5, 'rate': 100 }, { 'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 6, 'rate': 100 }] rm_items = [{ 'item_code': 'Subcontracted SRM Item 1', 'qty': 5 }, { 'item_code': 'Subcontracted SRM Item 2', 'qty': 5 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 5 }, { 'item_code': 'Subcontracted SRM Item 1', 'qty': 6 }, { 'item_code': 'Subcontracted SRM Item 2', 'qty': 6 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 6 }] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name if d.get( 'qty') == 5 else po.items[1].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.submit() for key, value in get_supplied_items(pr1).items(): transferred_detais = itemwise_details.get(key) for field in ['qty', 'serial_no', 'batch_no']: if value.get(field): transfer, consumed = (transferred_detais.get(field), value.get(field)) if field == 'serial_no': transfer, consumed = (sorted(transfer), sorted(consumed)) self.assertEqual(transfer, consumed)
def test_item_with_batch_based_on_material_transfer(self): ''' - Set backflush based on Material Transferred for Subcontract - Create subcontracted PO for the item Subcontracted Item SA4 (has batch no). - Transfer the components from Stores to Supplier warehouse with batch no and serial nos. - Transfer the components in multiple batches with extra 2 qty for the batched item. - Create the 3 purchase receipt against the PO and split Subcontracted Items into two batches. - Keep the qty as 2 for Subcontracted Item in the purchase receipt. - In the first purchase receipt the batched raw materials will be consumed 2 extra qty. ''' set_backflush_based_on('Material Transferred for Subcontract') item_code = 'Subcontracted Item SA4' items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100 }] rm_items = [{ 'item_code': 'Subcontracted SRM Item 1', 'qty': 10 }, { 'item_code': 'Subcontracted SRM Item 2', 'qty': 10 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 3 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 3 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 3 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 3 }] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.items[0].qty = 2 add_second_row_in_pr(pr1) pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): qty = 4 if key != 'Subcontracted SRM Item 3' else 6 self.assertEqual(value.qty, qty) pr1 = make_purchase_receipt(po.name) pr1.items[0].qty = 2 add_second_row_in_pr(pr1) pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): self.assertEqual(value.qty, 4) pr1 = make_purchase_receipt(po.name) pr1.items[0].qty = 2 pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): self.assertEqual(value.qty, 2)
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_partial_transfer_batch_based_on_material_transfer_for_purchase_invoice( self): ''' - Set backflush based on Material Transferred for Subcontract - Create subcontracted PO for the item Subcontracted Item SA6. - Transfer the partial components from Stores to Supplier warehouse with batch. - Create partial purchase receipt against the PO and change the qty manually. - Transfer the remaining components from Stores to Supplier warehouse with batch. - Create purchase receipt for remaining qty against the PO and change the qty manually. ''' set_backflush_based_on('Material Transferred for Subcontract') item_code = 'Subcontracted Item SA6' items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100 }] rm_items = [{'item_code': 'Subcontracted SRM Item 3', 'qty': 5}] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_invoice(po.name) pr1.update_stock = 1 pr1.items[0].qty = 5 pr1.items[0].expense_account = 'Stock Adjustment - _TC' pr1.save() transferred_batch_no = '' for key, value in get_supplied_items(pr1).items(): details = itemwise_details.get(key) self.assertEqual(value.qty, 3) transferred_batch_no = details.batch_no self.assertEqual(value.batch_no, details.batch_no) pr1.load_from_db() pr1.supplied_items[0].consumed_qty = 5 pr1.supplied_items[0].batch_no = list(transferred_batch_no.keys())[0] pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): details = itemwise_details.get(key) self.assertEqual(value.qty, details.qty) self.assertEqual(value.batch_no, details.batch_no) itemwise_details = make_stock_in_entry(rm_items=rm_items) for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_invoice(po.name) pr1.update_stock = 1 pr1.items[0].expense_account = 'Stock Adjustment - _TC' pr1.submit() for key, value in get_supplied_items(pr1).items(): details = itemwise_details.get(key) self.assertEqual(value.qty, details.qty) self.assertEqual(value.batch_no, details.batch_no)
def test_jv_against_purchase_order(self): from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order purchase_order = create_purchase_order(do_not_save=True) base_jv = frappe.copy_doc(test_records[1]) self.jv_against_voucher_testcase(base_jv, purchase_order)
def test_make_journal_entry(self): self.clear_table_entries() frappe.db.set_default("currency", "INR") base_customer_jv = self.create_against_jv(jv_test_records[2], { "party": "_Test Customer 3"}) base_supplier_jv = self.create_against_jv(jv_test_records[1], { "party": "_Test Supplier 1"}) # Create SO with partial outstanding so1 = make_sales_order(customer="_Test Customer 3", qty=10, rate=100) self.create_against_jv(jv_test_records[0], { "party": "_Test Customer 3", "reference_type": "Sales Order", "reference_name": so1.name, "is_advance": "Yes" }) #Create SO with no outstanding so2 = make_sales_order(customer="_Test Customer 3") self.create_against_jv(jv_test_records[0], { "party": "_Test Customer 3", "reference_type": "Sales Order", "reference_name": so2.name, "credit_in_account_currency": 1000, "is_advance": "Yes" }) # Purchase order po = create_purchase_order(supplier="_Test Supplier 1") #Create SI with partial outstanding si1 = self.create_voucher(si_test_records[0], { "customer": "_Test Customer 3", "debit_to": "_Test Receivable - _TC" }) self.create_against_jv(jv_test_records[0], { "party": "_Test Customer 3", "reference_type": si1.doctype, "reference_name": si1.name }) #Create SI with no outstanding si2 = self.create_voucher(si_test_records[0], { "customer": "_Test Customer 3", "debit_to": "_Test Receivable - _TC" }) self.create_against_jv(jv_test_records[0], { "party": "_Test Customer 3", "reference_type": si2.doctype, "reference_name": si2.name, "credit_in_account_currency": 561.80 }) pi = self.create_voucher(pi_test_records[0], { "supplier": "_Test Supplier 1", "credit_to": "_Test Payable - _TC" }) #Create a dict containing properties and expected values expected_outstanding = { "Journal Entry" : [base_customer_jv.name, 400.00], "Sales Invoice" : [si1.name, 161.80], "Purchase Invoice" : [pi.name, 1512.30], "Sales Order" : [so1.name, 600.00], "Purchase Order" : [po.name, 5000.00] } args = { "company": "_Test Company", "party_type": "Customer", "received_or_paid": "Received", "party": "_Test Customer 3", "party_account": "_Test Receivable - _TC", "payment_mode": "Cheque", "payment_account": "_Test Bank - _TC", "reference_no": "123456", "reference_date": "2013-02-14" } self.make_voucher_for_party(args, expected_outstanding) args.update({ "party_type": "Supplier", "received_or_paid": "Paid", "party": "_Test Supplier 1", "party_account": "_Test Payable - _TC" }) expected_outstanding["Journal Entry"] = [base_supplier_jv.name, 400.00] self.make_voucher_for_party(args, expected_outstanding)
def test_make_journal_entry(self): self.clear_table_entries() frappe.db.set_default("currency", "INR") base_customer_jv = self.create_against_jv( jv_test_records[2], {"party": "_Test Customer 3"}) base_supplier_jv = self.create_against_jv( jv_test_records[1], {"party": "_Test Supplier 1"}) # Create SO with partial outstanding so1 = make_sales_order(customer="_Test Customer 3", qty=10, rate=100) self.create_against_jv( jv_test_records[0], { "party": "_Test Customer 3", "reference_type": "Sales Order", "reference_name": so1.name, "is_advance": "Yes" }) #Create SO with no outstanding so2 = make_sales_order(customer="_Test Customer 3") self.create_against_jv( jv_test_records[0], { "party": "_Test Customer 3", "reference_type": "Sales Order", "reference_name": so2.name, "credit_in_account_currency": 1000, "is_advance": "Yes" }) # Purchase order po = create_purchase_order(supplier="_Test Supplier 1") #Create SI with partial outstanding si1 = self.create_voucher(si_test_records[0], { "customer": "_Test Customer 3", "debit_to": "_Test Receivable - _TC" }) self.create_against_jv( jv_test_records[0], { "party": "_Test Customer 3", "reference_type": si1.doctype, "reference_name": si1.name }) #Create SI with no outstanding si2 = self.create_voucher(si_test_records[0], { "customer": "_Test Customer 3", "debit_to": "_Test Receivable - _TC" }) self.create_against_jv( jv_test_records[0], { "party": "_Test Customer 3", "reference_type": si2.doctype, "reference_name": si2.name, "credit_in_account_currency": 561.80 }) pi = self.create_voucher(pi_test_records[0], { "supplier": "_Test Supplier 1", "credit_to": "_Test Payable - _TC" }) #Create a dict containing properties and expected values expected_outstanding = { "Journal Entry": [base_customer_jv.name, 400.00], "Sales Invoice": [si1.name, 161.80], "Purchase Invoice": [pi.name, 1512.30], "Sales Order": [so1.name, 600.00], "Purchase Order": [po.name, 5000.00] } args = { "company": "_Test Company", "party_type": "Customer", "received_or_paid": "Received", "party": "_Test Customer 3", "party_account": "_Test Receivable - _TC", "payment_mode": "Cheque", "payment_account": "_Test Bank - _TC", "reference_no": "123456", "reference_date": "2013-02-14" } self.make_voucher_for_party(args, expected_outstanding) args.update({ "party_type": "Supplier", "received_or_paid": "Paid", "party": "_Test Supplier 1", "party_account": "_Test Payable - _TC" }) expected_outstanding["Journal Entry"] = [base_supplier_jv.name, 400.00] self.make_voucher_for_party(args, expected_outstanding)
def test_subcontract_with_same_components_different_fg(self): ''' - Set backflush based on Material Transfer - Create subcontracted PO for the item Subcontracted Item SA2 and Subcontracted Item SA3. - Transfer the components from Stores to Supplier warehouse with serial nos. - Transfer extra qty of components for the item Subcontracted Item SA2. - Create partial purchase receipt against the PO and check serial nos and batch no. ''' set_backflush_based_on('Material Transferred for Subcontract') items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': 'Subcontracted Item SA2', 'qty': 5, 'rate': 100 }, { 'warehouse': '_Test Warehouse - _TC', 'item_code': 'Subcontracted Item SA3', 'qty': 6, 'rate': 100 }] rm_items = [{ 'item_code': 'Subcontracted SRM Item 2', 'qty': 6, 'main_item_code': 'Subcontracted Item SA2' }, { 'item_code': 'Subcontracted SRM Item 2', 'qty': 6, 'main_item_code': 'Subcontracted Item SA3' }] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name if d.get( 'qty') == 5 else po.items[1].name make_stock_transfer_entry( po_no=po.name, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.items[0].qty = 3 pr1.remove(pr1.items[1]) pr1.submit() for key, value in get_supplied_items(pr1).items(): transferred_detais = itemwise_details.get(key) self.assertEqual(value.qty, 4) self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get('serial_no')[0:4])) pr2 = make_purchase_receipt(po.name) pr2.items[0].qty = 2 pr2.remove(pr2.items[1]) pr2.submit() for key, value in get_supplied_items(pr2).items(): transferred_detais = itemwise_details.get(key) self.assertEqual(value.qty, 2) self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get('serial_no')[4:6])) pr3 = make_purchase_receipt(po.name) pr3.submit() for key, value in get_supplied_items(pr3).items(): transferred_detais = itemwise_details.get(key) self.assertEqual(value.qty, 6) self.assertEqual(sorted(value.serial_no), sorted(transferred_detais.get('serial_no')[6:12]))
def test_item_with_batch_based_on_bom_for_purchase_invoice(self): ''' - Set backflush based on BOM - Create subcontracted PO for the item Subcontracted Item SA4 (has batch no). - Transfer the components from Stores to Supplier warehouse with batch no and serial nos. - Transfer the components in multiple batches. - Create the 3 purchase receipt against the PO and split Subcontracted Items into two batches. - Keep the qty as 2 for Subcontracted Item in the purchase receipt. ''' set_backflush_based_on('BOM') item_code = 'Subcontracted Item SA4' items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100 }] rm_items = [{ 'item_code': 'Subcontracted SRM Item 1', 'qty': 10 }, { 'item_code': 'Subcontracted SRM Item 2', 'qty': 10 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 3 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 3 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 3 }, { 'item_code': 'Subcontracted SRM Item 3', 'qty': 1 }] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_invoice(po.name) pr1.update_stock = 1 pr1.items[0].qty = 2 pr1.items[0].expense_account = 'Stock Adjustment - _TC' add_second_row_in_pr(pr1) pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): self.assertEqual(value.qty, 4) pr1 = make_purchase_invoice(po.name) pr1.update_stock = 1 pr1.items[0].qty = 2 pr1.items[0].expense_account = 'Stock Adjustment - _TC' add_second_row_in_pr(pr1) pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): self.assertEqual(value.qty, 4) pr1 = make_purchase_invoice(po.name) pr1.update_stock = 1 pr1.items[0].qty = 2 pr1.items[0].expense_account = 'Stock Adjustment - _TC' pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): self.assertEqual(value.qty, 2)
def test_partial_transfer_serial_no_components_based_on_material_transfer( self): ''' - Set backflush based on Material Transferred for Subcontract - Create subcontracted PO for the item Subcontracted Item SA2. - Transfer the partial components from Stores to Supplier warehouse with serial nos. - Create partial purchase receipt against the PO and change the qty manually. - Transfer the remaining components from Stores to Supplier warehouse with serial nos. - Create purchase receipt for remaining qty against the PO and change the qty manually. ''' set_backflush_based_on('Material Transferred for Subcontract') item_code = 'Subcontracted Item SA2' items = [{ 'warehouse': '_Test Warehouse - _TC', 'item_code': item_code, 'qty': 10, 'rate': 100 }] rm_items = [{'item_code': 'Subcontracted SRM Item 2', 'qty': 5}] itemwise_details = make_stock_in_entry(rm_items=rm_items) po = create_purchase_order( rm_items=items, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.items[0].qty = 5 pr1.save() for key, value in get_supplied_items(pr1).items(): details = itemwise_details.get(key) self.assertEqual(value.qty, 3) self.assertEqual(sorted(value.serial_no), sorted(details.serial_no[0:3])) pr1.load_from_db() pr1.supplied_items[0].consumed_qty = 5 pr1.supplied_items[0].serial_no = '\n'.join( itemwise_details[pr1.supplied_items[0].rm_item_code]['serial_no']) pr1.save() pr1.submit() for key, value in get_supplied_items(pr1).items(): details = itemwise_details.get(key) self.assertEqual(value.qty, details.qty) self.assertEqual(sorted(value.serial_no), sorted(details.serial_no)) itemwise_details = make_stock_in_entry(rm_items=rm_items) for d in rm_items: d['po_detail'] = po.items[0].name make_stock_transfer_entry( po_no=po.name, main_item_code=item_code, rm_items=rm_items, itemwise_details=copy.deepcopy(itemwise_details)) pr1 = make_purchase_receipt(po.name) pr1.submit() for key, value in get_supplied_items(pr1).items(): details = itemwise_details.get(key) self.assertEqual(value.qty, details.qty) self.assertEqual(sorted(value.serial_no), sorted(details.serial_no))