Exemple #1
0
    def test_item_merging(self):
        create_item("Test Item for Merging 1")
        create_item("Test Item for Merging 2")

        make_stock_entry(item_code="Test Item for Merging 1",
                         target="_Test Warehouse - _TC",
                         qty=1,
                         rate=100)
        make_stock_entry(item_code="Test Item for Merging 2",
                         target="_Test Warehouse 1 - _TC",
                         qty=1,
                         rate=100)

        frappe.rename_doc("Item",
                          "Test Item for Merging 1",
                          "Test Item for Merging 2",
                          merge=True)

        self.assertFalse(frappe.db.exists("Item", "Test Item for Merging 1"))

        self.assertTrue(
            frappe.db.get_value(
                "Bin", {
                    "item_code": "Test Item for Merging 2",
                    "warehouse": "_Test Warehouse - _TC"
                }))

        self.assertTrue(
            frappe.db.get_value(
                "Bin", {
                    "item_code": "Test Item for Merging 2",
                    "warehouse": "_Test Warehouse 1 - _TC"
                }))
Exemple #2
0
    def test_repack_no_change_in_valuation(self):
        company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC',
                                      'company')

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

        repack = frappe.copy_doc(test_records[3])
        repack.posting_date = nowdate()
        repack.posting_time = nowtime()
        repack.set_stock_entry_type()
        repack.insert()
        repack.submit()

        self.check_stock_ledger_entries(
            "Stock Entry", repack.name,
            [["_Test Item", "_Test Warehouse - _TC", -50.0],
             ["_Test Item Home Desktop 100", "_Test Warehouse - _TC", 1]])

        gl_entries = frappe.db.sql("""select account, debit, credit
			from `tabGL Entry` where voucher_type='Stock Entry' and voucher_no=%s
			order by account desc""",
                                   repack.name,
                                   as_dict=1)
        self.assertFalse(gl_entries)
Exemple #3
0
    def test_material_issue_gl_entry(self):
        company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')
        make_stock_entry(item_code="_Test Item",
                         target="Stores - TCP1",
                         company=company,
                         qty=50,
                         basic_rate=100,
                         expense_account="Stock Adjustment - TCP1")

        mi = make_stock_entry(item_code="_Test Item",
                              source="Stores - TCP1",
                              company=company,
                              qty=40,
                              expense_account="Stock Adjustment - TCP1")

        self.check_stock_ledger_entries(
            "Stock Entry", mi.name, [["_Test Item", "Stores - TCP1", -40.0]])

        stock_in_hand_account = get_inventory_account(mi.company,
                                                      "Stores - TCP1")
        stock_value_diff = abs(
            frappe.db.get_value("Stock Ledger Entry", {
                "voucher_type": "Stock Entry",
                "voucher_no": mi.name
            }, "stock_value_difference"))

        self.check_gl_entries(
            "Stock Entry", mi.name,
            sorted([[stock_in_hand_account, 0.0, stock_value_diff],
                    ["Stock Adjustment - TCP1", stock_value_diff, 0.0]]))
        mi.cancel()
