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 make_subcontract(): from erpnext.buying.doctype.purchase_order.purchase_order import make_rm_stock_entry item_code = get_random("Item", {"is_sub_contracted_item": 1}) if item_code: # make sub-contract PO po = frappe.new_doc("Purchase Order") po.is_subcontracted = "Yes" po.supplier = get_random("Supplier") po.transaction_date = frappe.flags.current_date # added po.schedule_date = frappe.utils.add_days(frappe.flags.current_date, 7) item_code = get_random("Item", {"is_sub_contracted_item": 1}) po.append("items", { "item_code": item_code, "schedule_date": frappe.utils.add_days(frappe.flags.current_date, 7), "qty": random.randint(10, 30) }) po.set_missing_values() try: po.insert() except InvalidCurrency: return po.submit() # make material request for make_material_request(po.items[0].item_code, po.items[0].qty) # transfer material for sub-contract rm_items = get_rm_item(po.items[0], po.supplied_items[0]) stock_entry = frappe.get_doc(make_rm_stock_entry(po.name, json.dumps([rm_items]))) stock_entry.from_warehouse = _("Stores") + " - WP" stock_entry.to_warehouse = _("Supplier") + " - WP" stock_entry.insert()
def transfer_subcontracted_raw_materials(po): rm_item = [{ 'item_code': '_Test Item', 'rm_item_code': '_Test Item', 'item_name': '_Test Item', 'qty': 1, 'warehouse': '_Test Warehouse - _TC', 'rate': 100, 'amount': 100, 'stock_uom': 'Nos' }, { 'item_code': '_Test Item Home Desktop 100', 'rm_item_code': '_Test Item Home Desktop 100', 'item_name': '_Test Item Home Desktop 100', 'qty': 2, 'warehouse': '_Test Warehouse - _TC', 'rate': 100, 'amount': 200, 'stock_uom': 'Nos' }] rm_item_string = json.dumps(rm_item) se = frappe.get_doc(make_rm_stock_entry(po, rm_item_string)) se.to_warehouse = '_Test Warehouse 1 - _TC' se.stock_entry_type = 'Send to Subcontractor' se.save() se.submit()
def make_subcontract(): from erpnext.buying.doctype.purchase_order.purchase_order import make_rm_stock_entry item_code = get_random("Item", {"is_sub_contracted_item": 1}) if item_code: # make sub-contract PO po = frappe.new_doc("Purchase Order") po.is_subcontracted = "Yes" po.supplier = get_random("Supplier") po.transaction_date = frappe.flags.current_date # added po.schedule_date = frappe.utils.add_days(frappe.flags.current_date, 7) item_code = get_random("Item", {"is_sub_contracted_item": 1}) po.append("items", { "item_code": item_code, "schedule_date": frappe.utils.add_days(frappe.flags.current_date, 7), "qty": random.randint(10, 30) }) po.set_missing_values() try: po.insert() except InvalidCurrency: return po.submit() # make material request for make_material_request(po.items[0].item_code, po.items[0].qty) # transfer material for sub-contract rm_items = get_rm_item(po.items[0], po.supplied_items[0]) stock_entry = frappe.get_doc(make_rm_stock_entry(po.name, json.dumps([rm_items]))) stock_entry.from_warehouse = "Stores - WPL" stock_entry.to_warehouse = "Supplier - WPL" stock_entry.insert()
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 make_stock_transfer_entry(**args): args = frappe._dict(args) items = [] for row in args.rm_items: row = frappe._dict(row) item = { 'item_code': row.main_item_code or args.main_item_code, 'rm_item_code': row.item_code, 'qty': row.qty or 1, 'item_name': row.item_code, 'rate': row.rate or 100, 'stock_uom': row.stock_uom or 'Nos', 'warehouse': row.warehuose or '_Test Warehouse - _TC' } item_details = args.itemwise_details.get(row.item_code) if item_details and item_details.serial_no: serial_nos = item_details.serial_no[0:cint(row.qty)] item['serial_no'] = '\n'.join(serial_nos) item_details.serial_no = list( set(item_details.serial_no) - set(serial_nos)) if item_details and item_details.batch_no: for batch_no, batch_qty in item_details.batch_no.items(): if batch_qty >= row.qty: item['batch_no'] = batch_no item_details.batch_no[batch_no] -= row.qty break items.append(item) ste_dict = make_rm_stock_entry(args.po_no, items) doc = frappe.get_doc(ste_dict) doc.insert() doc.submit() return doc
def make_stock_transfer_entry(**args): args = frappe._dict(args) items = [] for row in args.rm_items: row = frappe._dict(row) item = { "item_code": row.main_item_code or args.main_item_code, "rm_item_code": row.item_code, "qty": row.qty or 1, "item_name": row.item_code, "rate": row.rate or 100, "stock_uom": row.stock_uom or "Nos", "warehouse": row.warehuose or "_Test Warehouse - _TC", } item_details = args.itemwise_details.get(row.item_code) if item_details and item_details.serial_no: serial_nos = item_details.serial_no[0:cint(row.qty)] item["serial_no"] = "\n".join(serial_nos) item_details.serial_no = list( set(item_details.serial_no) - set(serial_nos)) if item_details and item_details.batch_no: for batch_no, batch_qty in item_details.batch_no.items(): if batch_qty >= row.qty: item["batch_no"] = batch_no item_details.batch_no[batch_no] -= row.qty break items.append(item) ste_dict = make_rm_stock_entry(args.po_no, items) doc = frappe.get_doc(ste_dict) doc.insert() doc.submit() return doc
def transfer_subcontracted_raw_materials(po): # Order of supplied items fetched in PO is flaky transfer_qty_map = {"_Test Item": 2, "_Test Item Home Desktop 100": 1} item_1 = po.supplied_items[0].rm_item_code item_2 = po.supplied_items[1].rm_item_code rm_item = [ { "name": po.supplied_items[0].name, "item_code": item_1, "rm_item_code": item_1, "item_name": item_1, "qty": transfer_qty_map[item_1], "warehouse": "_Test Warehouse - _TC", "rate": 100, "amount": 100 * transfer_qty_map[item_1], "stock_uom": "Nos", }, { "name": po.supplied_items[1].name, "item_code": item_2, "rm_item_code": item_2, "item_name": item_2, "qty": transfer_qty_map[item_2], "warehouse": "_Test Warehouse - _TC", "rate": 100, "amount": 100 * transfer_qty_map[item_2], "stock_uom": "Nos", }, ] rm_item_string = json.dumps(rm_item) se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string)) se.from_warehouse = "_Test Warehouse - _TC" se.to_warehouse = "_Test Warehouse - _TC" se.stock_entry_type = "Send to Subcontractor" se.save() se.submit() return se
def transfer_subcontracted_raw_materials(po): # Order of supplied items fetched in PO is flaky transfer_qty_map = {'_Test Item': 2, '_Test Item Home Desktop 100': 1} item_1 = po.supplied_items[0].rm_item_code item_2 = po.supplied_items[1].rm_item_code rm_item = [{ 'name': po.supplied_items[0].name, 'item_code': item_1, 'rm_item_code': item_1, 'item_name': item_1, 'qty': transfer_qty_map[item_1], 'warehouse': '_Test Warehouse - _TC', 'rate': 100, 'amount': 100 * transfer_qty_map[item_1], 'stock_uom': 'Nos' }, { 'name': po.supplied_items[1].name, 'item_code': item_2, 'rm_item_code': item_2, 'item_name': item_2, 'qty': transfer_qty_map[item_2], 'warehouse': '_Test Warehouse - _TC', 'rate': 100, 'amount': 100 * transfer_qty_map[item_2], 'stock_uom': 'Nos' }] rm_item_string = json.dumps(rm_item) se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string)) se.from_warehouse = '_Test Warehouse - _TC' se.to_warehouse = '_Test Warehouse - _TC' se.stock_entry_type = 'Send to Subcontractor' se.save() se.submit() return se
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", )