def test_purchase_return(self): set_perpetual_inventory() pr = make_purchase_receipt() return_pr = make_purchase_receipt(is_return=1, return_against=pr.name, qty=-2) # check sle outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt", "voucher_no": return_pr.name}, "outgoing_rate") self.assertEqual(outgoing_rate, 50) # check gl entries for return gl_entries = get_gl_entries("Purchase Receipt", return_pr.name) self.assertTrue(gl_entries) stock_in_hand_account = get_inventory_account(return_pr.company) expected_values = { stock_in_hand_account: [0.0, 100.0], "Stock Received But Not Billed - _TC": [100.0, 0.0], } for gle in gl_entries: self.assertEquals(expected_values[gle.account][0], gle.debit) self.assertEquals(expected_values[gle.account][1], gle.credit) set_perpetual_inventory(0)
def work(): frappe.set_user(frappe.db.get_global('demo_manufacturing_user')) make_purchase_receipt() make_delivery_note() make_stock_reconciliation() submit_draft_stock_entries()
def test_purchase_return_for_serialized_items(self): def _check_serial_no_values(serial_no, field_values): serial_no = frappe.get_doc("Serial No", serial_no) for field, value in field_values.items(): self.assertEquals(cstr(serial_no.get(field)), value) from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1) serial_no = get_serial_nos(pr.get("items")[0].serial_no)[0] _check_serial_no_values(serial_no, { "warehouse": "_Test Warehouse - _TC", "purchase_document_no": pr.name }) return_pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=-1, is_return=1, return_against=pr.name, serial_no=serial_no) _check_serial_no_values(serial_no, { "warehouse": "", "purchase_document_no": pr.name, "delivery_document_no": return_pr.name })
def test_purchase_return_for_rejected_qty(self): set_perpetual_inventory() pr = make_purchase_receipt(received_qty=4, qty=2) return_pr = make_purchase_receipt(is_return=1, return_against=pr.name, received_qty = -4, qty=-2) actual_qty = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt", "voucher_no": return_pr.name, 'warehouse': return_pr.items[0].rejected_warehouse}, "actual_qty") self.assertEqual(actual_qty, -2) set_perpetual_inventory(0)
def test_purchase_return_for_multi_uom(self): item_code = "_Test Purchase Return For Multi-UOM" if not frappe.db.exists('Item', item_code): item = make_item(item_code, {'stock_uom': 'Box'}) row = item.append('uoms', { 'uom': 'Unit', 'conversion_factor': 0.1 }) row.db_update() pr = make_purchase_receipt(item_code=item_code, qty=1, uom="Box", conversion_factor=1.0) return_pr = make_purchase_receipt(item_code=item_code, qty=-10, uom="Unit", stock_uom="Box", conversion_factor=0.1, is_return=1, return_against=pr.name) self.assertEquals(abs(return_pr.items[0].stock_qty), 1.0)
def test_ordered_qty(self): existing_ordered_qty = self._get_ordered_qty("_Test Item", "_Test Warehouse - _TC") from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt po = frappe.copy_doc(test_records[0]).insert() self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name) po = frappe.get_doc("Purchase Order", po.name) po.is_subcontracted = "No" po.get("po_details")[0].item_code = "_Test Item" po.submit() self.assertEquals(self._get_ordered_qty("_Test Item", "_Test Warehouse - _TC"), existing_ordered_qty + 10) pr = make_purchase_receipt(po.name) self.assertEquals(pr.doctype, "Purchase Receipt") self.assertEquals(len(pr.get("purchase_receipt_details", [])), len(test_records[0]["po_details"])) pr.posting_date = "2013-05-12" pr.naming_series = "_T-Purchase Receipt-" pr.purchase_receipt_details[0].qty = 4.0 pr.insert() pr.submit() po.load_from_db() self.assertEquals(po.get("po_details")[0].received_qty, 4) self.assertEquals(self._get_ordered_qty("_Test Item", "_Test Warehouse - _TC"), existing_ordered_qty + 6) frappe.db.set_value("Item", "_Test Item", "tolerance", 50) pr1 = make_purchase_receipt(po.name) pr1.naming_series = "_T-Purchase Receipt-" pr1.posting_date = "2013-05-12" pr1.get("purchase_receipt_details")[0].qty = 8 pr1.insert() pr1.submit() po.load_from_db() self.assertEquals(po.get("po_details")[0].received_qty, 12) self.assertEquals(self._get_ordered_qty("_Test Item", "_Test Warehouse - _TC"), existing_ordered_qty) pr1.load_from_db() pr1.cancel() po.load_from_db() self.assertEquals(po.get("po_details")[0].received_qty, 4) self.assertEquals(self._get_ordered_qty("_Test Item", "_Test Warehouse - _TC"), existing_ordered_qty + 6)
def test_serial_no_supplier(self): pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1) self.assertEquals(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"), pr.supplier) pr.cancel() self.assertFalse(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "warehouse"))
def test_purchase_receipt_for_disable_allow_cost_center_in_entry_of_bs_account(self): accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings') accounts_settings.allow_cost_center_in_entry_of_bs_account = 0 accounts_settings.save() if not frappe.db.exists('Location', 'Test Location'): frappe.get_doc({ 'doctype': 'Location', 'location_name': 'Test Location' }).insert() set_perpetual_inventory(1, "_Test Company") pr = make_purchase_receipt() stock_in_hand_account = get_inventory_account(pr.company, pr.get("items")[0].warehouse) gl_entries = get_gl_entries("Purchase Receipt", pr.name) self.assertTrue(gl_entries) expected_values = { "Stock Received But Not Billed - _TC": { "cost_center": None }, stock_in_hand_account: { "cost_center": None } } for i, gle in enumerate(gl_entries): self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center) set_perpetual_inventory(0, pr.company)
def test_purchase_receipt_no_gl_entry(self): set_perpetual_inventory(0) existing_bin_stock_value = frappe.db.get_value( "Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "stock_value" ) pr = make_purchase_receipt() stock_value_difference = frappe.db.get_value( "Stock Ledger Entry", { "voucher_type": "Purchase Receipt", "voucher_no": pr.name, "item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC", }, "stock_value_difference", ) self.assertEqual(stock_value_difference, 250) current_bin_stock_value = frappe.db.get_value( "Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "stock_value" ) self.assertEqual(current_bin_stock_value, existing_bin_stock_value + 250) self.assertFalse(get_gl_entries("Purchase Receipt", pr.name))
def test_closed_purchase_receipt(self): from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_purchase_receipt_status pr = make_purchase_receipt(do_not_submit=True) pr.submit() update_purchase_receipt_status(pr.name, "Closed") self.assertEquals(frappe.db.get_value("Purchase Receipt", pr.name, "status"), "Closed")
def create_pr_for_po(wbtname, po): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt pr = make_purchase_receipt(po.name) pr.weighbridge_ticket = wbtname pr.save() frappe.db.commit() frappe.msgprint(_("Purchase Receipt %s created successfully." % (pr.name))) return pr
def test_not_accept_duplicate_serial_no(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note item_code = frappe.db.get_value('Item', {'has_serial_no': 1}) if not item_code: item = make_item("Test Serial Item 1", dict(has_serial_no=1)) item_code = item.name serial_no = random_string(5) make_purchase_receipt(item_code=item_code, qty=1, serial_no=serial_no) create_delivery_note(item_code=item_code, qty=1, serial_no=serial_no) pr = make_purchase_receipt(item_code=item_code, qty=1, serial_no=serial_no, do_not_submit=True) self.assertRaises(SerialNoDuplicateError, pr.submit) se = make_stock_entry(item_code=item_code, target="_Test Warehouse - _TC", qty=1, serial_no=serial_no, basic_rate=100, do_not_submit=True) self.assertRaises(SerialNoDuplicateError, se.submit)
def test_ordered_qty(self): frappe.db.sql("delete from tabBin") from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt po = frappe.copy_doc(test_records[0]).insert() self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name) po = frappe.get_doc("Purchase Order", po.name) po.is_subcontracted = "No" po.get("po_details")[0].item_code = "_Test Item" po.submit() self.assertEquals(frappe.db.get_value("Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "ordered_qty"), 10) pr = make_purchase_receipt(po.name) self.assertEquals(pr.doctype, "Purchase Receipt") self.assertEquals(len(pr.get("purchase_receipt_details", [])), len(test_records[0]["po_details"])) pr.posting_date = "2013-05-12" pr.naming_series = "_T-Purchase Receipt-" pr.purchase_receipt_details[0].qty = 4.0 pr.insert() pr.submit() self.assertEquals(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 6.0) frappe.db.set_value('Item', '_Test Item', 'tolerance', 50) pr1 = make_purchase_receipt(po.name) pr1.naming_series = "_T-Purchase Receipt-" pr1.posting_date = "2013-05-12" pr1.get("purchase_receipt_details")[0].qty = 8 pr1.insert() pr1.submit() self.assertEquals(flt(frappe.db.get_value("Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "ordered_qty")), 0.0)
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_subcontracting(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry 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) pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=500, is_subcontracted="Yes") self.assertEquals(len(pr.get("supplied_items")), 2) rm_supp_cost = sum([d.amount for d in pr.get("supplied_items")]) self.assertEquals(pr.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
def test_subcontracting(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry frappe.db.set_value("Buying Settings", None, "backflush_raw_materials_of_subcontract_based_on", "BOM") 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) pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=500, is_subcontracted="Yes") self.assertEqual(len(pr.get("supplied_items")), 2) rm_supp_cost = sum([d.amount for d in pr.get("supplied_items")]) self.assertEqual(pr.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
def test_make_purchase_invoice(self): pr = make_purchase_receipt(do_not_save=True) self.assertRaises(frappe.ValidationError, make_purchase_invoice, pr.name) pr.submit() pi = make_purchase_invoice(pr.name) self.assertEquals(pi.doctype, "Purchase Invoice") self.assertEquals(len(pi.get("items")), len(pr.get("items"))) # modify rate pi.get("items")[0].rate = 200 self.assertRaises(frappe.ValidationError, frappe.get_doc(pi).submit)
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_dn_with_returned_qty_against_dn(self): pr1 = make_purchase_receipt(qty=8, do_not_submit=True) pr1.append("items", { "item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC", "qty": 1, "received_qty": 1, "rate": 100, "conversion_factor": 1.0, }) pr1.submit() pi1 = make_purchase_invoice(pr1.name) pi1.items[0].qty = 4 pi1.items.pop(1) pi1.save() pi1.submit() make_purchase_receipt(is_return=1, return_against=pr1.name, qty=-2) pi2 = make_purchase_invoice(pr1.name) self.assertEquals(pi2.items[0].qty, 2) self.assertEquals(pi2.items[1].qty, 1)
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_serialized_asset_item(self): asset_item = "Test Serialized Asset Item" if not frappe.db.exists('Item', asset_item): asset_category = frappe.get_all('Asset Category') if asset_category: asset_category = asset_category[0].name if not asset_category: doc = frappe.get_doc({ 'doctype': 'Asset Category', 'asset_category_name': 'Test Asset Category', 'depreciation_method': 'Straight Line', 'total_number_of_depreciations': 12, 'frequency_of_depreciation': 1, 'accounts': [{ 'company_name': '_Test Company', 'fixed_asset_account': '_Test Fixed Asset - _TC', 'accumulated_depreciation_account': 'Depreciation - _TC', 'depreciation_expense_account': 'Depreciation - _TC' }] }).insert() asset_category = doc.name item_data = make_item(asset_item, {'is_stock_item':0, 'stock_uom': 'Box', 'is_fixed_asset': 1, 'has_serial_no': 1, 'asset_category': asset_category, 'serial_no_series': 'ABC.###'}) asset_item = item_data.item_code pr = make_purchase_receipt(item_code=asset_item, qty=3) asset = frappe.db.get_value('Asset', {'purchase_receipt': pr.name}, 'name') asset_movement = frappe.db.get_value('Asset Movement', {'reference_name': pr.name}, 'name') serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') self.assertEquals(len(serial_nos), 3) location = frappe.db.get_value('Serial No', serial_nos[0].name, 'location') self.assertEquals(location, "Test Location") pr.cancel() serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') or [] self.assertEquals(len(serial_nos), 0) #frappe.db.sql("delete from `tabLocation") frappe.db.sql("delete from `tabAsset`")
def test_backflush_based_on_stock_entry(self): item_code = "_Test Subcontracted FG Item 1" make_subcontracted_item(item_code) update_backflush_based_on("Material Transferred for Subcontract") po = create_purchase_order(item_code=item_code, qty=1, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100) 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) rm_item = [ {"item_code":item_code,"rm_item_code":"_Test Item","item_name":"_Test Item", "qty":1,"warehouse":"_Test Warehouse - _TC","rate":100,"amount":100,"stock_uom":"Nos"}, {"item_code":item_code,"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"}, {"item_code":item_code,"rm_item_code":"Test Extra Item 1","item_name":"Test Extra Item 1", "qty":1,"warehouse":"_Test Warehouse - _TC","rate":100,"amount":200,"stock_uom":"Nos"}] rm_item_string = json.dumps(rm_item) se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string)) se.append('items', { 'item_code': "Test Extra Item 2", "qty": 1, "rate": 100, "s_warehouse": "_Test Warehouse - _TC", "t_warehouse": "_Test Warehouse 1 - _TC" }) se.set_missing_values() se.submit() pr = make_purchase_receipt(po.name) pr.save() pr.submit() se_items = sorted([d.item_code for d in se.get('items')]) supplied_items = sorted([d.rm_item_code for d in pr.get('supplied_items')]) self.assertEquals(se_items, supplied_items) update_backflush_based_on("BOM")
def make_purchase_receipt(current_date): if can_make("Purchase Receipt"): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt report = "Purchase Order Items To Be Received" po_list =list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="'Total'"]))[:how_many("Purchase Receipt")] for po in po_list: pr = frappe.get_doc(make_purchase_receipt(po)) if pr.is_subcontracted=="Yes": pr.supplier_warehouse = "Supplier - WP" pr.posting_date = current_date pr.insert() try: pr.submit() frappe.db.commit() except (NegativeStockError, SerialNoRequiredError, SerialNoQtyError): frappe.db.rollback()
def test_make_purchase_receipt(self): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt po = frappe.copy_doc(test_records[0]).insert() self.assertRaises(frappe.ValidationError, make_purchase_receipt, po.name) po = frappe.get_doc("Purchase Order", po.name) po.submit() pr = make_purchase_receipt(po.name) pr.supplier_warehouse = "_Test Warehouse 1 - _TC" pr.posting_date = "2013-05-12" self.assertEquals(pr.doctype, "Purchase Receipt") self.assertEquals(len(pr.get("purchase_receipt_details")), len(test_records[0]["po_details"])) pr.naming_series = "_T-Purchase Receipt-" frappe.get_doc(pr).insert()
def make_purchase_receipt(): if random.random() < 0.6: from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt report = "Purchase Order Items To Be Received" po_list =list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="'Total'"]))[:random.randint(1, 10)] for po in po_list: pr = frappe.get_doc(make_purchase_receipt(po)) if pr.is_subcontracted=="Yes": pr.supplier_warehouse = "Supplier - WPL" pr.posting_date = frappe.flags.current_date pr.insert() try: pr.submit() except NegativeStockError: pass frappe.db.commit()
def run_stock(current_date): # make purchase requests if can_make("Purchase Receipt"): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt from erpnext.stock.stock_ledger import NegativeStockError report = "Purchase Order Items To Be Received" for po in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Purchase Receipt")]: pr = frappe.get_doc(make_purchase_receipt(po)) pr.posting_date = current_date pr.fiscal_year = cstr(current_date.year) pr.insert() try: pr.submit() frappe.db.commit() except NegativeStockError: pass # make delivery notes (if possible) if can_make("Delivery Note"): from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note from erpnext.stock.stock_ledger import NegativeStockError from erpnext.stock.doctype.serial_no.serial_no import SerialNoRequiredError, SerialNoQtyError report = "Ordered Items To Be Delivered" for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Delivery Note")]: dn = frappe.get_doc(make_delivery_note(so)) dn.posting_date = current_date dn.fiscal_year = cstr(current_date.year) for d in dn.get("delivery_note_details"): if not d.expense_account: d.expense_account = "Cost of Goods Sold - {}".format(company_abbr) dn.insert() try: dn.submit() frappe.db.commit() except NegativeStockError: pass except SerialNoRequiredError: pass except SerialNoQtyError: pass # try submitting existing for dn in frappe.db.get_values("Delivery Note", {"docstatus": 0}, "name"): b = frappe.get_doc("Delivery Note", dn[0]) b.submit() frappe.db.commit()
def run_stock(current_date): # make purchase requests if can_make("Purchase Receipt"): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt from erpnext.stock.stock_ledger import NegativeStockError report = "Purchase Order Items To Be Received" for po in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Purchase Receipt")]: pr = webnotes.bean(make_purchase_receipt(po)) pr.doc.posting_date = current_date pr.doc.fiscal_year = cstr(current_date.year) pr.insert() try: pr.submit() webnotes.conn.commit() except NegativeStockError: pass # make delivery notes (if possible) if can_make("Delivery Note"): from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note from erpnext.stock.stock_ledger import NegativeStockError from erpnext.stock.doctype.serial_no.serial_no import SerialNoRequiredError, SerialNoQtyError report = "Ordered Items To Be Delivered" for so in list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="Total"]))[:how_many("Delivery Note")]: dn = webnotes.bean(make_delivery_note(so)) dn.doc.posting_date = current_date dn.doc.fiscal_year = cstr(current_date.year) dn.insert() try: dn.submit() webnotes.conn.commit() except NegativeStockError: pass except SerialNoRequiredError: pass except SerialNoQtyError: pass # try submitting existing for dn in webnotes.conn.get_values("Delivery Note", {"docstatus": 0}, "name"): b = webnotes.bean("Delivery Note", dn[0]) b.submit() webnotes.conn.commit()
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=1, 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_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=1, 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_bom(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=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.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 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_make_purchase_invoice(self): if not frappe.db.exists( 'Payment Terms Template', '_Test Payment Terms Template For Purchase Invoice'): frappe.get_doc({ 'doctype': 'Payment Terms Template', 'template_name': '_Test Payment Terms Template For Purchase Invoice', 'allocate_payment_based_on_payment_terms': 1, 'terms': [{ 'doctype': 'Payment Terms Template Detail', 'invoice_portion': 50.00, 'credit_days_based_on': 'Day(s) after invoice date', 'credit_days': 00 }, { 'doctype': 'Payment Terms Template Detail', 'invoice_portion': 50.00, 'credit_days_based_on': 'Day(s) after invoice date', 'credit_days': 30 }] }).insert() template = frappe.db.get_value( 'Payment Terms Template', '_Test Payment Terms Template For Purchase Invoice') old_template_in_supplier = frappe.db.get_value("Supplier", "_Test Supplier", "payment_terms") frappe.db.set_value("Supplier", "_Test Supplier", "payment_terms", template) pr = make_purchase_receipt(do_not_save=True) self.assertRaises(frappe.ValidationError, make_purchase_invoice, pr.name) pr.submit() pi = make_purchase_invoice(pr.name) self.assertEqual(pi.doctype, "Purchase Invoice") self.assertEqual(len(pi.get("items")), len(pr.get("items"))) # test maintaining same rate throughout purchade cycle pi.get("items")[0].rate = 200 self.assertRaises(frappe.ValidationError, frappe.get_doc(pi).submit) # test if payment terms are fetched and set in PI self.assertEqual(pi.payment_terms_template, template) self.assertEqual(pi.payment_schedule[0].payment_amount, flt(pi.grand_total) / 2) self.assertEqual(pi.payment_schedule[0].invoice_portion, 50) self.assertEqual(pi.payment_schedule[1].payment_amount, flt(pi.grand_total) / 2) self.assertEqual(pi.payment_schedule[1].invoice_portion, 50) # teardown pi.delete() # draft PI pr.cancel() frappe.db.set_value("Supplier", "_Test Supplier", "payment_terms", old_template_in_supplier) frappe.get_doc( 'Payment Terms Template', '_Test Payment Terms Template For Purchase Invoice').delete()
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 create_pr_against_po(po, received_qty=4): pr = make_purchase_receipt(po) pr.get("items")[0].qty = received_qty pr.insert() pr.submit() return pr
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_partial_transfer_batch_based_on_material_transfer(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_receipt(po.name) pr1.items[0].qty = 5 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_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(value.batch_no, details.batch_no)
def test_serialized_asset_item(self): asset_item = "Test Serialized Asset Item" if not frappe.db.exists('Item', asset_item): asset_category = frappe.get_all('Asset Category') if asset_category: asset_category = asset_category[0].name if not asset_category: doc = frappe.get_doc({ 'doctype': 'Asset Category', 'asset_category_name': 'Test Asset Category', 'depreciation_method': 'Straight Line', 'total_number_of_depreciations': 12, 'frequency_of_depreciation': 1, 'accounts': [{ 'company_name': '_Test Company', 'fixed_asset_account': '_Test Fixed Asset - _TC', 'accumulated_depreciation_account': 'Depreciation - _TC', 'depreciation_expense_account': 'Depreciation - _TC' }] }).insert() asset_category = doc.name item_data = make_item( asset_item, { 'is_stock_item': 0, 'stock_uom': 'Box', 'is_fixed_asset': 1, 'has_serial_no': 1, 'asset_category': asset_category, 'serial_no_series': 'ABC.###' }) asset_item = item_data.item_code if not frappe.db.exists('Location', 'Test Location'): frappe.get_doc({ 'doctype': 'Location', 'location_name': 'Test Location' }).insert() pr = make_purchase_receipt(item_code=asset_item, qty=3) asset = frappe.db.get_value('Asset', {'purchase_receipt': pr.name}, 'name') asset_movement = frappe.db.get_value('Asset Movement', {'reference_name': pr.name}, 'name') serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') self.assertEquals(len(serial_nos), 3) location = frappe.db.get_value('Serial No', serial_nos[0].name, 'location') self.assertEquals(location, "Test Location") pr.cancel() serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') or [] self.assertEquals(len(serial_nos), 0) frappe.db.sql("delete from `tabLocation") frappe.db.sql("delete from `tabAsset`")
def _test_purchase_return_return_against_purchase_order(self): self._clear_stock_account_balance() actual_qty_0 = self._get_actual_qty() from erpnext.buying.doctype.purchase_order.test_purchase_order \ import test_records as purchase_order_test_records from erpnext.buying.doctype.purchase_order.purchase_order import \ make_purchase_receipt, make_purchase_invoice # submit purchase receipt po = frappe.copy_doc(purchase_order_test_records[0]) po.is_subcontracted = None po.get("po_details")[0].item_code = "_Test Item" po.get("po_details")[0].rate = 50 po.insert() po.submit() pr_doc = make_purchase_receipt(po.name) pr = frappe.get_doc(pr_doc) pr.posting_date = po.transaction_date pr.insert() pr.submit() actual_qty_1 = self._get_actual_qty() self.assertEquals(actual_qty_0 + 10, actual_qty_1) pi_doc = make_purchase_invoice(po.name) pi = frappe.get_doc(pi_doc) pi.posting_date = pr.posting_date pi.credit_to = "_Test Supplier - _TC" for d in pi.get("entries"): d.expense_account = "_Test Account Cost for Goods Sold - _TC" d.cost_center = "_Test Cost Center - _TC" for d in pi.get("other_charges"): d.cost_center = "_Test Cost Center - _TC" pi.run_method("calculate_taxes_and_totals") pi.bill_no = "NA" pi.insert() pi.submit() # submit purchase return se = frappe.copy_doc(test_records[0]) se.purpose = "Purchase Return" se.purchase_receipt_no = pr.name se.posting_date = "2013-03-01" se.fiscal_year = "_Test Fiscal Year 2013" se.get("mtn_details")[0].qty = se.get( "mtn_details")[0].transfer_qty = 5 se.get("mtn_details")[0].s_warehouse = "_Test Warehouse - _TC" se.insert() se.submit() actual_qty_2 = self._get_actual_qty() self.assertEquals(actual_qty_1 - 5, actual_qty_2) frappe.db.set_default("company", self.old_default_company) return se, pr.name
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, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") #stock raw materials in a warehouse before transfer make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100", qty=1, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="Test Extra Item 1", qty=1, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test 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 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" }, { "item_code": item_code, "rm_item_code": po.supplied_items[2].rm_item_code, "item_name": "_Test Item Home Desktop 100", "qty": po.supplied_items[2].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)
def make_purchase_receipt_against_po(po, quantity=5): pr = make_purchase_receipt(po) pr.items[0].qty = quantity pr.supplier_warehouse = '_Test Warehouse 1 - _TC' pr.insert() pr.submit()
def run_stock(current_date): make_purchase_receipt(current_date) make_delivery_note(current_date) make_stock_reconciliation(current_date) submit_draft_stock_entries(current_date)
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_purchase_return_return_against_purchase_order(self): self._clear_stock_account_balance() actual_qty_0 = self._get_actual_qty() from erpnext.buying.doctype.purchase_order.test_purchase_order \ import test_records as purchase_order_test_records from erpnext.buying.doctype.purchase_order.purchase_order import \ make_purchase_receipt, make_purchase_invoice # submit purchase receipt po = frappe.copy_doc(purchase_order_test_records[0]) po.is_subcontracted = None po.get("po_details")[0].item_code = "_Test Item" po.get("po_details")[0].rate = 50 po.insert() po.submit() pr_doc = make_purchase_receipt(po.name) pr = frappe.get_doc(pr_doc) pr.posting_date = po.transaction_date pr.insert() pr.submit() actual_qty_1 = self._get_actual_qty() self.assertEquals(actual_qty_0 + 10, actual_qty_1) pi_doc = make_purchase_invoice(po.name) pi = frappe.get_doc(pi_doc) pi.posting_date = pr.posting_date pi.credit_to = "_Test Supplier - _TC" for d in pi.get("entries"): d.expense_account = "_Test Account Cost for Goods Sold - _TC" d.cost_center = "_Test Cost Center - _TC" for d in pi.get("other_charges"): d.cost_center = "_Test Cost Center - _TC" pi.run_method("calculate_taxes_and_totals") pi.bill_no = "NA" pi.insert() pi.submit() # submit purchase return se = frappe.copy_doc(test_records[0]) se.purpose = "Purchase Return" se.purchase_receipt_no = pr.name se.posting_date = "2013-03-01" se.fiscal_year = "_Test Fiscal Year 2013" se.get("mtn_details")[0].qty = se.get("mtn_details")[0].transfer_qty = 5 se.get("mtn_details")[0].s_warehouse = "_Test Warehouse - _TC" se.insert() se.submit() actual_qty_2 = self._get_actual_qty() self.assertEquals(actual_qty_1 - 5, actual_qty_2) frappe.db.set_default("company", self.old_default_company) return se, pr.name
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 run_stock(current_date): make_purchase_receipt(current_date) make_delivery_note(current_date) make_stock_reconciliation(current_date) submit_draft_stock_entries(current_date)
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_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_backflush_based_on_stock_entry(self): item_code = "_Test Subcontracted FG Item 1" make_subcontracted_item(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")
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_reserved_qty_subcontract_po(self): # Make stock available for raw materials make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100", qty=20, basic_rate=100) make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item", qty=30, basic_rate=100) make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item Home Desktop 100", qty=30, basic_rate=100) bin1 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1) # Submit PO po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes") bin2 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname=["reserved_qty_for_sub_contract", "projected_qty"], as_dict=1) self.assertEquals(bin2.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10) self.assertEquals(bin2.projected_qty, bin1.projected_qty - 10) # Create stock transfer rm_item = [{"item_code":"_Test FG Item","rm_item_code":"_Test Item","item_name":"_Test Item", "qty":6,"warehouse":"_Test Warehouse - _TC","rate":100,"amount":600,"stock_uom":"Nos"}] rm_item_string = json.dumps(rm_item) se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string)) se.to_warehouse = "_Test Warehouse 1 - _TC" se.save() se.submit() bin3 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin3.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # close PO po.update_status("Closed") bin4 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin4.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) # Re-open PO po.update_status("Submitted") bin5 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin5.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # make Purchase Receipt against PO pr = make_purchase_receipt(po.name) pr.supplier_warehouse = "_Test Warehouse 1 - _TC" pr.save() pr.submit() bin6 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin6.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) # Cancel PR pr.cancel() bin7 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin7.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # Make Purchase Invoice pi = make_purchase_invoice(po.name) pi.update_stock = 1 pi.supplier_warehouse = "_Test Warehouse 1 - _TC" pi.insert() pi.submit() bin8 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin8.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract) # Cancel PR pi.cancel() bin9 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin9.reserved_qty_for_sub_contract, bin2.reserved_qty_for_sub_contract - 6) # Cancel Stock Entry se.cancel() bin10 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin10.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract + 10) # Cancel PO po.reload() po.cancel() bin11 = frappe.db.get_value("Bin", filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"}, fieldname="reserved_qty_for_sub_contract", as_dict=1) self.assertEquals(bin11.reserved_qty_for_sub_contract, bin1.reserved_qty_for_sub_contract)
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=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.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))
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_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=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, 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 create_pr_against_po(po, received_qty=4): pr = make_purchase_receipt(po) pr.get("items")[0].qty = received_qty pr.insert() pr.submit() return pr
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=1, 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_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") pr.delete() se.cancel() ste2.cancel() ste1.cancel() po.cancel()
def test_backflush_based_on_stock_entry(self): item_code = "_Test Subcontracted FG Item 1" make_subcontracted_item(item_code) update_backflush_based_on("Material Transferred for Subcontract") po = create_purchase_order( item_code=item_code, qty=1, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100) 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) rm_item = [{ "item_code": item_code, "rm_item_code": "_Test Item", "item_name": "_Test Item", "qty": 1, "warehouse": "_Test Warehouse - _TC", "rate": 100, "amount": 100, "stock_uom": "Nos" }, { "item_code": item_code, "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" }, { "item_code": item_code, "rm_item_code": "Test Extra Item 1", "item_name": "Test Extra Item 1", "qty": 1, "warehouse": "_Test Warehouse - _TC", "rate": 100, "amount": 200, "stock_uom": "Nos" }] rm_item_string = json.dumps(rm_item) se = frappe.get_doc( make_subcontract_transfer_entry(po.name, rm_item_string)) se.append( 'items', { 'item_code': "Test Extra Item 2", "qty": 1, "rate": 100, "s_warehouse": "_Test Warehouse - _TC", "t_warehouse": "_Test Warehouse 1 - _TC" }) se.set_missing_values() se.submit() pr = make_purchase_receipt(po.name) pr.save() pr.submit() se_items = sorted([d.item_code for d in se.get('items')]) supplied_items = sorted( [d.rm_item_code for d in pr.get('supplied_items')]) self.assertEquals(se_items, supplied_items) update_backflush_based_on("BOM")
def test_purchase_return_partial(self): pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1") return_pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", is_return=1, return_against=pr.name, qty=-2, do_not_submit=1) return_pr.items[0].purchase_receipt_item = pr.items[0].name return_pr.submit() # check sle outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt", "voucher_no": return_pr.name}, "outgoing_rate") self.assertEqual(outgoing_rate, 50) # check gl entries for return gl_entries = get_gl_entries("Purchase Receipt", return_pr.name) self.assertTrue(gl_entries) stock_in_hand_account = get_inventory_account(return_pr.company) expected_values = { stock_in_hand_account: [0.0, 100.0], "Stock Received But Not Billed - TCP1": [100.0, 0.0], } for gle in gl_entries: self.assertEqual(expected_values[gle.account][0], gle.debit) self.assertEqual(expected_values[gle.account][1], gle.credit) # hack because new_doc isn't considering is_return portion of status_updater returned = frappe.get_doc("Purchase Receipt", return_pr.name) returned.update_prevdoc_status() pr.load_from_db() # Check if Original PR updated self.assertEqual(pr.items[0].returned_qty, 2) self.assertEqual(pr.per_returned, 40) from erpnext.controllers.sales_and_purchase_return import make_return_doc return_pr_2 = make_return_doc("Purchase Receipt", pr.name) # Check if unreturned amount is mapped in 2nd return self.assertEqual(return_pr_2.items[0].qty, -3) # Make PI against unreturned amount pi = make_purchase_invoice(pr.name) pi.submit() self.assertEqual(pi.items[0].qty, 3) pr.load_from_db() # PR should be completed on billing all unreturned amount self.assertEqual(pr.items[0].billed_amt, 150) self.assertEqual(pr.per_billed, 100) self.assertEqual(pr.status, 'Completed') pi.load_from_db() pi.cancel() pr.load_from_db() self.assertEqual(pr.per_billed, 0) return_pr.cancel() pr.cancel()