Exemple #4
0
    def test_warehouse_merging(self):
        company = "_Test Company with perpetual inventory"
        create_warehouse(
            "Test Warehouse for Merging 1",
            company=company,
            properties={"parent_warehouse": "All Warehouses - TCP1"})
        create_warehouse(
            "Test Warehouse for Merging 2",
            company=company,
            properties={"parent_warehouse": "All Warehouses - TCP1"})

        make_stock_entry(item_code="_Test Item",
                         target="Test Warehouse for Merging 1 - TCP1",
                         qty=1,
                         rate=100,
                         company=company)
        make_stock_entry(item_code="_Test Item",
                         target="Test Warehouse for Merging 2 - TCP1",
                         qty=1,
                         rate=100,
                         company=company)

        existing_bin_qty = (cint(
            frappe.db.get_value(
                "Bin", {
                    "item_code": "_Test Item",
                    "warehouse": "Test Warehouse for Merging 1 - TCP1"
                }, "actual_qty")) + cint(
                    frappe.db.get_value(
                        "Bin", {
                            "item_code": "_Test Item",
                            "warehouse": "Test Warehouse for Merging 2 - TCP1"
                        }, "actual_qty")))

        frappe.rename_doc("Warehouse",
                          "Test Warehouse for Merging 1 - TCP1",
                          "Test Warehouse for Merging 2 - TCP1",
                          merge=True)

        self.assertFalse(
            frappe.db.exists("Warehouse",
                             "Test Warehouse for Merging 1 - TCP1"))

        bin_qty = frappe.db.get_value(
            "Bin", {
                "item_code": "_Test Item",
                "warehouse": "Test Warehouse for Merging 2 - TCP1"
            }, "actual_qty")

        self.assertEqual(bin_qty, existing_bin_qty)

        self.assertTrue(
            frappe.db.get_value(
                "Warehouse",
                filters={"account": "Test Warehouse for Merging 2 - TCP1"}))
Exemple #5
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)
Exemple #6
0
    def test_same_serial_nos_in_repack_or_manufacture_entries(self):
        s1 = make_serialized_item(target_warehouse="_Test Warehouse - _TC")
        serial_nos = s1.get("items")[0].serial_no

        s2 = make_stock_entry(item_code="_Test Serialized Item With Series",
                              source="_Test Warehouse - _TC",
                              qty=2,
                              basic_rate=100,
                              purpose="Repack",
                              serial_no=serial_nos,
                              do_not_save=True)

        s2.append(
            "items", {
                "item_code": "_Test Serialized Item",
                "t_warehouse": "_Test Warehouse - _TC",
                "qty": 2,
                "basic_rate": 120,
                "expense_account": "Stock Adjustment - _TC",
                "conversion_factor": 1.0,
                "cost_center": "_Test Cost Center - _TC",
                "serial_no": serial_nos
            })

        s2.submit()
        s2.cancel()
Exemple #7
0
    def test_variant_work_order(self):
        bom_no = frappe.db.get_value("BOM", {
            "item": "_Test Variant Item",
            "is_default": 1,
            "docstatus": 1
        })

        work_order = frappe.new_doc("Work Order")
        work_order.update({
            "company": "_Test Company",
            "fg_warehouse": "_Test Warehouse 1 - _TC",
            "production_item": "_Test Variant Item-S",
            "bom_no": bom_no,
            "qty": 1.0,
            "stock_uom": "_Test UOM",
            "wip_warehouse": "_Test Warehouse - _TC",
            "skip_transfer": 1
        })
        work_order.insert()
        work_order.submit()

        from erpbee.manufacturing.doctype.work_order.work_order import make_stock_entry

        stock_entry = frappe.get_doc(
            make_stock_entry(work_order.name, "Manufacture", 1))
        stock_entry.insert()
        self.assertTrue(
            "_Test Variant Item-S" in [d.item_code for d in stock_entry.items])
Exemple #8
0
    def test_material_receipt_gl_entry(self):
        company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')

        mr = make_stock_entry(item_code="_Test Item",
                              target="Stores - TCP1",
                              company=company,
                              qty=50,
                              basic_rate=100,
                              expense_account="Stock Adjustment - TCP1")

        stock_in_hand_account = get_inventory_account(
            mr.company,
            mr.get("items")[0].t_warehouse)
        self.check_stock_ledger_entries(
            "Stock Entry", mr.name, [["_Test Item", "Stores - TCP1", 50.0]])

        self.check_gl_entries(
            "Stock Entry", mr.name,
            sorted([[stock_in_hand_account, 5000.0, 0.0],
                    ["Stock Adjustment - TCP1", 0.0, 5000.0]]))

        mr.cancel()

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

        self.assertTrue(
            frappe.db.sql(
                """select * from `tabGL Entry`
			where voucher_type='Stock Entry' and voucher_no=%s""", mr.name))
