예제 #1
0
    def test_fifo(self):
        frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
        item_code = "_Test Item 2"
        warehouse = "_Test Warehouse - _TC"

        create_stock_reconciliation(item_code="_Test Item 2", warehouse="_Test Warehouse - _TC", qty=0, rate=100)

        make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=10)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]
        self.assertEqual([[1, 10]], eval(sle.stock_queue))

        # negative qty
        make_stock_entry(item_code=item_code, source=warehouse, qty=2, basic_rate=10)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]

        self.assertEqual([[-1, 10]], eval(sle.stock_queue))

        # further negative
        make_stock_entry(item_code=item_code, source=warehouse, qty=1)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]

        self.assertEqual([[-2, 10]], eval(sle.stock_queue))

        # move stock to positive
        make_stock_entry(item_code=item_code, target=warehouse, qty=3, basic_rate=20)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]
        self.assertEqual([[1, 20]], eval(sle.stock_queue))

        # incoming entry with diff rate
        make_stock_entry(item_code=item_code, target=warehouse, qty=1, basic_rate=30)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]

        self.assertEqual([[1, 20], [1, 30]], eval(sle.stock_queue))

        frappe.db.set_default("allow_negative_stock", 0)
예제 #2
0
	def _test_auto_material_request(self, item_code, material_request_type="Purchase", warehouse="_Test Warehouse - _TC"):
		variant = frappe.get_doc("Item", item_code)

		projected_qty, actual_qty = frappe.db.get_value("Bin", {"item_code": item_code,
			"warehouse": warehouse}, ["projected_qty", "actual_qty"]) or [0, 0]

		# stock entry reqd for auto-reorder
		create_stock_reconciliation(item_code=item_code, warehouse=warehouse,
			qty = actual_qty + abs(projected_qty) + 10, rate=100)

		projected_qty = frappe.db.get_value("Bin", {"item_code": item_code,
			"warehouse": warehouse}, "projected_qty") or 0

		frappe.db.set_value("Stock Settings", None, "auto_indent", 1)

		# update re-level qty so that it is more than projected_qty
		if projected_qty >= variant.reorder_levels[0].warehouse_reorder_level:
			variant.reorder_levels[0].warehouse_reorder_level += projected_qty
			variant.reorder_levels[0].material_request_type = material_request_type
			variant.save()

		from erpnext.stock.reorder_item import reorder_item
		mr_list = reorder_item()

		frappe.db.set_value("Stock Settings", None, "auto_indent", 0)

		items = []
		for mr in mr_list:
			for d in mr.items:
				items.append(d.item_code)

		self.assertTrue(item_code in items)
	def test_return_entire_bundled_items(self):
		set_perpetual_inventory()

		create_stock_reconciliation(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, rate=100)
		create_stock_reconciliation(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
			qty=50, rate=100)

		dn = create_delivery_note(item_code="_Test Product Bundle Item", qty=5, rate=500)

		#  return bundled item
		dn1 = create_delivery_note(item_code='_Test Product Bundle Item', is_return=1,
			return_against=dn.name, qty=-2, rate=500)

		# qty after return
		actual_qty = get_qty_after_transaction()
		self.assertEquals(actual_qty, 35)

		# Check incoming rate for return entry
		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(incoming_rate, 100)

		# Check gl entry for warehouse
		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, 1400)

		set_perpetual_inventory(0)
