Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 74b71d9..cd20266 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -39,7 +39,6 @@
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 @@
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 @@
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 21d15f7..a4103c3 100644
--- a/stock/doctype/stock_entry/test_stock_entry.py
+++ b/stock/doctype/stock_entry/test_stock_entry.py
@@ -43,6 +43,20 @@
])
)
+ 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 @@
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 @@
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 @@
"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 @@
"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 @@
"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 @@
"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