Exemple #9
0
    def test_work_order(self):
        from erpbee.manufacturing.doctype.work_order.work_order \
         import make_stock_entry as _make_stock_entry
        bom_no, bom_operation_cost = frappe.db.get_value(
            "BOM", {
                "item": "_Test FG Item 2",
                "is_default": 1,
                "docstatus": 1
            }, ["name", "operating_cost"])

        work_order = frappe.new_doc("Work Order")
        work_order.update({
            "company": "_Test Company",
            "fg_warehouse": "_Test Warehouse 1 - _TC",
            "production_item": "_Test FG Item 2",
            "bom_no": bom_no,
            "qty": 1.0,
            "stock_uom": "_Test UOM",
            "wip_warehouse": "_Test Warehouse - _TC",
            "additional_operating_cost": 1000
        })
        work_order.insert()
        work_order.submit()

        make_stock_entry(item_code="_Test Item",
                         target="_Test Warehouse - _TC",
                         qty=50,
                         basic_rate=100)
        make_stock_entry(item_code="_Test Item 2",
                         target="_Test Warehouse - _TC",
                         qty=50,
                         basic_rate=20)

        stock_entry = _make_stock_entry(work_order.name, "Manufacture", 1)

        rm_cost = 0
        for d in stock_entry.get("items"):
            if d.item_code != "_Test FG Item 2":
                rm_cost += flt(d.amount)
        fg_cost = list(
            filter(lambda x: x.item_code == "_Test FG Item 2",
                   stock_entry.get("items")))[0].amount
        self.assertEqual(
            fg_cost,
            flt(
                rm_cost + bom_operation_cost +
                work_order.additional_operating_cost, 2))
Exemple #10
0
 def test_customer_provided_parts_se(self):
     create_item('CUST-0987',
                 is_customer_provided_item=1,
                 customer='_Test Customer',
                 is_purchase_item=0)
     se = make_stock_entry(item_code='CUST-0987',
                           purpose='Material Receipt',
                           qty=4,
                           to_warehouse="_Test Warehouse - _TC")
     self.assertEqual(se.get("items")[0].allow_zero_valuation_rate, 1)
     self.assertEqual(se.get("items")[0].amount, 0)
Exemple #11
0
    def test_back_dated_entry_not_allowed(self):
        # Back dated stock transactions are only allowed to stock managers
        frappe.db.set_value(
            "Stock Settings", None,
            "role_allowed_to_create_edit_back_dated_transactions",
            "Stock Manager")

        # Set User with Stock User role but not Stock Manager
        frappe.set_user("*****@*****.**")
        user = frappe.get_doc("User", "*****@*****.**")
        user.add_roles("Stock User")
        user.remove_roles("Stock Manager")

        stock_entry_on_today = make_stock_entry(target="_Test Warehouse - _TC",
                                                qty=10,
                                                basic_rate=100)
        back_dated_se_1 = make_stock_entry(target="_Test Warehouse - _TC",
                                           qty=10,
                                           basic_rate=100,
                                           posting_date=add_days(today(), -1),
                                           do_not_submit=True)

        # Block back-dated entry
        self.assertRaises(BackDatedStockTransaction, back_dated_se_1.submit)

        user.add_roles("Stock Manager")

        # Back dated entry allowed to Stock Manager
        back_dated_se_2 = make_stock_entry(target="_Test Warehouse - _TC",
                                           qty=10,
                                           basic_rate=100,
                                           posting_date=add_days(today(), -1))

        back_dated_se_2.cancel()
        stock_entry_on_today.cancel()

        frappe.db.set_value(
            "Stock Settings", None,
            "role_allowed_to_create_edit_back_dated_transactions", None)
        frappe.set_user("Administrator")
Exemple #12
0
    def test_material_transfer_gl_entry(self):
        company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')

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

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

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

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

        if source_warehouse_account == target_warehouse_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,
                              as_dict=1))

        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([
                    [source_warehouse_account, 0.0, stock_value_diff],
                    [target_warehouse_account, stock_value_diff, 0.0],
                ]))

        mtn.cancel()