예제 #4
0
	def test_material_transfer_gl_entry(self):
		company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')

		create_stock_reconciliation(qty=100, rate=100)

		mtn = make_stock_entry(item_code="_Test Item", source="Stores - TCP1",
			target="Finished Goods - TCP1", qty=45)

		self.check_stock_ledger_entries("Stock Entry", mtn.name,
			[["_Test Item", "Stores - TCP1", -45.0], ["_Test Item", "Finished Goods - TCP1", 45.0]])

		stock_in_hand_account = get_inventory_account(mtn.company, mtn.get("items")[0].s_warehouse)

		fixed_asset_account = get_inventory_account(mtn.company, mtn.get("items")[0].t_warehouse)

		if stock_in_hand_account == fixed_asset_account:
			# no gl entry as both source and target warehouse has linked to same account.
			self.assertFalse(frappe.db.sql("""select * from `tabGL Entry`
				where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))

		else:
			stock_value_diff = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Stock Entry",
				"voucher_no": mtn.name, "warehouse": "Stores - TCP1"}, "stock_value_difference"))

			self.check_gl_entries("Stock Entry", mtn.name,
				sorted([
					[stock_in_hand_account, 0.0, stock_value_diff],
					[fixed_asset_account, stock_value_diff, 0.0],
				])
			)

		mtn.cancel()
예제 #5
0
	def test_alternative_item_for_production_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)
		pro_order = make_wo_order_test_record(production_item='Test Finished Goods - A',
			qty=5, source_warehouse='_Test Warehouse - _TC', wip_warehouse='Test Supplier Warehouse - _TC')

		reserved_qty_for_production = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_production')

		ste = frappe.get_doc(make_stock_entry(pro_order.name, "Material Transfer for Manufacture", 5))
		ste.insert()

		for item in ste.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'

		ste.submit()
		reserved_qty_for_production_after_transfer = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_production')

		self.assertEqual(reserved_qty_for_production_after_transfer, flt(reserved_qty_for_production - 5))
		ste1 = frappe.get_doc(make_stock_entry(pro_order.name, "Manufacture", 5))

		status = False
		for d in ste1.items:
			if d.item_code == 'Alternate Item For A RW 1':
				status = True

		self.assertEqual(status, True)
		ste1.submit()
예제 #6
0
	def _test_auto_material_request(self, item_code):
		item = frappe.get_doc("Item", item_code)

		if item.variant_of:
			template = frappe.get_doc("Item", item.variant_of)
		else:
			template = item

		# stock entry reqd for auto-reorder
		create_stock_reconciliation(item_code=item_code, warehouse="_Test Warehouse - _TC", 
			qty=10, rate=100)

		frappe.db.set_value("Stock Settings", None, "auto_indent", 1)
		projected_qty = frappe.db.get_value("Bin", {"item_code": item_code,
			"warehouse": "_Test Warehouse - _TC"}, "projected_qty") or 0

		# update re-level qty so that it is more than projected_qty
		if projected_qty > template.reorder_levels[0].warehouse_reorder_level:
			template.reorder_levels[0].warehouse_reorder_level += projected_qty
			template.save()

		from erpnext.stock.reorder_item import reorder_item
		mr_list = reorder_item()

		frappe.db.set_value("Stock Settings", None, "auto_indent", 0)

		items = []
		for mr in mr_list:
			for d in mr.items:
				items.append(d.item_code)

		self.assertTrue(item_code in items)
	def test_return_entire_bundled_items(self):
		set_perpetual_inventory()

		create_stock_reconciliation(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, rate=100)
		create_stock_reconciliation(item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC",
			qty=50, rate=100)

		dn = create_delivery_note(item_code="_Test Product Bundle Item", qty=5, rate=500)

		#  return bundled item
		dn1 = create_delivery_note(item_code='_Test Product Bundle Item', is_return=1,
			return_against=dn.name, qty=-2, rate=500)

		# qty after return
		actual_qty = get_qty_after_transaction()
		self.assertEquals(actual_qty, 35)

		# Check incoming rate for return entry
		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(incoming_rate, 100)

		# Check gl entry for warehouse
		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, 1400)

		set_perpetual_inventory(0)
예제 #8
0
def make_items():
	items = ['Test Finished Goods - A', 'Test FG A RW 1', 'Test FG A RW 2', 'Alternate Item For A RW 1']
	for item_code in items:
		if not frappe.db.exists('Item', item_code):
			create_item(item_code)

	create_stock_reconciliation(item_code="Test FG A RW 1",
		warehouse='_Test Warehouse - _TC', qty=10, rate=2000)

	if frappe.db.exists('Item', 'Test FG A RW 1'):
		doc = frappe.get_doc('Item', 'Test FG A RW 1')
		doc.allow_alternative_item = 1
		doc.save()

	if frappe.db.exists('Item', 'Test Finished Goods - A'):
		doc = frappe.get_doc('Item', 'Test Finished Goods - A')
		doc.is_sub_contracted_item = 1
		doc.save()

	if not frappe.db.get_value('BOM',
		{'item': 'Test Finished Goods - A', 'docstatus': 1}):
		make_bom(item = 'Test Finished Goods - A', raw_materials = ['Test FG A RW 1', 'Test FG A RW 2'])

	if not frappe.db.get_value('Warehouse', {'warehouse_name': 'Test Supplier Warehouse'}):
		frappe.get_doc({
			'doctype': 'Warehouse',
			'warehouse_name': 'Test Supplier Warehouse',
			'company': '_Test Company'
		}).insert(ignore_permissions=True)
예제 #9
0
	def test_material_transfer_gl_entry(self):
		set_perpetual_inventory()

		create_stock_reconciliation(qty=100, rate=100)

		mtn = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
			target="_Test Warehouse 1 - _TC", qty=45)

		self.check_stock_ledger_entries("Stock Entry", mtn.name,
			[["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]])

		stock_in_hand_account = frappe.db.get_value("Account", {"account_type": "Warehouse",
			"warehouse": mtn.get("items")[0].s_warehouse})

		fixed_asset_account = frappe.db.get_value("Account", {"account_type": "Warehouse",
			"warehouse": mtn.get("items")[0].t_warehouse})

		stock_value_diff = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Stock Entry",
			"voucher_no": mtn.name, "warehouse": "_Test Warehouse - _TC"}, "stock_value_difference"))

		self.check_gl_entries("Stock Entry", mtn.name,
			sorted([
				[stock_in_hand_account, 0.0, stock_value_diff],
				[fixed_asset_account, stock_value_diff, 0.0],
			])
		)

		mtn.cancel()
		self.assertFalse(frappe.db.sql("""select * from `tabStock Ledger Entry`
			where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))

		self.assertFalse(frappe.db.sql("""select * from `tabGL Entry`
			where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))
	def test_alternative_item_for_production_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)
		pro_order = make_wo_order_test_record(production_item='Test Finished Goods - A',
			qty=5, source_warehouse='_Test Warehouse - _TC', wip_warehouse='Test Supplier Warehouse - _TC')

		reserved_qty_for_production = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_production')

		ste = frappe.get_doc(make_stock_entry(pro_order.name, "Material Transfer for Manufacture", 5))
		ste.insert()

		for item in ste.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'

		ste.submit()
		reserved_qty_for_production_after_transfer = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_production')

		self.assertEqual(reserved_qty_for_production_after_transfer, flt(reserved_qty_for_production - 5))
		ste1 = frappe.get_doc(make_stock_entry(pro_order.name, "Manufacture", 5))

		status = False
		for d in ste1.items:
			if d.item_code == 'Alternate Item For A RW 1':
				status = True

		self.assertEqual(status, True)
		ste1.submit()
def make_items():
	items = ['Test Finished Goods - A', 'Test FG A RW 1', 'Test FG A RW 2', 'Alternate Item For A RW 1']
	for item_code in items:
		if not frappe.db.exists('Item', item_code):
			create_item(item_code)

	create_stock_reconciliation(item_code="Test FG A RW 1",
		warehouse='_Test Warehouse - _TC', qty=10, rate=2000)

	if frappe.db.exists('Item', 'Test FG A RW 1'):
		doc = frappe.get_doc('Item', 'Test FG A RW 1')
		doc.allow_alternative_item = 1
		doc.save()

	if frappe.db.exists('Item', 'Test Finished Goods - A'):
		doc = frappe.get_doc('Item', 'Test Finished Goods - A')
		doc.is_sub_contracted_item = 1
		doc.save()

	if not frappe.db.get_value('BOM',
		{'item': 'Test Finished Goods - A', 'docstatus': 1}):
		make_bom(item = 'Test Finished Goods - A', raw_materials = ['Test FG A RW 1', 'Test FG A RW 2'])

	if not frappe.db.get_value('Warehouse', {'warehouse_name': 'Test Supplier Warehouse'}):
		frappe.get_doc({
			'doctype': 'Warehouse',
			'warehouse_name': 'Test Supplier Warehouse',
			'company': '_Test Company'
		}).insert(ignore_permissions=True)
예제 #12
0
	def _test_auto_material_request(self, item_code):
		item = frappe.get_doc("Item", item_code)

		if item.variant_of:
			template = frappe.get_doc("Item", item.variant_of)
		else:
			template = item

		# stock entry reqd for auto-reorder
		create_stock_reconciliation(item_code=item_code, warehouse="_Test Warehouse - _TC",
			qty=10, rate=100)

		frappe.db.set_value("Stock Settings", None, "auto_indent", 1)
		projected_qty = frappe.db.get_value("Bin", {"item_code": item_code,
			"warehouse": "_Test Warehouse - _TC"}, "projected_qty") or 0

		# update re-level qty so that it is more than projected_qty
		if projected_qty > template.reorder_levels[0].warehouse_reorder_level:
			template.reorder_levels[0].warehouse_reorder_level += projected_qty
			template.save()

		from erpnext.stock.reorder_item import reorder_item
		mr_list = reorder_item()

		frappe.db.set_value("Stock Settings", None, "auto_indent", 0)

		items = []
		for mr in mr_list:
			for d in mr.items:
				items.append(d.item_code)

		self.assertTrue(item_code in items)
예제 #13
0
	def _test_auto_material_request(self, item_code, material_request_type="Purchase", warehouse="_Test Warehouse - _TC"):
		variant = frappe.get_doc("Item", item_code)

		projected_qty, actual_qty = frappe.db.get_value("Bin", {"item_code": item_code,
			"warehouse": warehouse}, ["projected_qty", "actual_qty"]) or [0, 0]

		# stock entry reqd for auto-reorder
		create_stock_reconciliation(item_code=item_code, warehouse=warehouse,
			qty = actual_qty + abs(projected_qty) + 10, rate=100)

		projected_qty = frappe.db.get_value("Bin", {"item_code": item_code,
			"warehouse": warehouse}, "projected_qty") or 0

		frappe.db.set_value("Stock Settings", None, "auto_indent", 1)

		# update re-level qty so that it is more than projected_qty
		if projected_qty >= variant.reorder_levels[0].warehouse_reorder_level:
			variant.reorder_levels[0].warehouse_reorder_level += projected_qty
			variant.reorder_levels[0].material_request_type = material_request_type
			variant.save()

		from erpnext.stock.reorder_item import reorder_item
		mr_list = reorder_item()

		frappe.db.set_value("Stock Settings", None, "auto_indent", 0)

		items = []
		for mr in mr_list:
			for d in mr.items:
				items.append(d.item_code)

		self.assertTrue(item_code in items)
예제 #14
0
	def test_material_transfer_gl_entry(self):
		set_perpetual_inventory()

		create_stock_reconciliation(qty=100, rate=100)

		mtn = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
			target="_Test Warehouse 1 - _TC", qty=45)

		self.check_stock_ledger_entries("Stock Entry", mtn.name,
			[["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]])

		stock_in_hand_account = frappe.db.get_value("Account", {"account_type": "Warehouse",
			"warehouse": mtn.get("items")[0].s_warehouse})

		fixed_asset_account = frappe.db.get_value("Account", {"account_type": "Warehouse",
			"warehouse": mtn.get("items")[0].t_warehouse})

		stock_value_diff = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Stock Entry",
			"voucher_no": mtn.name, "warehouse": "_Test Warehouse - _TC"}, "stock_value_difference"))

		self.check_gl_entries("Stock Entry", mtn.name,
			sorted([
				[stock_in_hand_account, 0.0, stock_value_diff],
				[fixed_asset_account, stock_value_diff, 0.0],
			])
		)

		mtn.cancel()
		self.assertFalse(frappe.db.sql("""select * from `tabStock Ledger Entry`
			where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))

		self.assertFalse(frappe.db.sql("""select * from `tabGL Entry`
			where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))
예제 #15
0
	def test_update_bom_cost_in_all_boms(self):
		# get current rate for '_Test Item 2'
		rm_rate = frappe.db.sql("""select rate from `tabBOM Item`
			where parent='BOM-_Test Item Home Desktop Manufactured-001'
			and item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""")
		rm_rate = rm_rate[0][0] if rm_rate else 0

		# update valuation rate of item '_Test Item 2'
		warehouse_list = frappe.db.sql_list("""select warehouse from `tabBin`
			where item_code='_Test Item 2' and actual_qty > 0""")

		if not warehouse_list:
			warehouse_list.append("_Test Warehouse - _TC")

		for warehouse in warehouse_list:
			create_stock_reconciliation(item_code="_Test Item 2", warehouse=warehouse,
				qty=200, rate=rm_rate + 10)

		# update cost of all BOMs based on latest valuation rate
		update_cost()

		# check if new valuation rate updated in all BOMs
		for d in frappe.db.sql("""select rate from `tabBOM Item`
			where item_code='_Test Item 2' and docstatus=1 and parenttype='BOM'""", as_dict=1):
				self.assertEqual(d.rate, rm_rate + 10)
예제 #16
0
    def test_update_bom_cost_in_all_boms(self):
        # get current rate for '_Test Item 2'
        rm_rate = frappe.db.sql("""select rate from `tabBOM Item`
			where parent='BOM-_Test Item Home Desktop Manufactured-001'
			and item_code='_Test Item 2' and docstatus=1""")
        rm_rate = rm_rate[0][0] if rm_rate else 0

        # update valuation rate of item '_Test Item 2'
        warehouse_list = frappe.db.sql_list("""select warehouse from `tabBin`
			where item_code='_Test Item 2' and actual_qty > 0""")

        if not warehouse_list:
            warehouse_list.append("_Test Warehouse - _TC")

        for warehouse in warehouse_list:
            create_stock_reconciliation(item_code="_Test Item 2",
                                        warehouse=warehouse,
                                        qty=200,
                                        rate=rm_rate + 10)

        # update cost of all BOMs based on latest valuation rate
        update_cost()

        # check if new valuation rate updated in all BOMs
        for d in frappe.db.sql("""select rate from `tabBOM Item`
			where item_code='_Test Item 2' and docstatus=1""",
                               as_dict=1):
            self.assertEqual(d.rate, rm_rate + 10)
예제 #17
0
    def test_alternative_item_for_production_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)
        pro_order = make_wo_order_test_record(
            production_item="Test Finished Goods - A",
            qty=5,
            source_warehouse="_Test Warehouse - _TC",
            wip_warehouse="Test Supplier Warehouse - _TC",
        )

        reserved_qty_for_production = frappe.db.get_value(
            "Bin",
            {
                "item_code": "Test FG A RW 1",
                "warehouse": "_Test Warehouse - _TC"
            },
            "reserved_qty_for_production",
        )

        ste = frappe.get_doc(
            make_stock_entry(pro_order.name,
                             "Material Transfer for Manufacture", 5))
        ste.insert()

        for item in ste.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"

        ste.submit()
        reserved_qty_for_production_after_transfer = frappe.db.get_value(
            "Bin",
            {
                "item_code": "Test FG A RW 1",
                "warehouse": "_Test Warehouse - _TC"
            },
            "reserved_qty_for_production",
        )

        self.assertEqual(reserved_qty_for_production_after_transfer,
                         flt(reserved_qty_for_production - 5))
        ste1 = frappe.get_doc(
            make_stock_entry(pro_order.name, "Manufacture", 5))

        status = False
        for d in ste1.items:
            if d.item_code == "Alternate Item For A RW 1":
                status = True

        self.assertEqual(status, True)
        ste1.submit()
예제 #18
0
    def test_return_single_item_from_bundled_items(self):
        set_perpetual_inventory()

        create_stock_reconciliation(item_code="_Test Item",
                                    target="_Test Warehouse - _TC",
                                    qty=50,
                                    rate=100)
        create_stock_reconciliation(item_code="_Test Item Home Desktop 100",
                                    target="_Test Warehouse - _TC",
                                    qty=50,
                                    rate=100)

        dn = create_delivery_note(item_code="_Test Product Bundle Item",
                                  qty=5,
                                  rate=500)

        # Qty after delivery
        actual_qty_1 = get_qty_after_transaction()
        self.assertEquals(actual_qty_1, 25)

        # outgoing_rate
        outgoing_rate = frappe.db.get_value(
            "Stock Ledger Entry", {
                "voucher_type": "Delivery Note",
                "voucher_no": dn.name,
                "item_code": "_Test Item"
            }, "stock_value_difference") / 25

        # return 'test item' from packed items
        dn1 = create_delivery_note(is_return=1,
                                   return_against=dn.name,
                                   qty=-10,
                                   rate=500)

        # qty after return
        actual_qty_2 = get_qty_after_transaction()
        self.assertEquals(actual_qty_2, 35)

        # Check incoming rate for return entry
        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)))

        # Check gl entry for warehouse
        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)
예제 #19
0
	def test_delivery_of_bundled_items_to_target_warehouse(self):
		company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')

		set_valuation_method("_Test Item", "FIFO")
		set_valuation_method("_Test Item Home Desktop 100", "FIFO")

		target_warehouse=get_warehouse(company=company, abbr="TCP1",
			warehouse_name="_Test Customer Warehouse").name

		for warehouse in ("Stores - TCP1", target_warehouse):
			create_stock_reconciliation(item_code="_Test Item", warehouse=warehouse, company = company,
				expense_account = "Stock Adjustment - TCP1", qty=500, rate=100)
			create_stock_reconciliation(item_code="_Test Item Home Desktop 100", company = company,
				expense_account = "Stock Adjustment - TCP1", warehouse=warehouse, qty=500, rate=100)

		dn = create_delivery_note(item_code="_Test Product Bundle Item",
			company='_Test Company with perpetual inventory', cost_center = 'Main - TCP1',
			expense_account = "Cost of Goods Sold - TCP1", do_not_submit=True, qty=5, rate=500,
			warehouse="Stores - TCP1", target_warehouse=target_warehouse)

		dn.submit()

		# qty after delivery
		actual_qty_at_source = get_qty_after_transaction(warehouse="Stores - TCP1")
		self.assertEqual(actual_qty_at_source, 475)

		actual_qty_at_target = get_qty_after_transaction(warehouse=target_warehouse)
		self.assertEqual(actual_qty_at_target, 525)

		# stock value diff for source warehouse for "_Test Item"
		stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
			{"voucher_type": "Delivery Note", "voucher_no": dn.name,
				"item_code": "_Test Item", "warehouse": "Stores - TCP1"},
			"stock_value_difference")

		# stock value diff for target warehouse
		stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry",
			{"voucher_type": "Delivery Note", "voucher_no": dn.name,
				"item_code": "_Test Item", "warehouse": target_warehouse},
			"stock_value_difference")

		self.assertEqual(abs(stock_value_difference), stock_value_difference1)

		# Check gl entries
		gl_entries = get_gl_entries("Delivery Note", dn.name)
		self.assertTrue(gl_entries)

		stock_value_difference = abs(frappe.db.sql("""select sum(stock_value_difference)
			from `tabStock Ledger Entry` where voucher_type='Delivery Note' and voucher_no=%s
			and warehouse='Stores - TCP1'""", dn.name)[0][0])

		expected_values = {
			"Stock In Hand - TCP1": [0.0, stock_value_difference],
			target_warehouse: [stock_value_difference, 0.0]
		}
		for i, gle in enumerate(gl_entries):
			self.assertEqual([gle.debit, gle.credit], expected_values.get(gle.account))
예제 #20
0
	def test_delivery_of_bundled_items_to_target_warehouse(self):
		set_perpetual_inventory()
		frappe.db.set_value("Item", "_Test Item", "valuation_method", "FIFO")

		for warehouse in ("_Test Warehouse - _TC", "_Test Warehouse 1 - _TC"):
			create_stock_reconciliation(item_code="_Test Item", target=warehouse,
				qty=50, rate=100)
			create_stock_reconciliation(item_code="_Test Item Home Desktop 100",
				target=warehouse, qty=50, rate=100)

		opening_qty_test_warehouse_1 = get_qty_after_transaction(warehouse="_Test Warehouse 1 - _TC")

		dn = create_delivery_note(item_code="_Test Product Bundle Item",
			qty=5, rate=500, target_warehouse="_Test Warehouse 1 - _TC", do_not_submit=True)

		dn.submit()

		# qty after delivery
		actual_qty = get_qty_after_transaction(warehouse="_Test Warehouse - _TC")
		self.assertEquals(actual_qty, 25)

		actual_qty = get_qty_after_transaction(warehouse="_Test Warehouse 1 - _TC")
		self.assertEquals(actual_qty, opening_qty_test_warehouse_1 + 25)

		# stock value diff for source warehouse
		stock_value_difference = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note",
			"voucher_no": dn.name, "item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse - _TC"},
			"stock_value_difference")

		# stock value diff for target warehouse
		stock_value_difference1 = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note",
			"voucher_no": dn.name, "item_code": "_Test Item Home Desktop 100", "warehouse": "_Test Warehouse 1 - _TC"},
			"stock_value_difference")

		self.assertEquals(abs(stock_value_difference), stock_value_difference1)

		# Check gl entries
		gl_entries = get_gl_entries("Delivery Note", dn.name)
		self.assertTrue(gl_entries)

		stock_value_difference = abs(frappe.db.sql("""select sum(stock_value_difference)
			from `tabStock Ledger Entry` where voucher_type='Delivery Note' and voucher_no=%s
			and warehouse='_Test Warehouse - _TC'""", dn.name)[0][0])

		expected_values = {
			"_Test Warehouse - _TC": [0.0, stock_value_difference],
			"_Test Warehouse 1 - _TC": [stock_value_difference, 0.0]
		}
		for i, gle in enumerate(gl_entries):
			self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account))

		set_perpetual_inventory(0)
예제 #21
0
	def test_production_plan_for_existing_ordered_qty(self):
		sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
			target="_Test Warehouse - _TC", qty=1, rate=100)
		sr2 = create_stock_reconciliation(item_code="Raw Material Item 2",
			target="_Test Warehouse - _TC", qty=1, rate=100)

		pln = create_production_plan(item_code='Test Production Item 1', ignore_existing_ordered_qty=0)
		self.assertTrue(len(pln.mr_items), 1)
		self.assertTrue(flt(pln.mr_items[0].quantity), 1.0)

		sr1.cancel()
		sr2.cancel()
		pln.cancel()
예제 #22
0
	def test_production_plan_without_multi_level_for_existing_ordered_qty(self):
		sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
			target="_Test Warehouse - _TC", qty=1, rate=100)
		sr2 = create_stock_reconciliation(item_code="Subassembly Item 1",
			target="_Test Warehouse - _TC", qty=1, rate=100)

		pln = create_production_plan(item_code='Test Production Item 1',
			use_multi_level_bom=0, ignore_existing_ordered_qty=0)
		self.assertTrue(len(pln.mr_items), 0)

		sr1.cancel()
		sr2.cancel()
		pln.cancel()
예제 #23
0
	def test_production_plan_for_existing_ordered_qty(self):
		sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
			target="_Test Warehouse - _TC", qty=1, rate=100)
		sr2 = create_stock_reconciliation(item_code="Raw Material Item 2",
			target="_Test Warehouse - _TC", qty=1, rate=100)

		pln = create_production_plan(item_code='Test Production Item 1', ignore_existing_ordered_qty=0)
		self.assertTrue(len(pln.mr_items), 1)
		self.assertTrue(flt(pln.mr_items[0].quantity), 1.0)

		sr1.cancel()
		sr2.cancel()
		pln.cancel()
예제 #24
0
	def test_production_plan_without_multi_level_for_existing_ordered_qty(self):
		sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
			target="_Test Warehouse - _TC", qty=1, rate=100)
		sr2 = create_stock_reconciliation(item_code="Subassembly Item 1",
			target="_Test Warehouse - _TC", qty=1, rate=100)

		pln = create_production_plan(item_code='Test Production Item 1',
			use_multi_level_bom=0, ignore_existing_ordered_qty=0)
		self.assertTrue(len(pln.mr_items), 0)

		sr1.cancel()
		sr2.cancel()
		pln.cancel()
예제 #25
0
    def test_fifo(self):
        frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
        item_code = "_Test Item 2"
        warehouse = "_Test Warehouse - _TC"

        create_stock_reconciliation(item_code="_Test Item 2",
                                    warehouse="_Test Warehouse - _TC",
                                    qty=0,
                                    rate=100)

        make_stock_entry(item_code=item_code,
                         target=warehouse,
                         qty=1,
                         basic_rate=10)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]

        self.assertEqual([[1, 10]], frappe.safe_eval(sle.stock_queue))

        # negative qty
        make_stock_entry(item_code=item_code,
                         source=warehouse,
                         qty=2,
                         basic_rate=10)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]

        self.assertEqual([[-1, 10]], frappe.safe_eval(sle.stock_queue))

        # further negative
        make_stock_entry(item_code=item_code, source=warehouse, qty=1)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]

        self.assertEqual([[-2, 10]], frappe.safe_eval(sle.stock_queue))

        # move stock to positive
        make_stock_entry(item_code=item_code,
                         target=warehouse,
                         qty=3,
                         basic_rate=20)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]
        self.assertEqual([[1, 20]], frappe.safe_eval(sle.stock_queue))

        # incoming entry with diff rate
        make_stock_entry(item_code=item_code,
                         target=warehouse,
                         qty=1,
                         basic_rate=30)
        sle = get_sle(item_code=item_code, warehouse=warehouse)[0]

        self.assertEqual([[1, 20], [1, 30]], frappe.safe_eval(sle.stock_queue))

        frappe.db.set_default("allow_negative_stock", 0)
예제 #26
0
    def test_return_single_item_from_bundled_items(self):
        set_perpetual_inventory()

        create_stock_reconciliation(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, rate=100)
        create_stock_reconciliation(
            item_code="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=50, rate=100
        )

        dn = create_delivery_note(item_code="_Test Product Bundle Item", qty=5, rate=500)

        # Qty after delivery
        actual_qty_1 = get_qty_after_transaction()
        self.assertEquals(actual_qty_1, 25)

        # outgoing_rate
        outgoing_rate = (
            frappe.db.get_value(
                "Stock Ledger Entry",
                {"voucher_type": "Delivery Note", "voucher_no": dn.name, "item_code": "_Test Item"},
                "stock_value_difference",
            )
            / 25
        )

        # return 'test item' from packed items
        dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-10, rate=500)

        # qty after return
        actual_qty_2 = get_qty_after_transaction()
        self.assertEquals(actual_qty_2, 35)

        # Check incoming rate for return entry
        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)))

        # Check gl entry for warehouse
        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)
예제 #27
0
def reset_item_valuation_rate(item_code, warehouse_list=None, qty=None, rate=None):
	if warehouse_list and isinstance(warehouse_list, string_types):
		warehouse_list = [warehouse_list]

	if not warehouse_list:
		warehouse_list = frappe.db.sql_list("""
			select warehouse from `tabBin`
			where item_code=%s and actual_qty > 0
		""", item_code)

		if not warehouse_list:
			warehouse_list.append("_Test Warehouse - _TC")

	for warehouse in warehouse_list:
		create_stock_reconciliation(item_code=item_code, warehouse=warehouse, qty=qty, rate=rate)
예제 #28
0
	def test_alternative_item_for_subcontract_rm(self):
		create_stock_reconciliation(item_code='Alternate Item For A RW 1', warehouse='_Test Warehouse - _TC',
			qty=5, rate=2000)
		create_stock_reconciliation(item_code='Test FG A RW 2', warehouse='_Test Warehouse - _TC',
			qty=5, rate=2000)

		supplier_warehouse = "Test Supplier Warehouse - _TC"
		po = create_purchase_order(item = "Test Finished Goods - A",
			is_subcontracted='Yes', qty=5, rate=3000, supplier_warehouse=supplier_warehouse)

		rm_item = [{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 1", "item_name":"Test FG A RW 1",
					"qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"},
					{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 2", "item_name":"Test FG A RW 2",
					"qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"}]

		rm_item_string = json.dumps(rm_item)
		reserved_qty_for_sub_contract = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract')

		se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string))
		se.to_warehouse = supplier_warehouse
		se.insert()

		doc = frappe.get_doc('Stock Entry', se.name)
		for item in doc.items:
			if item.item_code == 'Test FG A RW 1':
				item.item_code = 'Alternate Item For A RW 1'
				item.item_name = 'Alternate Item For A RW 1'
				item.description = 'Alternate Item For A RW 1'
				item.original_item = 'Test FG A RW 1'

		doc.save()
		doc.submit()
		after_transfer_reserved_qty_for_sub_contract = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract')

		self.assertEqual(after_transfer_reserved_qty_for_sub_contract, flt(reserved_qty_for_sub_contract - 5))

		pr = make_purchase_receipt(po.name)
		pr.save()

		pr = frappe.get_doc('Purchase Receipt', pr.name)
		status = False
		for d in pr.supplied_items:
			if d.rm_item_code == 'Alternate Item For A RW 1':
				status = True

		self.assertEqual(status, True)
	def test_alternative_item_for_subcontract_rm(self):
		create_stock_reconciliation(item_code='Alternate Item For A RW 1', warehouse='_Test Warehouse - _TC',
			qty=5, rate=2000)
		create_stock_reconciliation(item_code='Test FG A RW 2', warehouse='_Test Warehouse - _TC',
			qty=5, rate=2000)

		supplier_warehouse = "Test Supplier Warehouse - _TC"
		po = create_purchase_order(item = "Test Finished Goods - A",
			is_subcontracted='Yes', qty=5, rate=3000, supplier_warehouse=supplier_warehouse)

		rm_item = [{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 1", "item_name":"Test FG A RW 1",
					"qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"},
					{"item_code": "Test Finished Goods - A", "rm_item_code": "Test FG A RW 2", "item_name":"Test FG A RW 2",
					"qty":5, "warehouse":"_Test Warehouse - _TC", "rate":2000, "amount":10000, "stock_uom":"Nos"}]

		rm_item_string = json.dumps(rm_item)
		reserved_qty_for_sub_contract = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract')

		se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string))
		se.to_warehouse = supplier_warehouse
		se.insert()

		doc = frappe.get_doc('Stock Entry', se.name)
		for item in doc.items:
			if item.item_code == 'Test FG A RW 1':
				item.item_code = 'Alternate Item For A RW 1'
				item.item_name = 'Alternate Item For A RW 1'
				item.description = 'Alternate Item For A RW 1'
				item.original_item = 'Test FG A RW 1'

		doc.save()
		doc.submit()
		after_transfer_reserved_qty_for_sub_contract = frappe.db.get_value('Bin',
			{'item_code': 'Test FG A RW 1', 'warehouse': '_Test Warehouse - _TC'}, 'reserved_qty_for_sub_contract')

		self.assertEqual(after_transfer_reserved_qty_for_sub_contract, flt(reserved_qty_for_sub_contract - 5))

		pr = make_purchase_receipt(po.name)
		pr.save()

		pr = frappe.get_doc('Purchase Receipt', pr.name)
		status = False
		for d in pr.supplied_items:
			if d.rm_item_code == 'Alternate Item For A RW 1':
				status = True

		self.assertEqual(status, True)
예제 #30
0
	def test_return_single_item_from_bundled_items(self):
		company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')

		create_stock_reconciliation(item_code="_Test Item",
			warehouse="Stores - TCP1", qty=50, rate=100,
			company=company, expense_account = "Stock Adjustment - TCP1")
		create_stock_reconciliation(item_code="_Test Item Home Desktop 100",
			warehouse="Stores - TCP1", qty=50, rate=100,
			company=company, expense_account = "Stock Adjustment - TCP1")

		dn = create_delivery_note(item_code="_Test Product Bundle Item", qty=5, rate=500,
			company=company, warehouse="Stores - TCP1",
			expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1")

		# Qty after delivery
		actual_qty_1 = get_qty_after_transaction(warehouse="Stores - TCP1")
		self.assertEqual(actual_qty_1,  25)

		# outgoing_rate
		outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Delivery Note",
			"voucher_no": dn.name, "item_code": "_Test Item"}, "stock_value_difference") / 25

		# return 'test item' from packed items
		dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-10, rate=500,
			company=company, warehouse="Stores - TCP1",
			expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1")

		# qty after return
		actual_qty_2 = get_qty_after_transaction(warehouse="Stores - TCP1")
		self.assertEqual(actual_qty_2, 35)

		# Check incoming rate for return entry
		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)

		# Check gl entry for 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)
예제 #31
0
def make_items():
    items = [
        "Test Finished Goods - A",
        "Test FG A RW 1",
        "Test FG A RW 2",
        "Alternate Item For A RW 1",
    ]
    for item_code in items:
        if not frappe.db.exists("Item", item_code):
            create_item(item_code)

    try:
        create_stock_reconciliation(item_code="Test FG A RW 1",
                                    warehouse="_Test Warehouse - _TC",
                                    qty=10,
                                    rate=2000)
    except EmptyStockReconciliationItemsError:
        pass

    if frappe.db.exists("Item", "Test FG A RW 1"):
        doc = frappe.get_doc("Item", "Test FG A RW 1")
        doc.allow_alternative_item = 1
        doc.save()

    if frappe.db.exists("Item", "Test Finished Goods - A"):
        doc = frappe.get_doc("Item", "Test Finished Goods - A")
        doc.is_sub_contracted_item = 1
        doc.save()

    if not frappe.db.get_value("BOM", {
            "item": "Test Finished Goods - A",
            "docstatus": 1
    }):
        make_bom(item="Test Finished Goods - A",
                 raw_materials=["Test FG A RW 1", "Test FG A RW 2"])

    if not frappe.db.get_value("Warehouse",
                               {"warehouse_name": "Test Supplier Warehouse"}):
        frappe.get_doc({
            "doctype": "Warehouse",
            "warehouse_name": "Test Supplier Warehouse",
            "company": "_Test Company",
        }).insert(ignore_permissions=True)
예제 #32
0
	def test_return_entire_bundled_items(self):
		company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')

		create_stock_reconciliation(item_code="_Test Item",
			warehouse="Stores - TCP1", qty=50, rate=100,
			company=company, expense_account = "Stock Adjustment - TCP1")
		create_stock_reconciliation(item_code="_Test Item Home Desktop 100",
			warehouse="Stores - TCP1", qty=50, rate=100,
			company=company, expense_account = "Stock Adjustment - TCP1")

		actual_qty = get_qty_after_transaction(warehouse="Stores - TCP1")
		self.assertEqual(actual_qty, 50)

		dn = create_delivery_note(item_code="_Test Product Bundle Item",
			qty=5, rate=500, company=company, warehouse="Stores - TCP1", expense_account="Cost of Goods Sold - TCP1", cost_center="Main - TCP1")

		# qty after return
		actual_qty = get_qty_after_transaction(warehouse="Stores - TCP1")
		self.assertEqual(actual_qty, 25)

		#  return bundled item
		dn1 = create_delivery_note(item_code='_Test Product Bundle Item', 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")

		# qty after return
		actual_qty = get_qty_after_transaction(warehouse="Stores - TCP1")
		self.assertEqual(actual_qty, 35)

		# Check incoming rate for return entry
		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(incoming_rate, 100)
		stock_in_hand_account = get_inventory_account('_Test Company', dn1.items[0].warehouse)

		# Check gl entry for 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, 1400)
예제 #33
0
    def test_production_plan_for_existing_ordered_qty(self):
        """
		- Enable 'ignore_existing_ordered_qty'.
		- Test if MR Planning table pulls Raw Material Qty even if it is in stock.
		"""
        sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
                                          target="_Test Warehouse - _TC",
                                          qty=1,
                                          rate=110)
        sr2 = create_stock_reconciliation(item_code="Raw Material Item 2",
                                          target="_Test Warehouse - _TC",
                                          qty=1,
                                          rate=120)

        pln = create_production_plan(item_code="Test Production Item 1",
                                     ignore_existing_ordered_qty=1)
        self.assertTrue(len(pln.mr_items), 1)
        self.assertTrue(flt(pln.mr_items[0].quantity), 1.0)

        sr1.cancel()
        sr2.cancel()
        pln.cancel()
예제 #34
0
	def test_material_transfer_gl_entry(self):
		company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
		set_perpetual_inventory(1, company)

		create_stock_reconciliation(qty=100, rate=100)

		mtn = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
			target="_Test Warehouse 1 - _TC", qty=45)

		self.check_stock_ledger_entries("Stock Entry", mtn.name,
			[["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]])

		stock_in_hand_account = get_inventory_account(mtn.company, mtn.get("items")[0].s_warehouse)

		fixed_asset_account = get_inventory_account(mtn.company, mtn.get("items")[0].t_warehouse)

		if stock_in_hand_account == fixed_asset_account:
			# no gl entry as both source and target warehouse has linked to same account.
			self.assertFalse(frappe.db.sql("""select * from `tabGL Entry`
				where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))

		else:
			stock_value_diff = abs(frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Stock Entry",
				"voucher_no": mtn.name, "warehouse": "_Test Warehouse - _TC"}, "stock_value_difference"))

			self.check_gl_entries("Stock Entry", mtn.name,
				sorted([
					[stock_in_hand_account, 0.0, stock_value_diff],
					[fixed_asset_account, stock_value_diff, 0.0],
				])
			)

		mtn.cancel()
		self.assertFalse(frappe.db.sql("""select * from `tabStock Ledger Entry`
			where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))

		self.assertFalse(frappe.db.sql("""select * from `tabGL Entry`
			where voucher_type='Stock Entry' and voucher_no=%s""", mtn.name))
예제 #35
0
def initialize_records_for_future_negative_sle_test(
	item_code, batch_no, warehouses, opening_qty, posting_date
):
	from erpnext.stock.doctype.batch.test_batch import TestBatch, make_new_batch
	from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
		create_stock_reconciliation,
	)
	from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse

	TestBatch.make_batch_item(item_code)
	make_new_batch(item_code=item_code, batch_id=batch_no)
	warehouse_names = [create_warehouse(w) for w in warehouses]
	create_stock_reconciliation(
		purpose="Opening Stock",
		posting_date=posting_date,
		posting_time="20:00:20",
		item_code=item_code,
		warehouse=warehouse_names[0],
		valuation_rate=100,
		qty=opening_qty,
		batch_no=batch_no,
	)
	return warehouse_names
예제 #36
0
    def test_pick_list_shows_serial_no_for_serialized_item(self):

        create_stock_reconciliation(
            item_code="_Test Serialized Item",
            target="_Test Warehouse - _TC",
            qty=5,
            rate=100,
            serial_no='123450\n123451\n123452\n123453\n123454')

        pick_list = frappe.get_doc({
            'doctype':
            'Pick List',
            'company':
            '_Test Company',
            'customer':
            '_Test Customer',
            'items_based_on':
            'Sales Order',
            'locations': [{
                'item_code': '_Test Serialized Item',
                'qty': 1000,
                'stock_qty': 1000,
                'conversion_factor': 1,
                'sales_order': '_T-Sales Order-1',
                'sales_order_item': '_T-Sales Order-1_item',
            }]
        })

        pick_list.set_item_locations()
        self.assertEqual(
            pick_list.get("locations")[0].item_code, '_Test Serialized Item')
        self.assertEqual(
            pick_list.get("locations")[0].warehouse, '_Test Warehouse - _TC')
        self.assertEqual(pick_list.get("locations")[0].qty, 5)
        self.assertEqual(
            pick_list.get("locations")[0].serial_no,
            '123450\n123451\n123452\n123453\n123454')
예제 #37
0
    def test_production_plan_without_multi_level_for_existing_ordered_qty(
            self):
        """
		- Disable 'ignore_existing_ordered_qty'.
		- Test if MR Planning table avoids pulling Raw Material Qty as it is in stock for
		non exploded BOM.
		"""
        sr1 = create_stock_reconciliation(item_code="Raw Material Item 1",
                                          target="_Test Warehouse - _TC",
                                          qty=1,
                                          rate=130)
        sr2 = create_stock_reconciliation(item_code="Subassembly Item 1",
                                          target="_Test Warehouse - _TC",
                                          qty=1,
                                          rate=140)

        pln = create_production_plan(item_code="Test Production Item 1",
                                     use_multi_level_bom=0,
                                     ignore_existing_ordered_qty=0)
        self.assertTrue(len(pln.mr_items), 0)

        sr1.cancel()
        sr2.cancel()
        pln.cancel()
예제 #38
0
    def test_delivery_of_bundled_items_to_target_warehouse(self):
        company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC',
                                      'company')
        set_perpetual_inventory(1, company)

        set_valuation_method("_Test Item", "FIFO")
        set_valuation_method("_Test Item Home Desktop 100", "FIFO")

        for warehouse in ("_Test Warehouse - _TC", "_Test Warehouse 1 - _TC"):
            create_stock_reconciliation(item_code="_Test Item",
                                        target=warehouse,
                                        qty=100,
                                        rate=100)
            create_stock_reconciliation(
                item_code="_Test Item Home Desktop 100",
                target=warehouse,
                qty=100,
                rate=100)

        opening_qty_test_warehouse_1 = get_qty_after_transaction(
            warehouse="_Test Warehouse 1 - _TC")
        dn = create_delivery_note(item_code="_Test Product Bundle Item",
                                  qty=5,
                                  rate=500,
                                  target_warehouse="_Test Warehouse 1 - _TC",
                                  do_not_submit=True)

        dn.submit()

        # qty after delivery
        actual_qty = get_qty_after_transaction(
            warehouse="_Test Warehouse - _TC")
        self.assertEquals(actual_qty, 75)

        actual_qty = get_qty_after_transaction(
            warehouse="_Test Warehouse 1 - _TC")
        self.assertEquals(actual_qty, opening_qty_test_warehouse_1 + 25)

        # stock value diff for source warehouse
        # for "_Test Item"
        stock_value_difference = frappe.db.get_value(
            "Stock Ledger Entry", {
                "voucher_type": "Delivery Note",
                "voucher_no": dn.name,
                "item_code": "_Test Item",
                "warehouse": "_Test Warehouse - _TC"
            }, "stock_value_difference")

        # stock value diff for target warehouse
        stock_value_difference1 = frappe.db.get_value(
            "Stock Ledger Entry", {
                "voucher_type": "Delivery Note",
                "voucher_no": dn.name,
                "item_code": "_Test Item",
                "warehouse": "_Test Warehouse 1 - _TC"
            }, "stock_value_difference")

        self.assertEquals(abs(stock_value_difference), stock_value_difference1)

        # for "_Test Item Home Desktop 100"
        stock_value_difference = frappe.db.get_value(
            "Stock Ledger Entry", {
                "voucher_type": "Delivery Note",
                "voucher_no": dn.name,
                "item_code": "_Test Item Home Desktop 100",
                "warehouse": "_Test Warehouse - _TC"
            }, "stock_value_difference")

        # stock value diff for target warehouse
        stock_value_difference1 = frappe.db.get_value(
            "Stock Ledger Entry", {
                "voucher_type": "Delivery Note",
                "voucher_no": dn.name,
                "item_code": "_Test Item Home Desktop 100",
                "warehouse": "_Test Warehouse 1 - _TC"
            }, "stock_value_difference")

        self.assertEquals(abs(stock_value_difference), stock_value_difference1)

        # Check gl entries
        gl_entries = get_gl_entries("Delivery Note", dn.name)
        self.assertTrue(gl_entries)

        stock_value_difference = abs(
            frappe.db.sql(
                """select sum(stock_value_difference)
			from `tabStock Ledger Entry` where voucher_type='Delivery Note' and voucher_no=%s
			and warehouse='_Test Warehouse - _TC'""", dn.name)[0][0])

        expected_values = {
            "Stock In Hand - _TC": [0.0, stock_value_difference],
            "_Test Warehouse 1 - _TC": [stock_value_difference, 0.0]
        }
        for i, gle in enumerate(gl_entries):
            self.assertEquals([gle.debit, gle.credit],
                              expected_values.get(gle.account))

        set_perpetual_inventory(0, company)
예제 #39
0
    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",
        )
예제 #40
0
    def test_delivery_of_bundled_items_to_target_warehouse(self):
        from erpnext.selling.doctype.customer.test_customer import create_internal_customer

        company = frappe.db.get_value("Warehouse", "Stores - TCP1", "company")
        customer_name = create_internal_customer(
            customer_name="_Test Internal Customer 2",
            represents_company="_Test Company with perpetual inventory",
            allowed_to_interact_with="_Test Company with perpetual inventory",
        )

        set_valuation_method("_Test Item", "FIFO")
        set_valuation_method("_Test Item Home Desktop 100", "FIFO")

        target_warehouse = get_warehouse(
            company=company,
            abbr="TCP1",
            warehouse_name="_Test Customer Warehouse").name

        for warehouse in ("Stores - TCP1", target_warehouse):
            create_stock_reconciliation(
                item_code="_Test Item",
                warehouse=warehouse,
                company=company,
                expense_account="Stock Adjustment - TCP1",
                qty=500,
                rate=100,
            )
            create_stock_reconciliation(
                item_code="_Test Item Home Desktop 100",
                company=company,
                expense_account="Stock Adjustment - TCP1",
                warehouse=warehouse,
                qty=500,
                rate=100,
            )

        dn = create_delivery_note(
            item_code="_Test Product Bundle Item",
            company="_Test Company with perpetual inventory",
            customer=customer_name,
            cost_center="Main - TCP1",
            expense_account="Cost of Goods Sold - TCP1",
            qty=5,
            rate=500,
            warehouse="Stores - TCP1",
            target_warehouse=target_warehouse,
        )

        # qty after delivery
        actual_qty_at_source = get_qty_after_transaction(
            warehouse="Stores - TCP1")
        self.assertEqual(actual_qty_at_source, 475)

        actual_qty_at_target = get_qty_after_transaction(
            warehouse=target_warehouse)
        self.assertEqual(actual_qty_at_target, 525)

        # stock value diff for source warehouse for "_Test Item"
        stock_value_difference = frappe.db.get_value(
            "Stock Ledger Entry",
            {
                "voucher_type": "Delivery Note",
                "voucher_no": dn.name,
                "item_code": "_Test Item",
                "warehouse": "Stores - TCP1",
            },
            "stock_value_difference",
        )

        # stock value diff for target warehouse
        stock_value_difference1 = frappe.db.get_value(
            "Stock Ledger Entry",
            {
                "voucher_type": "Delivery Note",
                "voucher_no": dn.name,
                "item_code": "_Test Item",
                "warehouse": target_warehouse,
            },
            "stock_value_difference",
        )

        self.assertEqual(abs(stock_value_difference), stock_value_difference1)

        # Check gl entries
        gl_entries = get_gl_entries("Delivery Note", dn.name)
        self.assertTrue(gl_entries)

        stock_value_difference = abs(
            frappe.db.sql(
                """select sum(stock_value_difference)
			from `tabStock Ledger Entry` where voucher_type='Delivery Note' and voucher_no=%s
			and warehouse='Stores - TCP1'""",
                dn.name,
            )[0][0])

        expected_values = {
            "Stock In Hand - TCP1": [0.0, stock_value_difference],
            target_warehouse: [stock_value_difference, 0.0],
        }
        for i, gle in enumerate(gl_entries):
            self.assertEqual([gle.debit, gle.credit],
                             expected_values.get(gle.account))

        # tear down
        frappe.db.rollback()
예제 #41
0
    def test_item_cost_reposting(self):
        company = "_Test Company"

        # _Test Item for Reposting at Stores warehouse on 10-04-2020: Qty = 50, Rate = 100
        create_stock_reconciliation(item_code="_Test Item for Reposting",
                                    warehouse="Stores - _TC",
                                    qty=50,
                                    rate=100,
                                    company=company,
                                    expense_account="Stock Adjustment - _TC"
                                    if frappe.get_all("Stock Ledger Entry")
                                    else "Temporary Opening - _TC",
                                    posting_date='2020-04-10',
                                    posting_time='14:00')

        # _Test Item for Reposting at FG warehouse on 20-04-2020: Qty = 10, Rate = 200
        create_stock_reconciliation(item_code="_Test Item for Reposting",
                                    warehouse="Finished Goods - _TC",
                                    qty=10,
                                    rate=200,
                                    company=company,
                                    expense_account="Stock Adjustment - _TC"
                                    if frappe.get_all("Stock Ledger Entry")
                                    else "Temporary Opening - _TC",
                                    posting_date='2020-04-20',
                                    posting_time='14:00')

        # _Test Item for Reposting transferred from Stores to FG warehouse on 30-04-2020
        se = make_stock_entry(item_code="_Test Item for Reposting",
                              source="Stores - _TC",
                              target="Finished Goods - _TC",
                              company=company,
                              qty=10,
                              expense_account="Stock Adjustment - _TC"
                              if frappe.get_all("Stock Ledger Entry") else
                              "Temporary Opening - _TC",
                              posting_date='2020-04-30',
                              posting_time='14:00')
        target_wh_sle = frappe.db.get_value('Stock Ledger Entry', {
            "item_code": "_Test Item for Reposting",
            "warehouse": "Finished Goods - _TC",
            "voucher_type": "Stock Entry",
            "voucher_no": se.name
        }, ["valuation_rate"],
                                            as_dict=1)

        self.assertEqual(target_wh_sle.get("valuation_rate"), 150)

        # Repack entry on 5-5-2020
        repack = create_repack_entry(company=company,
                                     posting_date='2020-05-05',
                                     posting_time='14:00')

        finished_item_sle = frappe.db.get_value('Stock Ledger Entry', {
            "item_code": "_Test Finished Item for Reposting",
            "warehouse": "Finished Goods - _TC",
            "voucher_type": "Stock Entry",
            "voucher_no": repack.name
        }, ["incoming_rate", "valuation_rate"],
                                                as_dict=1)
        self.assertEqual(finished_item_sle.get("incoming_rate"), 540)
        self.assertEqual(finished_item_sle.get("valuation_rate"), 540)

        # Reconciliation for _Test Item for Reposting at Stores on 12-04-2020: Qty = 50, Rate = 150
        sr = create_stock_reconciliation(
            item_code="_Test Item for Reposting",
            warehouse="Stores - _TC",
            qty=50,
            rate=150,
            company=company,
            expense_account="Stock Adjustment - _TC"
            if frappe.get_all("Stock Ledger Entry") else
            "Temporary Opening - _TC",
            posting_date='2020-04-12',
            posting_time='14:00')

        # Check valuation rate of finished goods warehouse after back-dated entry at Stores
        target_wh_sle = get_previous_sle({
            "item_code": "_Test Item for Reposting",
            "warehouse": "Finished Goods - _TC",
            "posting_date": '2020-04-30',
            "posting_time": '14:00'
        })
        self.assertEqual(target_wh_sle.get("incoming_rate"), 150)
        self.assertEqual(target_wh_sle.get("valuation_rate"), 175)

        # Check valuation rate of repacked item after back-dated entry at Stores
        finished_item_sle = frappe.db.get_value('Stock Ledger Entry', {
            "item_code": "_Test Finished Item for Reposting",
            "warehouse": "Finished Goods - _TC",
            "voucher_type": "Stock Entry",
            "voucher_no": repack.name
        }, ["incoming_rate", "valuation_rate"],
                                                as_dict=1)
        self.assertEqual(finished_item_sle.get("incoming_rate"), 790)
        self.assertEqual(finished_item_sle.get("valuation_rate"), 790)

        # Check updated rate in Repack entry
        repack.reload()
        self.assertEqual(repack.items[0].get("basic_rate"), 150)
        self.assertEqual(repack.items[1].get("basic_rate"), 750)