def test_work_order_with_non_stock_item(self): items = {'Finished Good Test Item For non stock': 1, '_Test FG Item': 1, '_Test FG Non Stock Item': 0} for item, is_stock_item in items.items(): make_item(item, { 'is_stock_item': is_stock_item }) if not frappe.db.get_value('Item Price', {'item_code': '_Test FG Non Stock Item'}): frappe.get_doc({ 'doctype': 'Item Price', 'item_code': '_Test FG Non Stock Item', 'price_list_rate': 1000, 'price_list': 'Standard Buying' }).insert(ignore_permissions=True) fg_item = 'Finished Good Test Item For non stock' test_stock_entry.make_stock_entry(item_code="_Test FG Item", target="_Test Warehouse - _TC", qty=1, basic_rate=100) if not frappe.db.get_value('BOM', {'item': fg_item}): make_bom(item=fg_item, rate=1000, raw_materials = ['_Test FG Item', '_Test FG Non Stock Item']) wo = make_wo_order_test_record(production_item = fg_item) se = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", 1)) se.insert() se.submit() ste = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1)) ste.insert() self.assertEqual(len(ste.additional_costs), 1) self.assertEqual(ste.total_additional_costs, 1000)
def check_planned_qty(self): set_perpetual_inventory(0) planned0 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty") or 0 pro_doc = frappe.copy_doc(test_records[0]) pro_doc.insert() pro_doc.submit() # add raw materials to stores test_stock_entry.make_stock_entry("_Test Item", None, "Stores - _TC", 100, 100) test_stock_entry.make_stock_entry("_Test Item Home Desktop 100", None, "Stores - _TC", 100, 100) # from stores to wip s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer", 4)) for d in s.get("mtn_details"): d.s_warehouse = "Stores - _TC" s.fiscal_year = "_Test Fiscal Year 2013" s.posting_date = "2013-01-02" s.insert() s.submit() # from wip to fg s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 4)) s.fiscal_year = "_Test Fiscal Year 2013" s.posting_date = "2013-01-03" s.insert() s.submit() self.assertEqual(frappe.db.get_value("Production Order", pro_doc.name, "produced_qty"), 4) planned1 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty") self.assertEqual(planned1 - planned0, 6) return pro_doc
def test_delivery_note_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() cost_center = "_Test Cost Center - _TC" company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company') set_perpetual_inventory(1, company) set_valuation_method("_Test Item", "FIFO") make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100) stock_in_hand_account = get_inventory_account('_Test Company') dn = create_delivery_note() gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) expected_values = { "Cost of Goods Sold - _TC": { "cost_center": cost_center }, 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, company)
def test_delivery_note_no_gl_entry(self): set_perpetual_inventory(0) self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 0) make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100) stock_queue = json.loads( get_previous_sle( { "item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC", "posting_date": nowdate(), "posting_time": nowtime(), } ).stock_queue or "[]" ) dn = create_delivery_note() sle = frappe.get_doc("Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name}) self.assertEqual(sle.stock_value_difference, -1 * stock_queue[0][1]) self.assertFalse(get_gl_entries("Delivery Note", dn.name))
def test_sales_return_for_non_bundled_items(self): set_perpetual_inventory() make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100) actual_qty_0 = get_qty_after_transaction() dn = create_delivery_note(qty=5, rate=500) actual_qty_1 = get_qty_after_transaction() self.assertEquals(actual_qty_0 - 5, actual_qty_1) # outgoing_rate outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name}, "stock_value_difference") / 5 # return entry dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-2, rate=500) actual_qty_2 = get_qty_after_transaction() self.assertEquals(actual_qty_1 + 2, actual_qty_2) incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn1.name}, ["incoming_rate", "stock_value_difference"]) self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3))) gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Delivery Note", "voucher_no": dn1.name, "account": "_Test Warehouse - _TC"}, "debit") self.assertEquals(gle_warehouse_amount, stock_value_difference) set_perpetual_inventory(0)
def test_reserved_qty_for_production_on_stock_entry(self): test_stock_entry.make_stock_entry(item_code="_Test Item", target= self.warehouse, qty=100, basic_rate=100) test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100", target= self.warehouse, qty=100, basic_rate=100) self.test_reserved_qty_for_production_submit() s = frappe.get_doc(make_stock_entry(self.pro_order.name, "Material Transfer for Manufacture", 2)) s.submit() bin1_on_start_production = get_bin(self.item, self.warehouse) # reserved_qty_for_producion updated self.assertEqual(cint(self.bin1_at_start.reserved_qty_for_production), cint(bin1_on_start_production.reserved_qty_for_production)) # projected qty will now be 2 less (becuase of item movement) self.assertEqual(cint(self.bin1_at_start.projected_qty), cint(bin1_on_start_production.projected_qty) + 2) s = frappe.get_doc(make_stock_entry(self.pro_order.name, "Manufacture", 2)) bin1_on_end_production = get_bin(self.item, self.warehouse) # no change in reserved / projected self.assertEqual(cint(bin1_on_end_production.reserved_qty_for_production), cint(bin1_on_start_production.reserved_qty_for_production)) self.assertEqual(cint(bin1_on_end_production.projected_qty), cint(bin1_on_end_production.projected_qty))
def test_scrap_material_qty(self): prod_order = make_prod_order_test_record(planned_start_date=now(), qty=2) # add raw materials to stores test_stock_entry.make_stock_entry(item_code="_Test Item", target="Stores - _TC", qty=10, basic_rate=5000.0) test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=10, basic_rate=1000.0 ) s = frappe.get_doc(make_stock_entry(prod_order.name, "Material Transfer for Manufacture", 2)) for d in s.get("items"): d.s_warehouse = "Stores - _TC" s.insert() s.submit() s = frappe.get_doc(make_stock_entry(prod_order.name, "Manufacture", 2)) s.insert() s.submit() prod_order_details = frappe.db.get_value( "Production Order", prod_order.name, ["scrap_warehouse", "qty", "produced_qty", "bom_no"], as_dict=1 ) scrap_item_details = get_scrap_item_details(prod_order_details.bom_no) self.assertEqual(prod_order_details.produced_qty, 2) for item in s.items: if item.bom_no and item.item_code in scrap_item_details: self.assertEqual(prod_order_details.scrap_warehouse, item.t_warehouse) self.assertEqual(flt(prod_order_details.qty) * flt(scrap_item_details[item.item_code]), item.qty)
def test_over_production(self): from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError pro_doc = self.test_planned_qty() test_stock_entry.make_stock_entry("_Test Item", None, "_Test Warehouse - _TC", 100, 100) test_stock_entry.make_stock_entry("_Test Item Home Desktop 100", None, "_Test Warehouse - _TC", 100, 100) s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7)) s.insert() self.assertRaises(StockOverProductionError, s.submit)
def test_delivery_note_gl_entry(self): set_perpetual_inventory() self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1) set_valuation_method("_Test Item", "FIFO") make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100) stock_in_hand_account = frappe.db.get_value("Account", {"warehouse": "_Test Warehouse - _TC"}) prev_bal = get_balance_on(stock_in_hand_account) dn = create_delivery_note() gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) stock_value_difference = abs( frappe.db.get_value( "Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name}, "stock_value_difference" ) ) expected_values = { stock_in_hand_account: [0.0, stock_value_difference], "Cost of Goods Sold - _TC": [stock_value_difference, 0.0], } for i, gle in enumerate(gl_entries): self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account)) # check stock in hand balance bal = get_balance_on(stock_in_hand_account) self.assertEquals(bal, prev_bal - stock_value_difference) # back dated incoming entry make_stock_entry(posting_date=add_days(nowdate(), -2), target="_Test Warehouse - _TC", qty=5, basic_rate=100) gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) stock_value_difference = abs( frappe.db.get_value( "Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name}, "stock_value_difference" ) ) expected_values = { stock_in_hand_account: [0.0, stock_value_difference], "Cost of Goods Sold - _TC": [stock_value_difference, 0.0], } for i, gle in enumerate(gl_entries): self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account)) dn.cancel() self.assertFalse(get_gl_entries("Delivery Note", dn.name)) set_perpetual_inventory(0)
def test_over_production(self): wo_doc = self.check_planned_qty() test_stock_entry.make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=100, basic_rate=100) test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=100, basic_rate=100) s = frappe.get_doc(make_stock_entry(wo_doc.name, "Manufacture", 7)) s.insert() self.assertRaises(StockOverProductionError, s.submit)
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_sales_return_for_non_bundled_items(self): company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company') set_perpetual_inventory(1, company) make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, basic_rate=100) actual_qty_0 = get_qty_after_transaction() dn = create_delivery_note(qty=5, rate=500) actual_qty_1 = get_qty_after_transaction() self.assertEquals(actual_qty_0 - 5, actual_qty_1) # outgoing_rate outgoing_rate = frappe.db.get_value("Stock Ledger Entry", { "voucher_type": "Delivery Note", "voucher_no": dn.name }, "stock_value_difference") / 5 # return entry dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-2, rate=500) actual_qty_2 = get_qty_after_transaction() self.assertEquals(actual_qty_1 + 2, actual_qty_2) incoming_rate, stock_value_difference = frappe.db.get_value( "Stock Ledger Entry", { "voucher_type": "Delivery Note", "voucher_no": dn1.name }, ["incoming_rate", "stock_value_difference"]) self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3))) stock_in_hand_account = get_inventory_account('_Test Company', dn1.items[0].warehouse) gle_warehouse_amount = frappe.db.get_value( "GL Entry", { "voucher_type": "Delivery Note", "voucher_no": dn1.name, "account": stock_in_hand_account }, "debit") self.assertEquals(gle_warehouse_amount, stock_value_difference) set_perpetual_inventory(0, company)
def check_planned_qty(self): planned0 = frappe.db.get_value("Bin", { "item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC" }, "planned_qty") or 0 wo_order = make_wo_order_test_record() planned1 = frappe.db.get_value("Bin", { "item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC" }, "planned_qty") self.assertEqual(planned1, planned0 + 10) # add raw materials to stores test_stock_entry.make_stock_entry(item_code="_Test Item", target="Stores - _TC", qty=100, basic_rate=100) test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=100, basic_rate=100) # from stores to wip s = frappe.get_doc( make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 4)) for d in s.get("items"): d.s_warehouse = "Stores - _TC" s.insert() s.submit() # from wip to fg s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 4)) s.insert() s.submit() self.assertEqual( frappe.db.get_value("Work Order", wo_order.name, "produced_qty"), 4) planned2 = frappe.db.get_value("Bin", { "item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC" }, "planned_qty") self.assertEqual(planned2, planned0 + 6) return wo_order
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 Extra Item 1", qty=1, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code = "_Test FG Item", qty=1, basic_rate=100) rm_items = [ { "item_code": item_code, "rm_item_code": po.supplied_items[0].rm_item_code, "item_name": "_Test FG Item", "qty": po.supplied_items[0].required_qty, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { "item_code": item_code, "rm_item_code": po.supplied_items[1].rm_item_code, "item_name": "Test Extra Item 1", "qty": po.supplied_items[1].required_qty, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" } ] rm_item_string = json.dumps(rm_items) se = frappe.get_doc(make_subcontract_transfer_entry(po.name, rm_item_string)) se.to_warehouse = "_Test Warehouse 1 - _TC" se.save() se.submit() pr1 = make_purchase_receipt(po.name) pr2 = make_purchase_receipt(po.name) pr1.submit() self.assertRaises(frappe.ValidationError, pr2.submit)
def test_closed_delivery_note(self): from erpnext.stock.doctype.delivery_note.delivery_note import update_delivery_note_status make_stock_entry(target="Stores - TCP1", qty=5, basic_rate=100) dn = create_delivery_note(company='_Test Company with perpetual inventory', warehouse='Stores - TCP1', cost_center = 'Main - TCP1', expense_account = "Cost of Goods Sold - TCP1", do_not_submit=True) dn.submit() update_delivery_note_status(dn.name, "Closed") self.assertEqual(frappe.db.get_value("Delivery Note", dn.name, "Status"), "Closed")
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 check_planned_qty(self): set_perpetual_inventory(0) planned0 = frappe.db.get_value("Bin", { "item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC" }, "planned_qty") or 0 pro_doc = frappe.copy_doc(test_records[0]) pro_doc.insert() pro_doc.submit() # add raw materials to stores test_stock_entry.make_stock_entry(item_code="_Test Item", target="Stores - _TC", qty=100, incoming_rate=100) test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=100, incoming_rate=100) # from stores to wip s = frappe.get_doc( make_stock_entry(pro_doc.name, "Material Transfer for Manufacture", 4)) for d in s.get("items"): d.s_warehouse = "Stores - _TC" s.fiscal_year = "_Test Fiscal Year 2013" s.posting_date = "2013-01-02" s.insert() s.submit() # from wip to fg s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 4)) s.fiscal_year = "_Test Fiscal Year 2013" s.posting_date = "2013-01-03" s.insert() s.submit() self.assertEqual( frappe.db.get_value("Production Order", pro_doc.name, "produced_qty"), 4) planned1 = frappe.db.get_value("Bin", { "item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC" }, "planned_qty") self.assertEqual(planned1 - planned0, 6) return pro_doc
def test_job_card(self): data = frappe.get_cached_value('BOM', { 'docstatus': 1, 'with_operations': 1, 'company': '_Test Company' }, ['name', 'item']) bom, bom_item = data bom_doc = frappe.get_doc('BOM', bom) work_order = make_wo_order_test_record( item=bom_item, qty=1, bom_no=bom, source_warehouse="_Test Warehouse - _TC") for row in work_order.required_items: test_stock_entry.make_stock_entry(item_code=row.item_code, target="_Test Warehouse - _TC", qty=row.required_qty, basic_rate=100) ste = frappe.get_doc( make_stock_entry(work_order.name, "Material Transfer for Manufacture", 1)) ste.submit() job_cards = frappe.get_all('Job Card', filters={'work_order': work_order.name}) self.assertEqual(len(job_cards), len(bom_doc.operations)) for i, job_card in enumerate(job_cards): doc = frappe.get_doc("Job Card", job_card) doc.append( "time_logs", { "from_time": now(), "hours": i, "to_time": add_to_date(now(), i), "completed_qty": doc.for_quantity }) doc.submit() ste1 = frappe.get_doc( make_stock_entry(work_order.name, "Manufacture", 1)) ste1.submit() for job_card in job_cards: doc = frappe.get_doc("Job Card", job_card) self.assertRaises(JobCardCancelError, doc.cancel) ste1.cancel() ste.cancel()
def insert_existing_sle(warehouse): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry se1 = make_stock_entry(posting_date="2012-12-15", posting_time="02:00", item_code="_Test Item", target=warehouse, qty=10, basic_rate=700) se2 = make_stock_entry(posting_date="2012-12-25", posting_time="03:00", item_code="_Test Item", source=warehouse, qty=15) se3 = make_stock_entry(posting_date="2013-01-05", posting_time="07:00", item_code="_Test Item", target=warehouse, qty=15, basic_rate=1200) return se1, se2, se3
def test_delivery_note_gl_entry(self): company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company') set_perpetual_inventory(1, company) set_valuation_method("_Test Item", "FIFO") make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100) stock_in_hand_account = get_inventory_account('_Test Company') prev_bal = get_balance_on(stock_in_hand_account) dn = create_delivery_note() gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) stock_value_difference = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name}, "stock_value_difference")) expected_values = { stock_in_hand_account: [0.0, stock_value_difference], "Cost of Goods Sold - _TC": [stock_value_difference, 0.0] } for i, gle in enumerate(gl_entries): self.assertEqual([gle.debit, gle.credit], expected_values.get(gle.account)) # check stock in hand balance bal = get_balance_on(stock_in_hand_account) self.assertEqual(bal, prev_bal - stock_value_difference) # back dated incoming entry make_stock_entry(posting_date=add_days(nowdate(), -2), target="_Test Warehouse - _TC", qty=5, basic_rate=100) gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) stock_value_difference = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name}, "stock_value_difference")) expected_values = { stock_in_hand_account: [0.0, stock_value_difference], "Cost of Goods Sold - _TC": [stock_value_difference, 0.0] } for i, gle in enumerate(gl_entries): self.assertEqual([gle.debit, gle.credit], expected_values.get(gle.account)) dn.cancel() self.assertFalse(get_gl_entries("Delivery Note", dn.name)) set_perpetual_inventory(0, company)
def test_pending_and_received_qty(self): po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes') transfer_param = [] make_stock_entry(item_code='_Test Item', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) make_purchase_receipt_against_po(po.name) po.reload() col, data = execute(filters=frappe._dict({'supplier': po.supplier, 'from_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=-10)), 'to_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=10))})) self.assertEqual(data[0]['pending_qty'], 5) self.assertEqual(data[0]['received_qty'], 5) self.assertEqual(data[0]['purchase_order'], po.name) self.assertEqual(data[0]['supplier'], po.supplier)
def test_over_production(self): from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError pro_doc = self.test_planned_qty() test_stock_entry.make_stock_entry("_Test Item", None, "_Test Warehouse - _TC", 100, 100) test_stock_entry.make_stock_entry("_Test Item Home Desktop 100", None, "_Test Warehouse - _TC", 100, 100) s = frappe.get_doc( make_stock_entry(pro_doc.name, "Manufacture/Repack", 7)) s.insert() self.assertRaises(StockOverProductionError, s.submit)
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_delivery_note_gl_entry_packing_item(self): set_perpetual_inventory() make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=10, basic_rate=100) make_stock_entry( item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, basic_rate=100 ) stock_in_hand_account = frappe.db.get_value("Account", {"warehouse": "_Test Warehouse - _TC"}) prev_bal = get_balance_on(stock_in_hand_account) dn = create_delivery_note(item_code="_Test Product Bundle Item") stock_value_diff_rm1 = abs( frappe.db.get_value( "Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item"}, "stock_value_difference", ) ) stock_value_diff_rm2 = abs( frappe.db.get_value( "Stock Ledger Entry", {"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item Home Desktop 100"}, "stock_value_difference", ) ) stock_value_diff = stock_value_diff_rm1 + stock_value_diff_rm2 gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) expected_values = { stock_in_hand_account: [0.0, stock_value_diff], "Cost of Goods Sold - _TC": [stock_value_diff, 0.0], } for i, gle in enumerate(gl_entries): self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account)) # check stock in hand balance bal = get_balance_on(stock_in_hand_account) self.assertEquals(flt(bal, 2), flt(prev_bal - stock_value_diff, 2)) dn.cancel() self.assertFalse(get_gl_entries("Delivery Note", dn.name)) set_perpetual_inventory(0)
def test_production_plan_pending_qty_with_sales_order(self): """ Test Prod Plan impact via: SO -> Prod Plan -> WO -> SE -> SE (cancel) """ from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record from erpnext.manufacturing.doctype.work_order.work_order import ( make_stock_entry as make_se_from_wo, ) make_stock_entry(item_code="Raw Material Item 1", target="Work In Progress - _TC", qty=2, basic_rate=100) make_stock_entry(item_code="Raw Material Item 2", target="Work In Progress - _TC", qty=2, basic_rate=100) item = "Test Production Item 1" so = make_sales_order(item_code=item, qty=1) pln = create_production_plan(company=so.company, get_items_from="Sales Order", sales_order=so, skip_getting_mr_items=True) self.assertEqual(pln.po_items[0].pending_qty, 1) wo = make_wo_order_test_record( item_code=item, qty=1, company=so.company, wip_warehouse="Work In Progress - _TC", fg_warehouse="Finished Goods - _TC", skip_transfer=1, use_multi_level_bom=1, do_not_submit=True, ) wo.production_plan = pln.name wo.production_plan_item = pln.po_items[0].name wo.submit() se = frappe.get_doc(make_se_from_wo(wo.name, "Manufacture", 1)) se.submit() pln.reload() self.assertEqual(pln.po_items[0].pending_qty, 0) se.cancel() pln.reload() self.assertEqual(pln.po_items[0].pending_qty, 1)
def test_over_production(self): from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError pro_doc = self.check_planned_qty() test_stock_entry.make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=100, incoming_rate=100) test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=100, incoming_rate=100) s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7)) s.fiscal_year = "_Test Fiscal Year 2013" s.posting_date = "2013-01-04" s.insert() self.assertRaises(StockOverProductionError, s.submit)
def test_subcontracting_gle_fg_item_rate_zero(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry set_perpetual_inventory() frappe.db.set_value("Buying Settings", None, "backflush_raw_materials_of_subcontract_based_on", "BOM") make_stock_entry(item_code="_Test Item", target="Work In Progress - TCP1", qty=100, basic_rate=100, company="_Test Company with perpetual inventory") make_stock_entry(item_code="_Test Item Home Desktop 100", target="Work In Progress - TCP1", qty=100, basic_rate=100, company="_Test Company with perpetual inventory") pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=0, is_subcontracted="Yes", company="_Test Company with perpetual inventory", warehouse='Stores - TCP1', supplier_warehouse='Work In Progress - TCP1') gl_entries = get_gl_entries("Purchase Receipt", pr.name) self.assertFalse(gl_entries) set_perpetual_inventory(0)
def test_pending_and_transferred_qty(self): po = create_purchase_order( item_code='_Test FG Item', is_subcontracted='Yes', supplier_warehouse="_Test Warehouse 1 - _TC") # Material Receipt of RMs make_stock_entry(item_code='_Test Item', target='_Test Warehouse - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse - _TC', qty=100, basic_rate=100) se = transfer_subcontracted_raw_materials(po) col, data = execute(filters=frappe._dict({ 'supplier': po.supplier, 'from_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=-10)), 'to_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=10)) })) po.reload() po_data = [row for row in data if row.get('purchase_order') == po.name] # Alphabetically sort to be certain of order po_data = sorted(po_data, key=lambda i: i['rm_item_code']) self.assertEqual(len(po_data), 2) self.assertEqual(po_data[0]['purchase_order'], po.name) self.assertEqual(po_data[0]['rm_item_code'], '_Test Item') self.assertEqual(po_data[0]['p_qty'], 8) self.assertEqual(po_data[0]['transferred_qty'], 2) self.assertEqual(po_data[1]['rm_item_code'], '_Test Item Home Desktop 100') self.assertEqual(po_data[1]['p_qty'], 19) self.assertEqual(po_data[1]['transferred_qty'], 1) se.cancel() po.cancel()
def test_reserved_qty_for_stopped_production(self): test_stock_entry.make_stock_entry(item_code="_Test Item", target=self.warehouse, qty=100, basic_rate=100) test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target=self.warehouse, qty=100, basic_rate=100) # 0 0 0 self.test_reserved_qty_for_production_submit() #2 0 -2 s = frappe.get_doc( make_stock_entry(self.wo_order.name, "Material Transfer for Manufacture", 1)) s.submit() #1 -1 0 bin1_on_start_production = get_bin(self.item, self.warehouse) # reserved_qty_for_producion updated self.assertEqual( cint(self.bin1_at_start.reserved_qty_for_production) + 1, cint(bin1_on_start_production.reserved_qty_for_production)) # projected qty will now be 2 less (becuase of item movement) self.assertEqual(cint(self.bin1_at_start.projected_qty), cint(bin1_on_start_production.projected_qty) + 2) # STOP stop_unstop(self.wo_order.name, "Stopped") bin1_on_stop_production = get_bin(self.item, self.warehouse) # no change in reserved / projected self.assertEqual( cint(bin1_on_stop_production.reserved_qty_for_production), cint(self.bin1_at_start.reserved_qty_for_production)) self.assertEqual( cint(bin1_on_stop_production.projected_qty) + 1, cint(self.bin1_at_start.projected_qty))
def make_stock_in_entry(**args): args = frappe._dict(args) items = {} for row in args.rm_items: row = frappe._dict(row) doc = make_stock_entry(target=row.warehouse or '_Test Warehouse - _TC', item_code=row.item_code, qty=row.qty or 1, basic_rate=row.rate or 100) if row.item_code not in items: items.setdefault( row.item_code, frappe._dict({ 'qty': 0, 'serial_no': [], 'batch_no': defaultdict(float) })) child_row = doc.items[0] details = items[child_row.item_code] update_item_details(child_row, details) return items
def test_putaway_rules_multi_uom(self): """Test rules applied on uom other than stock uom.""" item = frappe.get_doc("Item", "_Rice") if not frappe.db.get_value("UOM Conversion Detail", {"parent": "_Rice", "uom": "Bag"}): item.append("uoms", { "uom": "Bag", "conversion_factor": 1000 }) item.save() rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=3, uom="Bag") self.assertEqual(rule_1.stock_capacity, 3000) rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=4, uom="Bag") self.assertEqual(rule_2.stock_capacity, 4000) # populate 'Rack 1' with 1 Bag, making the free space 2 Bags stock_receipt = make_stock_entry(item_code="_Rice", target=self.warehouse_1, qty=1000, basic_rate=50) pr = make_purchase_receipt(item_code="_Rice", qty=6, uom="Bag", stock_uom="Kg", conversion_factor=1000, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 4) self.assertEqual(pr.items[0].warehouse, self.warehouse_2) self.assertEqual(pr.items[1].qty, 2) self.assertEqual(pr.items[1].warehouse, self.warehouse_1) stock_receipt.cancel() pr.delete() rule_1.delete() rule_2.delete()
def test_template_cannot_have_stock(self): item = self.get_item(10) se = make_stock_entry(item_code=item.name, target="Stores - _TC", qty=1, incoming_rate=1) item.has_variants = 1 self.assertRaises(ItemTemplateCannotHaveStock, item.save)
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, 'is_fixed_asset': 0 }) 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_putaway_rules_with_same_priority(self): """Test if rule with more free space is applied, among two rules with same priority and capacity.""" rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=500, uom="Kg") rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=500, uom="Kg") # out of 500 kg capacity, occupy 100 kg in warehouse_1 stock_receipt = make_stock_entry(item_code="_Rice", target=self.warehouse_1, qty=100, basic_rate=50) pr = make_purchase_receipt(item_code="_Rice", qty=700, apply_putaway_rule=1, do_not_submit=1) self.assertEqual(len(pr.items), 2) self.assertEqual(pr.items[0].qty, 500) # warehouse_2 has 500 kg free space, it is given priority self.assertEqual(pr.items[0].warehouse, self.warehouse_2) self.assertEqual(pr.items[1].qty, 200) # warehouse_1 has 400 kg free space, it is given less priority self.assertEqual(pr.items[1].warehouse, self.warehouse_1) stock_receipt.cancel() pr.delete() rule_1.delete() rule_2.delete()
def test_putaway_rule_on_stock_entry_material_transfer(self): """Test if source warehouse is considered while applying rules.""" rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=200, uom="Kg") # higher priority rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=100, uom="Kg", priority=2) stock_entry = make_stock_entry(item_code="_Rice", source=self.warehouse_1, qty=200, target="_Test Warehouse - _TC", purpose="Material Transfer", apply_putaway_rule=1, do_not_submit=1) stock_entry_item = stock_entry.get("items")[0] # since source warehouse is Rack 1, rule 1 (for Rack 1) will be avoided # even though it has more free space and higher priority self.assertEqual(stock_entry_item.t_warehouse, self.warehouse_2) # unassigned 100 out of 200 Kg self.assertEqual(stock_entry_item.qty, 100) self.assertEqual(stock_entry_item.putaway_rule, rule_2.name) stock_entry.delete() rule_1.delete() rule_2.delete()
def test_putaway_rule_on_stock_entry_material_receipt(self): """Test if rules are applied in Stock Entry of type Receipt.""" rule_1 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_1, capacity=200, uom="Kg") # more capacity rule_2 = create_putaway_rule(item_code="_Rice", warehouse=self.warehouse_2, capacity=100, uom="Kg") stock_entry = make_stock_entry( item_code="_Rice", qty=100, target="_Test Warehouse - _TC", purpose="Material Receipt", apply_putaway_rule=1, do_not_submit=1, ) stock_entry_item = stock_entry.get("items")[0] self.assertEqual(stock_entry_item.t_warehouse, self.warehouse_1) self.assertEqual(stock_entry_item.qty, 100) self.assertEqual(stock_entry_item.putaway_rule, rule_1.name) self.assertUnchangedItemsOnResave(stock_entry) stock_entry.delete() rule_1.delete() rule_2.delete()
def test_get_items(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry create_warehouse("_Test Warehouse Group", {"is_group": 0}) create_warehouse("_Test Warehouse Ledger 1", {"is_group": 0, "parent_warehouse": "_Test Warehouse Group - _TC"}) create_item("_Test Stock Reco Item", is_stock_item=1, valuation_rate=100, warehouse="_Test Warehouse Ledger 1 - _TC", create_new_batch=1, has_batch_no=1) make_stock_entry(posting_date="2012-12-15", posting_time="02:00", item_code="_Test Stock Reco Item", target="_Test Warehouse Ledger 1 - _TC", qty=100, basic_rate=100, purpose="Material Receipt") items = get_items("_Test Warehouse Group - _TC", nowdate(), nowtime(), "_Test Company") self.assertEqual(["_Test Stock Reco Item", "_Test Warehouse Ledger 1 - _TC", 100], [items[0]["item_code"], items[0]["warehouse"], items[0]["qty"]])
def test_return_sales_invoice(self): set_perpetual_inventory() make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100) actual_qty_0 = get_qty_after_transaction() si = create_sales_invoice(qty=5, rate=500, update_stock=1) actual_qty_1 = get_qty_after_transaction() self.assertEquals(actual_qty_0 - 5, actual_qty_1) # outgoing_rate outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice", "voucher_no": si.name}, "stock_value_difference") / 5 # return entry si1 = create_sales_invoice(is_return=1, return_against=si.name, qty=-2, rate=500, update_stock=1) actual_qty_2 = get_qty_after_transaction() self.assertEquals(actual_qty_1 + 2, actual_qty_2) incoming_rate, stock_value_difference = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Sales Invoice", "voucher_no": si1.name}, ["incoming_rate", "stock_value_difference"]) self.assertEquals(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3))) # Check gl entry gle_warehouse_amount = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice", "voucher_no": si1.name, "account": "_Test Warehouse - _TC"}, "debit") self.assertEquals(gle_warehouse_amount, stock_value_difference) party_credited = frappe.db.get_value("GL Entry", {"voucher_type": "Sales Invoice", "voucher_no": si1.name, "account": "Debtors - _TC", "party": "_Test Customer"}, "credit") self.assertEqual(party_credited, 1000) # Check outstanding amount self.assertFalse(si1.outstanding_amount) self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 1500) set_perpetual_inventory(0)
def test_qa_for_delivery(self): make_stock_entry(item_code="_Test Item with QA", target="_Test Warehouse - _TC", qty=1, basic_rate=100) dn = create_delivery_note(item_code="_Test Item with QA", do_not_submit=True) self.assertRaises(QualityInspectionRequiredError, dn.submit) qa = create_quality_inspection(reference_type="Delivery Note", reference_name=dn.name, status="Rejected") dn.reload() self.assertRaises(QualityInspectionRejectedError, dn.submit) frappe.db.set_value("Quality Inspection Reading", {"parent": qa.name}, "status", "Accepted") dn.reload() dn.submit() qa.cancel() dn.reload() dn.cancel()
def test_backflush_qty_for_overpduction_manufacture(self): cancel_stock_entry = [] allow_overproduction("overproduction_percentage_for_work_order", 30) wo_order = make_wo_order_test_record(planned_start_date=now(), qty=100) ste1 = test_stock_entry.make_stock_entry( item_code="_Test Item", target="_Test Warehouse - _TC", qty=120, basic_rate=5000.0) ste2 = test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=240, basic_rate=1000.0) cancel_stock_entry.extend([ste1.name, ste2.name]) s = frappe.get_doc( make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 60)) s.submit() cancel_stock_entry.append(s.name) s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 60)) s.submit() cancel_stock_entry.append(s.name) s = frappe.get_doc( make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 60)) s.submit() cancel_stock_entry.append(s.name) s1 = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 50)) s1.submit() cancel_stock_entry.append(s1.name) self.assertEqual(s1.items[0].qty, 50) self.assertEqual(s1.items[1].qty, 100) cancel_stock_entry.reverse() for ste in cancel_stock_entry: doc = frappe.get_doc("Stock Entry", ste) doc.cancel() allow_overproduction("overproduction_percentage_for_work_order", 0)
def check_planned_qty(self): set_perpetual_inventory(0) planned0 = ( frappe.db.get_value( "Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty" ) or 0 ) pro_order = make_prod_order_test_record() planned1 = frappe.db.get_value( "Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty" ) self.assertEqual(planned1, planned0 + 10) # add raw materials to stores test_stock_entry.make_stock_entry(item_code="_Test Item", target="Stores - _TC", qty=100, basic_rate=100) test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target="Stores - _TC", qty=100, basic_rate=100 ) # from stores to wip s = frappe.get_doc(make_stock_entry(pro_order.name, "Material Transfer for Manufacture", 4)) for d in s.get("items"): d.s_warehouse = "Stores - _TC" s.insert() s.submit() # from wip to fg s = frappe.get_doc(make_stock_entry(pro_order.name, "Manufacture", 4)) s.insert() s.submit() self.assertEqual(frappe.db.get_value("Production Order", pro_order.name, "produced_qty"), 4) planned2 = frappe.db.get_value( "Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty" ) self.assertEqual(planned2, planned0 + 6) return pro_order
def test_allow_overproduction(self): allow_overproduction("overproduction_percentage_for_work_order", 0) wo_order = make_wo_order_test_record(planned_start_date=now(), qty=2) test_stock_entry.make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=10, basic_rate=5000.0) test_stock_entry.make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, basic_rate=1000.0) s = frappe.get_doc(make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 3)) s.insert() self.assertRaises(StockOverProductionError, s.submit) allow_overproduction("overproduction_percentage_for_work_order", 50) s.load_from_db() s.submit() self.assertEqual(s.docstatus, 1) allow_overproduction("overproduction_percentage_for_work_order", 0)
def test_template_cannot_have_stock(self): item = self.get_item(10) se = make_stock_entry(item_code=item.name, target="Stores - _TC", qty=1, incoming_rate=1) item.has_variants = 1 item.append("variants", {"item_attribute": "Test Size", "item_attribute_value": "Small"}) self.assertRaises(ItemTemplateCannotHaveStock, item.save)
def test_work_order_with_non_transfer_item(self): items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0} for item, allow_transfer in items.items(): make_item(item, { 'include_item_in_manufacturing': allow_transfer }) fg_item = 'Finished Good Transfer Item' test_stock_entry.make_stock_entry(item_code="_Test FG Item", target="_Test Warehouse - _TC", qty=1, basic_rate=100) test_stock_entry.make_stock_entry(item_code="_Test FG Item 1", target="_Test Warehouse - _TC", qty=1, basic_rate=100) if not frappe.db.get_value('BOM', {'item': fg_item}): make_bom(item=fg_item, raw_materials = ['_Test FG Item', '_Test FG Item 1']) wo = make_wo_order_test_record(production_item = fg_item) ste = frappe.get_doc(make_stock_entry(wo.name, "Material Transfer for Manufacture", 1)) ste.insert() ste.submit() self.assertEqual(len(ste.items), 1) ste1 = frappe.get_doc(make_stock_entry(wo.name, "Manufacture", 1)) self.assertEqual(len(ste1.items), 3)
def test_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 insert_existing_sle(self): from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry make_stock_entry(posting_date="2012-12-15", posting_time="02:00", item_code="_Test Item", target="_Test Warehouse - _TC", qty=10, incoming_rate=700) make_stock_entry(posting_date="2012-12-25", posting_time="03:00", item_code="_Test Item", source="_Test Warehouse - _TC", qty=15) make_stock_entry(posting_date="2013-01-05", posting_time="07:00", item_code="_Test Item", target="_Test Warehouse - _TC", qty=15, incoming_rate=1200)
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_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)