[fix] [minor] perpetual inventory: account for each warehouse

This commit is contained in:
Nabin Hait
2013-09-17 10:21:20 +05:30
parent 87eb4b99a8
commit 7a75e10a61
18 changed files with 241 additions and 171 deletions

View File

@@ -7,7 +7,7 @@ import unittest
import webnotes
import webnotes.defaults
from webnotes.utils import cint
from stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries, test_records as pr_test_records
from stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries, set_perpetual_inventory, test_records as pr_test_records
class TestDeliveryNote(unittest.TestCase):
def _insert_purchase_receipt(self, item_code=None):
@@ -41,7 +41,7 @@ class TestDeliveryNote(unittest.TestCase):
def test_delivery_note_no_gl_entry(self):
self.clear_stock_account_balance()
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
set_perpetual_inventory(0)
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")), 0)
self._insert_purchase_receipt()
@@ -65,8 +65,7 @@ class TestDeliveryNote(unittest.TestCase):
def test_delivery_note_gl_entry(self):
self.clear_stock_account_balance()
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
set_perpetual_inventory()
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")), 1)
webnotes.conn.set_value("Item", "_Test Item", "valuation_method", "FIFO")
@@ -76,8 +75,8 @@ class TestDeliveryNote(unittest.TestCase):
dn.doclist[1].expense_account = "Cost of Goods Sold - _TC"
dn.doclist[1].cost_center = "Main - _TC"
stock_in_hand_account = webnotes.conn.get_value("Warehouse", dn.doclist[1].warehouse,
"account")
stock_in_hand_account = webnotes.conn.get_value("Account",
{"master_name": dn.doclist[1].warehouse})
from accounts.utils import get_balance_on
prev_bal = get_balance_on(stock_in_hand_account, dn.doc.posting_date)
@@ -118,12 +117,11 @@ class TestDeliveryNote(unittest.TestCase):
dn.cancel()
self.assertFalse(get_gl_entries("Delivery Note", dn.doc.name))
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
set_perpetual_inventory(0)
def test_delivery_note_gl_entry_packing_item(self):
self.clear_stock_account_balance()
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
set_perpetual_inventory()
self._insert_purchase_receipt()
self._insert_purchase_receipt("_Test Item Home Desktop 100")
@@ -132,8 +130,8 @@ class TestDeliveryNote(unittest.TestCase):
dn.doclist[1].item_code = "_Test Sales BOM Item"
dn.doclist[1].qty = 1
stock_in_hand_account = webnotes.conn.get_value("Warehouse", dn.doclist[1].warehouse,
"account")
stock_in_hand_account = webnotes.conn.get_value("Account",
{"master_name": dn.doclist[1].warehouse})
from accounts.utils import get_balance_on
prev_bal = get_balance_on(stock_in_hand_account, dn.doc.posting_date)
@@ -158,7 +156,7 @@ class TestDeliveryNote(unittest.TestCase):
dn.cancel()
self.assertFalse(get_gl_entries("Delivery Note", dn.doc.name))
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
set_perpetual_inventory(0)
def test_serialized(self):
from stock.doctype.stock_entry.test_stock_entry import make_serialized_item

View File