Exemple #13
0
    def test_gle_for_opening_stock_entry(self):
        mr = make_stock_entry(item_code="_Test Item",
                              target="Stores - TCP1",
                              company="_Test Company with perpetual inventory",
                              qty=50,
                              basic_rate=100,
                              expense_account="Stock Adjustment - TCP1",
                              is_opening="Yes",
                              do_not_save=True)

        self.assertRaises(OpeningEntryAccountError, mr.save)

        mr.items[0].expense_account = "Temporary Opening - TCP1"

        mr.save()
        mr.submit()

        is_opening = frappe.db.get_value("GL Entry",
                                         filters={
                                             "voucher_type": "Stock Entry",
                                             "voucher_no": mr.name
                                         },
                                         fieldname="is_opening")
        self.assertEqual(is_opening, "Yes")
Exemple #14
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",
                                    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",
                                    posting_date='2020-04-20',
                                    posting_time='14:00')

        # _Test Item for Reposting transferred from Stores to FG warehouse on 30-04-2020
        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",
                         posting_date='2020-04-30',
                         posting_time='14:00')
        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("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 = get_previous_sle({
            "item_code": "_Test Finished Item for Reposting",
            "warehouse": "Finished Goods - _TC",
            "posting_date": '2020-05-05',
            "posting_time": '14:00'
        })
        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
        create_stock_reconciliation(item_code="_Test Item for Reposting",
                                    warehouse="Stores - _TC",
                                    qty=50,
                                    rate=150,
                                    company=company,
                                    expense_account="Stock Adjustment - _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 = get_previous_sle({
            "item_code": "_Test Finished Item for Reposting",
            "warehouse": "Finished Goods - _TC",
            "posting_date": '2020-05-05',
            "posting_time": '14:00'
        })
        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)
Exemple #15
0
    def test_repack_with_additional_costs(self):
        company = frappe.db.get_value('Warehouse', 'Stores - TCP1', 'company')

        make_stock_entry(item_code="_Test Item",
                         target="Stores - TCP1",
                         company=company,
                         qty=50,
                         basic_rate=100,
                         expense_account="Stock Adjustment - TCP1")

        repack = make_stock_entry(company=company,
                                  purpose="Repack",
                                  do_not_save=True)
        repack.posting_date = nowdate()
        repack.posting_time = nowtime()

        expenses_included_in_valuation = frappe.get_value(
            "Company", company, "expenses_included_in_valuation")

        items = get_multiple_items()
        repack.items = []
        for item in items:
            repack.append("items", item)

        repack.set("additional_costs", [
            {
                "expense_account": expenses_included_in_valuation,
                "description": "Actual Operating Cost",
                "amount": 1000
            },
            {
                "expense_account": expenses_included_in_valuation,
                "description": "Additional Operating Cost",
                "amount": 200
            },
        ])

        repack.set_stock_entry_type()
        repack.insert()
        repack.submit()

        stock_in_hand_account = get_inventory_account(
            repack.company,
            repack.get("items")[1].t_warehouse)
        rm_stock_value_diff = abs(
            frappe.db.get_value(
                "Stock Ledger Entry", {
                    "voucher_type": "Stock Entry",
                    "voucher_no": repack.name,
                    "item_code": "_Test Item"
                }, "stock_value_difference"))

        fg_stock_value_diff = abs(
            frappe.db.get_value(
                "Stock Ledger Entry", {
                    "voucher_type": "Stock Entry",
                    "voucher_no": repack.name,
                    "item_code": "_Test Item Home Desktop 100"
                }, "stock_value_difference"))

        stock_value_diff = flt(fg_stock_value_diff - rm_stock_value_diff, 2)

        self.assertEqual(stock_value_diff, 1200)

        self.check_gl_entries(
            "Stock Entry", repack.name,
            sorted([[stock_in_hand_account, 1200, 0.0],
                    ["Expenses Included In Valuation - TCP1", 0.0, 1200.0]]))