From 4ceb1b51645b2991339a3b56a0dbab079d5068c0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 13 Mar 2013 11:40:30 +0530 Subject: [PATCH] aii: gl entries for stock entry and testcases --- stock/doctype/stock_entry/stock_entry.py | 48 +++++++- stock/doctype/stock_entry/test_stock_entry.py | 106 +++++++++++++----- 2 files changed, 124 insertions(+), 30 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 74b71d97b3..cd20266d6b 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -39,7 +39,6 @@ class DocType(AccountsController): def validate(self): self.validate_purpose() - self.validate_serial_nos() pro_obj = self.doc.production_order and \ get_obj('Production Order', self.doc.production_order) or None @@ -51,22 +50,20 @@ class DocType(AccountsController): self.validate_incoming_rate() self.validate_bom() self.validate_finished_goods() - self.validate_return_reference_doc() - self.validate_with_material_request() def on_submit(self): self.update_serial_no(1) self.update_stock_ledger(0) - # update Production Order self.update_production_order(1) + self.make_gl_entries() def on_cancel(self): self.update_serial_no(0) self.update_stock_ledger(1) - # update Production Order self.update_production_order(0) + self.make_gl_entries() def validate_purpose(self): valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", @@ -167,6 +164,47 @@ class DocType(AccountsController): elif self.doc.purpose != "Material Transfer": self.doc.production_order = None + def make_gl_entries(self): + if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")): + return + + abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr") + stock_in_hand_account = self.get_stock_in_hand_account() + total_valuation_amount = self.get_total_valuation_amount() + + if total_valuation_amount: + gl_entries = [ + # debit stock in hand account + self.get_gl_dict({ + "account": stock_in_hand_account, + "against": "Stock Adjustment - %s" % abbr, + "debit": total_valuation_amount, + "remarks": self.doc.remarks or "Accounting Entry for Stock", + }, self.doc.docstatus == 2), + + # debit stock received but not billed account + self.get_gl_dict({ + "account": "Stock Adjustment - %s" % abbr, + "against": stock_in_hand_account, + "credit": total_valuation_amount, + "cost_center": "Auto Inventory Accounting - %s" % abbr, + "remarks": self.doc.remarks or "Accounting Entry for Stock", + }, self.doc.docstatus == 2), + ] + from accounts.general_ledger import make_gl_entries + make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2) + + def get_total_valuation_amount(self): + total_valuation_amount = 0 + for item in self.doclist.get({"parentfield": "mtn_details"}): + if item.t_warehouse and not item.s_warehouse: + total_valuation_amount += flt(item.incoming_rate) * flt(item.transfer_qty) + + if item.s_warehouse and not item.t_warehouse: + total_valuation_amount -= flt(item.incoming_rate) * flt(item.transfer_qty) + + return total_valuation_amount + def get_stock_and_rate(self): """get stock and incoming rate on posting date""" for d in getlist(self.doclist, 'mtn_details'): diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 21d15f7e23..a4103c37bb 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -43,6 +43,20 @@ class TestStockEntry(unittest.TestCase): ]) ) + mr.cancel() + self.check_stock_ledger_entries("Stock Entry", mr.doc.name, + sorted([["_Test Item", "_Test Warehouse", 50.0], + ["_Test Item", "_Test Warehouse", -50.0]])) + + self.check_gl_entries("Stock Entry", mr.doc.name, + sorted([ + [stock_in_hand_account, 5000.0, 0.0], + ["Stock Adjustment - _TC", 0.0, 5000.0], + [stock_in_hand_account, 0.0, 5000.0], + ["Stock Adjustment - _TC", 5000.0, 0.0] + ]) + ) + webnotes.defaults.set_global_default("auto_inventory_accounting", 0) def test_material_issue_gl_entry(self): @@ -53,25 +67,78 @@ class TestStockEntry(unittest.TestCase): mr.insert() mr.submit() + mi = webnotes.bean(copy=test_records[1]) + mi.insert() + mi.submit() + stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company", "stock_in_hand_account") - self.check_stock_ledger_entries("Stock Entry", mr.doc.name, - [["_Test Item", "_Test Warehouse", 50.0]]) + self.check_stock_ledger_entries("Stock Entry", mi.doc.name, + [["_Test Item", "_Test Warehouse", -40.0]]) - self.check_gl_entries("Stock Entry", mr.doc.name, + self.check_gl_entries("Stock Entry", mi.doc.name, sorted([ - [stock_in_hand_account, 5000.0, 0.0], - ["Stock Adjustment - _TC", 0.0, 5000.0] + [stock_in_hand_account, 0.0, 4000.0], + ["Stock Adjustment - _TC", 4000.0, 0.0] ]) ) + mi.cancel() + + self.check_stock_ledger_entries("Stock Entry", mi.doc.name, + sorted([["_Test Item", "_Test Warehouse", -40.0], + ["_Test Item", "_Test Warehouse", 40.0]])) + + self.check_gl_entries("Stock Entry", mi.doc.name, + sorted([ + [stock_in_hand_account, 0.0, 4000.0], + ["Stock Adjustment - _TC", 4000.0, 0.0], + [stock_in_hand_account, 4000.0, 0.0], + ["Stock Adjustment - _TC", 0.0, 4000.0], + ]) + ) + + webnotes.defaults.set_global_default("auto_inventory_accounting", 0) + + def test_material_transfer_gl_entry(self): + webnotes.conn.sql("delete from `tabStock Ledger Entry`") + webnotes.defaults.set_global_default("auto_inventory_accounting", 1) + + mr = webnotes.bean(copy=test_records[0]) + mr.insert() + mr.submit() + + mtn = webnotes.bean(copy=test_records[2]) + mtn.insert() + mtn.submit() + + self.check_stock_ledger_entries("Stock Entry", mtn.doc.name, + [["_Test Item", "_Test Warehouse", -45.0], ["_Test Item", "_Test Warehouse 1", 45.0]]) + + # no gl entry + gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` + where voucher_type = 'Stock Entry' and voucher_no=%s""", mtn.doc.name) + self.assertFalse(gl_entries) + + mtn.cancel() + self.check_stock_ledger_entries("Stock Entry", mtn.doc.name, + sorted([["_Test Item", "_Test Warehouse", 45.0], + ["_Test Item", "_Test Warehouse 1", -45.0], + ["_Test Item", "_Test Warehouse", -45.0], + ["_Test Item", "_Test Warehouse 1", 45.0]])) + + # no gl entry + gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` + where voucher_type = 'Stock Entry' and voucher_no=%s""", mtn.doc.name) + self.assertFalse(gl_entries) + webnotes.defaults.set_global_default("auto_inventory_accounting", 0) def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle): # check stock ledger entries - sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` - where voucher_type = %s and voucher_no = %s order by item_code, warehouse""", + sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` where voucher_type = %s + and voucher_no = %s order by item_code, warehouse, actual_qty""", (voucher_type, voucher_no), as_dict=1) self.assertTrue(sle) @@ -87,7 +154,6 @@ class TestStockEntry(unittest.TestCase): from `tabGL Entry` where voucher_type=%s and voucher_no=%s order by account asc, debit asc""", (voucher_type, voucher_no), as_dict=1) self.assertTrue(gl_entries) - for i, gle in enumerate(gl_entries): self.assertEquals(expected_gl_entries[i][0], gle.account) self.assertEquals(expected_gl_entries[i][1], gle.debit) @@ -100,7 +166,8 @@ test_records = [ "doctype": "Stock Entry", "posting_date": "2013-01-25", "posting_time": "17:14:24", - "purpose": "Material Receipt" + "purpose": "Material Receipt", + "fiscal_year": "_Test Fiscal Year 2013", }, { "conversion_factor": 1.0, @@ -121,7 +188,8 @@ test_records = [ "doctype": "Stock Entry", "posting_date": "2013-01-25", "posting_time": "17:15", - "purpose": "Material Issue" + "purpose": "Material Issue", + "fiscal_year": "_Test Fiscal Year 2013", }, { "conversion_factor": 1.0, @@ -142,12 +210,13 @@ test_records = [ "doctype": "Stock Entry", "posting_date": "2013-01-25", "posting_time": "17:14:24", - "purpose": "Material Transfer" + "purpose": "Material Transfer", + "fiscal_year": "_Test Fiscal Year 2013", }, { "conversion_factor": 1.0, "doctype": "Stock Entry Detail", - "item_code": "_Test Item Home Desktop 100", + "item_code": "_Test Item", "parentfield": "mtn_details", "incoming_rate": 100, "qty": 45.0, @@ -156,19 +225,6 @@ test_records = [ "uom": "_Test UOM", "s_warehouse": "_Test Warehouse", "t_warehouse": "_Test Warehouse 1", - }, - { - "conversion_factor": 1.0, - "doctype": "Stock Entry Detail", - "item_code": "_Test Item Home Desktop 100", - "parentfield": "mtn_details", - "qty": 45.0, - "incoming_rate": 100, - "stock_uom": "_Test UOM", - "transfer_qty": 45.0, - "uom": "_Test UOM", - "s_warehouse": "_Test Warehouse", - "t_warehouse": "_Test Warehouse 1", } ] ] \ No newline at end of file