@@ -12,8 +12,8 @@ from accounts.utils import get_stock_and_account_difference
class TestPurchaseReceipt(unittest.TestCase):
def test_make_purchase_invoice(self):
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
self._clear_stock_account_balance()
set_perpetual_inventory(0)
from stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
pr = webnotes.bean(copy=test_records[0]).insert()
@@ -33,8 +33,8 @@ class TestPurchaseReceipt(unittest.TestCase):
self.assertRaises(webnotes.ValidationError, webnotes.bean(pi).submit)
def test_purchase_receipt_no_gl_entry(self):
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
self._clear_stock_account_balance()
set_perpetual_inventory(0)
pr = webnotes.bean(copy=test_records[0])
pr.insert()
pr.submit()
@@ -53,11 +53,11 @@ class TestPurchaseReceipt(unittest.TestCase):
self.assertFalse(get_gl_entries("Purchase Receipt", pr.doc.name))
def test_purchase_receipt_gl_entry(self):
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")), 1)
self._clear_stock_account_balance()
set_perpetual_inventory()
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")), 1)
pr = webnotes.bean(copy=test_records[0])
pr.insert()
pr.submit()
@@ -66,10 +66,10 @@ class TestPurchaseReceipt(unittest.TestCase):
self.assertTrue(gl_entries)
stock_in_hand_account = webnotes.conn.get_value("Warehouse", pr.doclist[1].warehouse,
"account")
fixed_asset_account = webnotes.conn.get_value("Warehouse", pr.doclist[2].warehouse,
"account")
stock_in_hand_account = webnotes.conn.get_value("Account",
{"master_name": pr.doclist[1].warehouse})
fixed_asset_account = webnotes.conn.get_value("Account",
{"master_name": pr.doclist[2].warehouse})
expected_values = {
stock_in_hand_account: [375.0, 0.0],
@@ -84,7 +84,7 @@ class TestPurchaseReceipt(unittest.TestCase):
pr.cancel()
self.assertFalse(get_gl_entries("Purchase Receipt", pr.doc.name))
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
set_perpetual_inventory(0)
def _clear_stock_account_balance(self):
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
@@ -123,6 +123,10 @@ def get_gl_entries(voucher_type, voucher_no):
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
order by account desc""", (voucher_type, voucher_no), as_dict=1)
def set_perpetual_inventory(enable=1):
accounts_settings = webnotes.bean("Accounts Settings")
accounts_settings.doc.auto_accounting_for_stock = enable
accounts_settings.save()
test_dependencies = ["BOM"]

View File

@@ -6,18 +6,18 @@ test_records = [
"doctype": "Warehouse",
"warehouse_name": "_Test Warehouse",
"company": "_Test Company",
"account": "_Test Account Stock In Hand - _TC"
"create_account_under": "Stock Assets - _TC"
}],
[{
"doctype": "Warehouse",
"warehouse_name": "_Test Warehouse 1",
"company": "_Test Company",
"account": "_Test Account Fixed Assets - _TC"
"create_account_under": "Fixed Assets - _TC"
}],
[{
"doctype": "Warehouse",
"warehouse_name": "_Test Warehouse 2",
"account": "_Test Account Stock In Hand - _TC1",
"create_account_under": "Stock Assets - _TC",
"company": "_Test Company 1"
}, {
"doctype": "Warehouse User",

View File

@@ -17,12 +17,12 @@ cur_frm.cscript.merge = function(doc, cdt, cdn) {
}
}
cur_frm.set_query("account", function() {
cur_frm.set_query("create_account_under", function() {
return {
filters: {
"company": cur_frm.doc.company,
"debit_or_credit": "Debit",
'group_or_ledger': "Ledger"
'group_or_ledger': "Group"
}
}
})

View File

@@ -6,7 +6,7 @@ import webnotes
from webnotes.utils import cint, flt, validate_email_add
from webnotes.model.code import get_obj
from webnotes import msgprint
from webnotes import msgprint, _
sql = webnotes.conn.sql
@@ -23,21 +23,47 @@ class DocType:
def validate(self):
if self.doc.email_id and not validate_email_add(self.doc.email_id):
msgprint("Please enter valid Email Id", raise_exception=1)
self.account_mandatory()
def account_mandatory(self):
if cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
sle_exists = webnotes.conn.get_value("Stock Ledger Entry", {"warehouse": self.doc.name})
if not self.doc.account and (self.doc.__islocal or not sle_exists):
webnotes.throw(_("Asset/Expense Account mandatory"))
self.validate_parent_account()
if not self.doc.__islocal and sle_exists:
old_account = webnotes.conn.get_value("Warehouse", self.doc.name, "account")
if old_account != self.doc.account:
webnotes.throw(_("Account can not be changed/assigned/removed as \
stock transactions exist for this warehouse"))
def on_update(self):
self.create_account_head()
def create_account_head(self):
if cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
if not webnotes.conn.get_value("Account", {"account_type": "Warehouse",
"master_name": self.doc.name}):
if self.doc.__islocal or not webnotes.conn.get_value("Stock Ledger Entry",
{"warehouse": self.doc.name}):
ac_bean = webnotes.bean({
"doctype": "Account",
'account_name': self.doc.warehouse_name,
'parent_account': self.doc.create_account_under,
'group_or_ledger':'Ledger',
'company':self.doc.company,
"account_type": "Warehouse",
"master_name": self.doc.name,
"freeze_account": "No"
})
ac_bean.ignore_permissions = True
ac_bean.insert()
msgprint(_("Account Head") + ": " + ac_bean.doc.name + _(" created"))
def validate_parent_account(self):
if cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")) and \
not self.doc.create_account_under:
parent_account = webnotes.conn.get_value("Account",
{"account_name": "Stock Assets", "company": self.doc.company})
if parent_account:
self.doc.create_account_under = parent_account
else:
webnotes.throw(_("Please enter account group under which account \
for warehouse ") + self.doc.name +_(" will be created"))
def on_rename(self, new, old):
webnotes.conn.set_value("Account", {"account_type": "Warehouse", "master_name": old},
"master_name", new)
def merge_warehouses(self):
webnotes.conn.auto_commit_on_many_writes = 1
@@ -52,6 +78,15 @@ class DocType:
link_fields = rename_doc.get_link_fields('Warehouse')
rename_doc.update_link_field_values(link_fields, self.doc.name, self.doc.merge_with)
account_link_fields = rename_doc.get_link_fields('Account')
old_warehouse_account = webnotes.conn.get_value("Account", {"master_name": self.doc.name})
new_warehouse_account = webnotes.conn.get_value("Account",
{"master_name": self.doc.merge_with})
rename_doc.update_link_field_values(account_link_fields, old_warehouse_account,
new_warehouse_account)
webnotes.conn.delete_doc("Account", old_warehouse_account)
for item_code in items:
self.repost(item_code[0], self.doc.merge_with)
@@ -160,6 +195,11 @@ class DocType:
else:
sql("delete from `tabBin` where name = %s", d['name'])
warehouse_account = webnotes.conn.get_value("Account",
{"account_type": "Warehosue", "master_name": self.doc.name})
if warehouse_account:
webnotes.delete_doc("Account", warehouse_account)
# delete cancelled sle
if sql("""select name from `tabStock Ledger Entry` where warehouse = %s""", self.doc.name):
msgprint("""Warehosue can not be deleted as stock ledger entry

View File

@@ -2,7 +2,7 @@
{
"creation": "2013-03-07 18:50:32",
"docstatus": 0,
"modified": "2013-08-01 15:27:49",
"modified": "2013-09-16 10:45:49",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -28,9 +28,9 @@
"parent": "Warehouse",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"read": 1,
"report": 1,
"submit": 0
"report": 1
},
{
"doctype": "DocType",
@@ -71,11 +71,12 @@
"search_index": 1
},
{
"description": "This account will be used for perpetual accounting for inventory e.g. Stock-in-Hand, Fixed Asset Account etc",
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
"description": "Account for the warehouse (Perpetual Inventory) will be created under this Account.",
"doctype": "DocField",
"fieldname": "account",
"fieldname": "create_account_under",
"fieldtype": "Link",
"label": "Account",
"label": "Create Account Under",
"options": "Account",
"permlevel": 0
},
@@ -231,16 +232,8 @@
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"permlevel": 0,
"role": "Material Master Manager",
"write": 1
},
{
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"permlevel": 0,
"role": "System Manager",
"submit": 0,
"write": 1
},
{
@@ -248,26 +241,20 @@
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 0,
"role": "Material Manager",
"write": 0
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 0,
"role": "Material User",
"submit": 0,
"write": 0
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 2,
"role": "System Manager",
"write": 1
"role": "Sales User"
},
{
"doctype": "DocPerm",
"role": "Purchase User"
},
{
"doctype": "DocPerm",
"role": "Accounts User"
}
]