def test_delivery_note_cost_center_with_balance_sheet_account(self): cost_center = "Main - TCP1" company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company') set_valuation_method("_Test Item", "FIFO") make_stock_entry(target="Stores - TCP1", qty=5, basic_rate=100) stock_in_hand_account = get_inventory_account( '_Test Company with perpetual inventory') 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=1) dn.get('items')[0].cost_center = None dn.submit() gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) expected_values = { "Cost of Goods Sold - TCP1": { "cost_center": cost_center }, stock_in_hand_account: { "cost_center": cost_center } } for i, gle in enumerate(gl_entries): self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
def test_delivery_note_with_cost_center(self): from erpbee.accounts.doctype.cost_center.test_cost_center import create_cost_center cost_center = "_Test Cost Center for BS Account - TCP1" create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company with perpetual inventory") company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company') set_valuation_method("_Test Item", "FIFO") make_stock_entry(target="Stores - TCP1", qty=5, basic_rate=100) stock_in_hand_account = get_inventory_account( '_Test Company with perpetual inventory') dn = create_delivery_note( company='_Test Company with perpetual inventory', warehouse='Stores - TCP1', expense_account="Cost of Goods Sold - TCP1", cost_center=cost_center) gl_entries = get_gl_entries("Delivery Note", dn.name) self.assertTrue(gl_entries) expected_values = { "Cost of Goods Sold - TCP1": { "cost_center": cost_center }, stock_in_hand_account: { "cost_center": cost_center } } for i, gle in enumerate(gl_entries): self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
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_pending_and_received_qty(self): po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes') make_stock_entry(item_code='_Test Item', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse 1 - _TC', qty=100, basic_rate=100) transfer_subcontracted_raw_materials(po.name) col, data = execute(filters=frappe._dict({ 'supplier': po.supplier, 'from_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=-10)), 'to_date': frappe.utils.get_datetime( frappe.utils.add_to_date(po.transaction_date, days=10)) })) self.assertEqual(data[0]['purchase_order'], po.name) self.assertIn(data[0]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100']) self.assertIn(data[0]['p_qty'], [9, 18]) self.assertIn(data[0]['t_qty'], [1, 2]) self.assertEqual(data[1]['purchase_order'], po.name) self.assertIn(data[1]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100']) self.assertIn(data[1]['p_qty'], [9, 18]) self.assertIn(data[1]['t_qty'], [1, 2])
def test_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_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_delivery_note_gl_entry_packing_item(self): company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company') make_stock_entry(item_code="_Test Item", target="Stores - TCP1", qty=10, basic_rate=100) make_stock_entry(item_code="_Test Item Home Desktop 100", target="Stores - TCP1", qty=10, basic_rate=100) stock_in_hand_account = get_inventory_account( '_Test Company with perpetual inventory') prev_bal = get_balance_on(stock_in_hand_account) dn = create_delivery_note( item_code="_Test Product Bundle Item", company='_Test Company with perpetual inventory', warehouse='Stores - TCP1', cost_center='Main - TCP1', expense_account="Cost of Goods Sold - TCP1") 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 - TCP1": [stock_value_diff, 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(flt(bal, 2), flt(prev_bal - stock_value_diff, 2)) dn.cancel()
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 insert_existing_sle(warehouse): from erpbee.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_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 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_job_card(self): stock_entries = [] 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: stock_entry_doc = test_stock_entry.make_stock_entry( item_code=row.item_code, target="_Test Warehouse - _TC", qty=row.required_qty, basic_rate=100) stock_entries.append(stock_entry_doc) ste = frappe.get_doc( make_stock_entry(work_order.name, "Material Transfer for Manufacture", 1)) ste.submit() stock_entries.append(ste) 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() stock_entries.append(ste1) for job_card in job_cards: doc = frappe.get_doc("Job Card", job_card) self.assertRaises(JobCardCancelError, doc.cancel) stock_entries.reverse() for stock_entry in stock_entries: stock_entry.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 test_partial_material_consumption(self): frappe.db.set_value("Manufacturing Settings", None, "material_consumption", 1) wo_order = make_wo_order_test_record(planned_start_date=now(), qty=4) ste_cancel_list = [] ste1 = test_stock_entry.make_stock_entry( item_code="_Test Item", target="_Test Warehouse - _TC", qty=20, basic_rate=5000.0) ste2 = test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=20, basic_rate=1000.0) ste_cancel_list.extend([ste1, ste2]) s = frappe.get_doc( make_stock_entry(wo_order.name, "Material Transfer for Manufacture", 4)) s.submit() ste_cancel_list.append(s) ste1 = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 2)) ste1.submit() ste_cancel_list.append(ste1) ste3 = frappe.get_doc( make_stock_entry(wo_order.name, "Material Consumption for Manufacture", 2)) self.assertEquals(ste3.fg_completed_qty, 2) expected_qty = {"_Test Item": 2, "_Test Item Home Desktop 100": 4} for row in ste3.items: self.assertEquals(row.qty, expected_qty.get(row.item_code)) for ste_doc in ste_cancel_list: ste_doc.cancel() frappe.db.set_value("Manufacturing Settings", None, "material_consumption", 0)
def test_sales_return_for_non_bundled_items_full(self): from erpbee.stock.doctype.item.test_item import make_item company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company') make_item("Box", {'is_stock_item': 1}) make_stock_entry(item_code="Box", target="Stores - TCP1", qty=10, basic_rate=100) dn = create_delivery_note(item_code="Box", qty=5, rate=500, warehouse="Stores - TCP1", company=company, expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1") #return entry dn1 = create_delivery_note(item_code="Box", is_return=1, return_against=dn.name, qty=-5, rate=500, company=company, warehouse="Stores - TCP1", expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1", do_not_submit=1) dn1.items[0].dn_detail = dn.items[0].name dn1.submit() # hack because new_doc isn't considering is_return portion of status_updater returned = frappe.get_doc("Delivery Note", dn1.name) returned.update_prevdoc_status() dn.load_from_db() # Check if Original DN updated self.assertEqual(dn.items[0].returned_qty, 5) self.assertEqual(dn.per_returned, 100) self.assertEqual(dn.status, 'Return Issued')
def test_scrap_material_qty(self): wo_order = make_wo_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(wo_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(wo_order.name, "Manufacture", 2)) s.insert() s.submit() wo_order_details = frappe.db.get_value( "Work Order", wo_order.name, ["scrap_warehouse", "qty", "produced_qty", "bom_no"], as_dict=1) scrap_item_details = get_scrap_item_details(wo_order_details.bom_no) self.assertEqual(wo_order_details.produced_qty, 2) for item in s.items: if item.bom_no and item.item_code in scrap_item_details: self.assertEqual(wo_order_details.scrap_warehouse, item.t_warehouse) self.assertEqual( flt(wo_order_details.qty) * flt(scrap_item_details[item.item_code]), item.qty)
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 test_resered_qty_for_partial_completion(self): item = "_Test Item" warehouse = create_warehouse("Test Warehouse for reserved_qty - _TC") bin1_at_start = get_bin(item, warehouse) # reset to correct value bin1_at_start.update_reserved_qty_for_production() wo_order = make_wo_order_test_record(item="_Test FG Item", qty=2, source_warehouse=warehouse, skip_transfer=1) bin1_on_submit = get_bin(item, warehouse) # reserved qty for production is updated self.assertEqual( cint(bin1_at_start.reserved_qty_for_production) + 2, cint(bin1_on_submit.reserved_qty_for_production)) test_stock_entry.make_stock_entry(item_code="_Test Item", target=warehouse, qty=100, basic_rate=100) test_stock_entry.make_stock_entry( item_code="_Test Item Home Desktop 100", target=warehouse, qty=100, basic_rate=100) s = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 1)) s.submit() bin1_at_completion = get_bin(item, warehouse) self.assertEqual(cint(bin1_at_completion.reserved_qty_for_production), cint(bin1_on_submit.reserved_qty_for_production) - 1)
def test_subcontracting_via_purchase_invoice(self): from erpbee.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) pi = make_purchase_invoice(item_code="_Test FG Item", qty=10, rate=500, update_stock=1, is_subcontracted="Yes") self.assertEqual(len(pi.get("supplied_items")), 2) rm_supp_cost = sum([d.amount for d in pi.get("supplied_items")]) self.assertEqual(flt(pi.get("items")[0].rm_supp_cost, 2), flt(rm_supp_cost, 2))
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_delivery_note_no_gl_entry(self): company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company') 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, flt(-1 * stock_queue[0][1], 2)) self.assertFalse(get_gl_entries("Delivery Note", dn.name))
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_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item", qty=40, basic_rate=100) make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item Home Desktop 100", qty=40, basic_rate=100) # 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_pi_from_po(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_supplied_qty_against_subcontracted_po(self): item_code = "_Test Subcontracted FG Item 5" make_item('Sub Contracted Raw Material 4', { 'is_stock_item': 1, 'is_sub_contracted_item': 1 }) make_subcontracted_item( item_code=item_code, raw_materials=["Sub Contracted Raw Material 4"]) update_backflush_based_on("Material Transferred for Subcontract") order_qty = 250 po = create_purchase_order( item_code=item_code, qty=order_qty, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC", do_not_save=True) # Add same subcontracted items multiple times po.append( "items", { "item_code": item_code, "qty": order_qty, "schedule_date": add_days(nowdate(), 1), "warehouse": "_Test Warehouse - _TC" }) po.set_missing_values() po.submit() # Material receipt entry for the raw materials which will be send to supplier make_stock_entry(target="_Test Warehouse - _TC", item_code="Sub Contracted Raw Material 4", qty=500, basic_rate=100) rm_items = [ { "item_code": item_code, "rm_item_code": "Sub Contracted Raw Material 4", "item_name": "_Test Item", "qty": 250, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos", "name": po.supplied_items[0].name }, { "item_code": item_code, "rm_item_code": "Sub Contracted Raw Material 4", "item_name": "_Test Item", "qty": 250, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, ] # Raw Materials transfer entry from stores to supplier's warehouse rm_item_string = json.dumps(rm_items) se = frappe.get_doc( make_subcontract_transfer_entry(po.name, rm_item_string)) se.submit() # Test po_detail field has value or not for item_row in se.items: self.assertEqual(item_row.po_detail, po.supplied_items[item_row.idx - 1].name) po_doc = frappe.get_doc("Purchase Order", po.name) for row in po_doc.supplied_items: # Valid that whether transferred quantity is matching with supplied qty or not in the purchase order self.assertEqual(row.supplied_qty, 250.0) update_backflush_based_on("BOM")
def test_backflush_based_on_stock_entry(self): item_code = "_Test Subcontracted FG Item 1" make_subcontracted_item(item_code=item_code) make_item('Sub Contracted Raw Material 1', { 'is_stock_item': 1, 'is_sub_contracted_item': 1 }) update_backflush_based_on("Material Transferred for Subcontract") order_qty = 5 po = create_purchase_order( item_code=item_code, qty=order_qty, is_subcontracted="Yes", supplier_warehouse="_Test Warehouse 1 - _TC") make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100", qty=10, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="Test Extra Item 1", qty=100, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="Test Extra Item 2", qty=10, basic_rate=100) make_stock_entry(target="_Test Warehouse - _TC", item_code="Sub Contracted Raw Material 1", qty=10, basic_rate=100) rm_items = [{ "item_code": item_code, "rm_item_code": "Sub Contracted Raw Material 1", "item_name": "_Test Item", "qty": 10, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { "item_code": item_code, "rm_item_code": "_Test Item Home Desktop 100", "item_name": "_Test Item Home Desktop 100", "qty": 20, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { "item_code": item_code, "rm_item_code": "Test Extra Item 1", "item_name": "Test Extra Item 1", "qty": 10, "warehouse": "_Test Warehouse - _TC", "stock_uom": "Nos" }, { 'item_code': item_code, 'rm_item_code': 'Test Extra Item 2', 'stock_uom': 'Nos', 'qty': 10, 'warehouse': '_Test Warehouse - _TC', 'item_name': 'Test Extra Item 2' }] rm_item_string = json.dumps(rm_items) se = frappe.get_doc( make_subcontract_transfer_entry(po.name, rm_item_string)) se.submit() pr = make_purchase_receipt(po.name) received_qty = 2 # partial receipt pr.get('items')[0].qty = received_qty pr.save() pr.submit() transferred_items = sorted([ d.item_code for d in se.get('items') if se.purchase_order == po.name ]) issued_items = sorted( [d.rm_item_code for d in pr.get('supplied_items')]) self.assertEquals(transferred_items, issued_items) self.assertEquals(pr.get('items')[0].rm_supp_cost, 2000) transferred_rm_map = frappe._dict() for item in rm_items: transferred_rm_map[item.get('rm_item_code')] = item for item in pr.get('supplied_items'): self.assertEqual( item.get('required_qty'), (transferred_rm_map[item.get('rm_item_code')].get('qty') / order_qty) * received_qty) update_backflush_based_on("BOM")
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_sales_return_for_non_bundled_items_partial(self): company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company') make_stock_entry(item_code="_Test Item", target="Stores - TCP1", qty=50, basic_rate=100) actual_qty_0 = get_qty_after_transaction(warehouse="Stores - TCP1") dn = create_delivery_note(qty=5, rate=500, warehouse="Stores - TCP1", company=company, expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1") actual_qty_1 = get_qty_after_transaction(warehouse="Stores - TCP1") self.assertEqual(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, company=company, warehouse="Stores - TCP1", expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1", do_not_submit=1) dn1.items[0].dn_detail = dn.items[0].name dn1.submit() actual_qty_2 = get_qty_after_transaction(warehouse="Stores - TCP1") self.assertEqual(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.assertEqual(flt(incoming_rate, 3), abs(flt(outgoing_rate, 3))) stock_in_hand_account = get_inventory_account(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.assertEqual(gle_warehouse_amount, stock_value_difference) # hack because new_doc isn't considering is_return portion of status_updater returned = frappe.get_doc("Delivery Note", dn1.name) returned.update_prevdoc_status() dn.load_from_db() # Check if Original DN updated self.assertEqual(dn.items[0].returned_qty, 2) self.assertEqual(dn.per_returned, 40) from erpbee.controllers.sales_and_purchase_return import make_return_doc return_dn_2 = make_return_doc("Delivery Note", dn.name) # Check if unreturned amount is mapped in 2nd return self.assertEqual(return_dn_2.items[0].qty, -3) si = make_sales_invoice(dn.name) si.submit() self.assertEqual(si.items[0].qty, 3) dn.load_from_db() # DN should be completed on billing all unreturned amount self.assertEqual(dn.items[0].billed_amt, 1500) self.assertEqual(dn.per_billed, 100) self.assertEqual(dn.status, 'Completed') si.load_from_db() si.cancel() dn.load_from_db() self.assertEqual(dn.per_billed, 0) dn1.cancel() dn.cancel()