[fix] [minor] perpetual inventory: account for each warehouse
This commit is contained in:
parent
5cd1d54347
commit
142007a226
@ -34,16 +34,17 @@ class TestJournalVoucher(unittest.TestCase):
|
|||||||
where against_jv=%s""", jv_invoice.doc.name))
|
where against_jv=%s""", jv_invoice.doc.name))
|
||||||
|
|
||||||
def test_jv_against_stock_account(self):
|
def test_jv_against_stock_account(self):
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||||
|
set_perpetual_inventory()
|
||||||
|
|
||||||
jv = webnotes.bean(copy=test_records[0])
|
jv = webnotes.bean(copy=test_records[0])
|
||||||
jv.doclist[1].account = "_Test Account Stock in Hand - _TC"
|
jv.doclist[1].account = "_Test Warehouse - _TC"
|
||||||
jv.insert()
|
jv.insert()
|
||||||
|
|
||||||
from accounts.general_ledger import StockAccountInvalidTransaction
|
from accounts.general_ledger import StockAccountInvalidTransaction
|
||||||
self.assertRaises(StockAccountInvalidTransaction, jv.submit)
|
self.assertRaises(StockAccountInvalidTransaction, jv.submit)
|
||||||
|
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
def test_monthly_budget_crossed_ignore(self):
|
def test_monthly_budget_crossed_ignore(self):
|
||||||
webnotes.conn.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
webnotes.conn.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
||||||
|
@ -9,13 +9,14 @@ import webnotes.model
|
|||||||
import json
|
import json
|
||||||
from webnotes.utils import cint
|
from webnotes.utils import cint
|
||||||
import webnotes.defaults
|
import webnotes.defaults
|
||||||
|
from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||||
|
|
||||||
test_dependencies = ["Item", "Cost Center"]
|
test_dependencies = ["Item", "Cost Center"]
|
||||||
test_ignore = ["Serial No"]
|
test_ignore = ["Serial No"]
|
||||||
|
|
||||||
class TestPurchaseInvoice(unittest.TestCase):
|
class TestPurchaseInvoice(unittest.TestCase):
|
||||||
def test_gl_entries_without_auto_accounting_for_stock(self):
|
def test_gl_entries_without_auto_accounting_for_stock(self):
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
set_perpetual_inventory(0)
|
||||||
self.assertTrue(not cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")))
|
self.assertTrue(not cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")))
|
||||||
|
|
||||||
wrapper = webnotes.bean(copy=test_records[0])
|
wrapper = webnotes.bean(copy=test_records[0])
|
||||||
@ -42,7 +43,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
self.assertEqual([d.debit, d.credit], expected_gl_entries.get(d.account))
|
self.assertEqual([d.debit, d.credit], expected_gl_entries.get(d.account))
|
||||||
|
|
||||||
def test_gl_entries_with_auto_accounting_for_stock(self):
|
def test_gl_entries_with_auto_accounting_for_stock(self):
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
set_perpetual_inventory(1)
|
||||||
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||||
|
|
||||||
pi = webnotes.bean(copy=test_records[1])
|
pi = webnotes.bean(copy=test_records[1])
|
||||||
@ -68,10 +69,10 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
self.assertEquals(expected_values[i][1], gle.debit)
|
self.assertEquals(expected_values[i][1], gle.debit)
|
||||||
self.assertEquals(expected_values[i][2], gle.credit)
|
self.assertEquals(expected_values[i][2], gle.credit)
|
||||||
|
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
def test_gl_entries_with_aia_for_non_stock_items(self):
|
def test_gl_entries_with_aia_for_non_stock_items(self):
|
||||||
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)
|
self.assertEqual(cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")), 1)
|
||||||
|
|
||||||
pi = webnotes.bean(copy=test_records[1])
|
pi = webnotes.bean(copy=test_records[1])
|
||||||
@ -98,8 +99,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
|||||||
self.assertEquals(expected_values[i][0], gle.account)
|
self.assertEquals(expected_values[i][0], gle.account)
|
||||||
self.assertEquals(expected_values[i][1], gle.debit)
|
self.assertEquals(expected_values[i][1], gle.debit)
|
||||||
self.assertEquals(expected_values[i][2], gle.credit)
|
self.assertEquals(expected_values[i][2], gle.credit)
|
||||||
|
set_perpetual_inventory(0)
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
|
||||||
|
|
||||||
def test_purchase_invoice_calculation(self):
|
def test_purchase_invoice_calculation(self):
|
||||||
wrapper = webnotes.bean(copy=test_records[0])
|
wrapper = webnotes.bean(copy=test_records[0])
|
||||||
|
@ -91,8 +91,8 @@ def validate_total_debit_credit(total_debit, total_credit):
|
|||||||
|
|
||||||
def validate_account_for_auto_accounting_for_stock(gl_map):
|
def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||||
if gl_map[0].voucher_type=="Journal Voucher":
|
if gl_map[0].voucher_type=="Journal Voucher":
|
||||||
aii_accounts = [d[0] for d in webnotes.conn.sql("""select account from tabWarehouse
|
aii_accounts = [d[0] for d in webnotes.conn.sql("""select name from tabAccount
|
||||||
where ifnull(account, '')!=''""")]
|
where account_type = 'Warehouse' and ifnull(master_name, '')!=''""")]
|
||||||
|
|
||||||
for entry in gl_map:
|
for entry in gl_map:
|
||||||
if entry.account in aii_accounts:
|
if entry.account in aii_accounts:
|
||||||
|
@ -62,7 +62,7 @@ class AccountsController(TransactionBase):
|
|||||||
if self.meta.get_field(fieldname) and self.doc.fields.get(fieldname):
|
if self.meta.get_field(fieldname) and self.doc.fields.get(fieldname):
|
||||||
if not self.doc.price_list_currency:
|
if not self.doc.price_list_currency:
|
||||||
self.doc.price_list_currency = webnotes.conn.get_value("Price List",
|
self.doc.price_list_currency = webnotes.conn.get_value("Price List",
|
||||||
self.doc.fields.get(fieldame), "currency")
|
self.doc.fields.get(fieldname), "currency")
|
||||||
|
|
||||||
if self.doc.price_list_currency == company_currency:
|
if self.doc.price_list_currency == company_currency:
|
||||||
self.doc.plc_conversion_rate = 1.0
|
self.doc.plc_conversion_rate = 1.0
|
||||||
|
@ -15,17 +15,22 @@ class StockController(AccountsController):
|
|||||||
if not cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
|
if not cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
warehouse_account = self.get_warehouse_account()
|
||||||
|
|
||||||
if self.doc.docstatus==1:
|
if self.doc.docstatus==1:
|
||||||
gl_entries = self.get_gl_entries_for_stock()
|
gl_entries = self.get_gl_entries_for_stock(warehouse_account)
|
||||||
make_gl_entries(gl_entries)
|
make_gl_entries(gl_entries)
|
||||||
else:
|
else:
|
||||||
delete_gl_entries(voucher_type=self.doc.doctype, voucher_no=self.doc.name)
|
delete_gl_entries(voucher_type=self.doc.doctype, voucher_no=self.doc.name)
|
||||||
|
|
||||||
self.update_gl_entries_after()
|
self.update_gl_entries_after(warehouse_account)
|
||||||
|
|
||||||
def get_gl_entries_for_stock(self, default_expense_account=None, default_cost_center=None):
|
def get_gl_entries_for_stock(self, warehouse_account=None, default_expense_account=None,
|
||||||
|
default_cost_center=None):
|
||||||
from accounts.general_ledger import process_gl_map
|
from accounts.general_ledger import process_gl_map
|
||||||
warehouse_account = self.get_warehouse_account()
|
if not warehouse_account:
|
||||||
|
warehouse_account = self.get_warehouse_account()
|
||||||
|
|
||||||
stock_ledger = self.get_stock_ledger_details()
|
stock_ledger = self.get_stock_ledger_details()
|
||||||
voucher_details = self.get_voucher_details(stock_ledger, default_expense_account,
|
voucher_details = self.get_voucher_details(stock_ledger, default_expense_account,
|
||||||
default_cost_center)
|
default_cost_center)
|
||||||
@ -93,14 +98,17 @@ class StockController(AccountsController):
|
|||||||
where account_type = 'Warehouse' and ifnull(master_name, '') != ''"""))
|
where account_type = 'Warehouse' and ifnull(master_name, '') != ''"""))
|
||||||
return warehouse_account
|
return warehouse_account
|
||||||
|
|
||||||
def update_gl_entries_after(self):
|
def update_gl_entries_after(self, warehouse_account=None):
|
||||||
from accounts.utils import get_stock_and_account_difference
|
from accounts.utils import get_stock_and_account_difference
|
||||||
future_stock_vouchers = self.get_future_stock_vouchers()
|
future_stock_vouchers = self.get_future_stock_vouchers()
|
||||||
gle = self.get_voucherwise_gl_entries(future_stock_vouchers)
|
gle = self.get_voucherwise_gl_entries(future_stock_vouchers)
|
||||||
|
if not warehouse_account:
|
||||||
|
warehouse_account = self.get_warehouse_account()
|
||||||
|
|
||||||
for voucher_type, voucher_no in future_stock_vouchers:
|
for voucher_type, voucher_no in future_stock_vouchers:
|
||||||
existing_gle = gle.get((voucher_type, voucher_no), [])
|
existing_gle = gle.get((voucher_type, voucher_no), [])
|
||||||
voucher_obj = webnotes.get_obj(voucher_type, voucher_no)
|
voucher_obj = webnotes.get_obj(voucher_type, voucher_no)
|
||||||
expected_gle = voucher_obj.get_gl_entries_for_stock()
|
expected_gle = voucher_obj.get_gl_entries_for_stock(warehouse_account)
|
||||||
|
|
||||||
if expected_gle:
|
if expected_gle:
|
||||||
matched = True
|
matched = True
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
The value of available inventory is treated as an Asset in company's Chart of Accounts. Depending on the type of item, it can be treated as Fixed Asset or Current Asset. To prepare Balance Sheet, you should make the accounting entries for those assets.
|
The value of available inventory is treated as an Asset in company's Chart of Accounts. Depending on the type of items, it can be treated as Fixed Asset or Current Asset. To prepare Balance Sheet, you should make the accounting entries for those assets.
|
||||||
There are generally two different methods of accounting for inventory:
|
There are generally two different methods of accounting for inventory:
|
||||||
|
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ There are generally two different methods of accounting for inventory:
|
|||||||
|
|
||||||
In this process, for each stock transactions system posts relevant accounting entries to sync stock balance and accounting balance. This is the default settings in ERPNext for new accounts.
|
In this process, for each stock transactions system posts relevant accounting entries to sync stock balance and accounting balance. This is the default settings in ERPNext for new accounts.
|
||||||
|
|
||||||
When you buy and receive items, those items are booked as the company’s assets (stock-in-hand / fixed-assets). When you sell and deliver those items, an expense (cost-of-goods-sold) equal to the buying cost of the items is booked. General Ledger entries are made after every transaction. This improves accuracy of Balance Sheet and Profit and Loss statement. And the value as per Stock Ledger always remains same with the relevant account balance.
|
When you buy and receive items, those items are booked as the company’s assets (stock-in-hand / fixed-assets). When you sell and deliver those items, an expense (cost-of-goods-sold) equal to the buying cost of the items is booked. General Ledger entries are made after every stock transaction. This improves accuracy of Balance Sheet and Profit and Loss statement. And the value as per Stock Ledger always remains same with the relevant account balance.
|
||||||
|
|
||||||
To check accounting entries for a particular stock transaction, please check [**examples**](docs.user.stock.perpetual_inventory.html)
|
To check accounting entries for a particular stock transaction, please check [**examples**](docs.user.stock.perpetual_inventory.html)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
In perpetual accounting, system creates accounting entries for each stock transactions. Hence, stock balance are always remains same as relevant account balance.
|
In perpetual accounting, system creates accounting entries for each stock transactions. Hence, stock balance will always remains same as relevant account balance.
|
||||||
|
|
||||||
## **Activation**
|
## **Activation**
|
||||||
|
|
||||||
@ -14,22 +14,21 @@ In perpetual accounting, system creates accounting entries for each stock transa
|
|||||||
- Expenses Included In Valuation
|
- Expenses Included In Valuation
|
||||||
- Cost Center
|
- Cost Center
|
||||||
|
|
||||||
2. Go to Setup > Accounts Settings > check "Make Accounting Entry For Every Stock Entry"
|
2. The system will create an account head for each warehouse. Enter "Create Account Under" (account group under which account will be created) in warehouse master, based on type of items it stores (Stores, Fixed Asset Warehouse, etc).
|
||||||

|
|
||||||
|
|
||||||
3. Enter Asset / Expense account for each warehouse depending upon type of warehouse (Stores, Fixed Asset Warehouse etc)
|
3. Go to Setup > Accounts Settings > check "Make Accounting Entry For Every Stock Movement"
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
## **Migration from Periodic Inventory**
|
## **Migration from Periodic Inventory**
|
||||||
|
|
||||||
Migration from Periodic Inventory is not a one click settings, it involves some speacial steps. As Perpetual Inventory always maintain a sync between stock and account balance, it is not possible to enable it with existing Warehouse setup. You have to create a whole new set of Warehouses, each linked to relevant account.
|
Migration from Periodic Inventory is not a one click settings, it involves some special steps. As Perpetual Inventory always maintain a sync between stock and account balance, it is not possible to enable it with existing Warehouse setup. You have to create a whole new set of Warehouses, each linked to relevant account.
|
||||||
|
|
||||||
Steps to be followed:
|
Steps to be followed:
|
||||||
|
|
||||||
- Nullify current stock-in-hand / fixed-asset account balance through Journal Voucher.
|
- Nullify current stock-in-hand / fixed-asset account balance through Journal Voucher.
|
||||||
- Create new warehouse for each existing warehouse.
|
- Create new warehouse for each existing warehouse
|
||||||
- Assign Asset / Expense account while creating new warehouse.
|
- Follow Activation Step 1, 2 & 3
|
||||||
- Follow Activation Step 1 & 2
|
|
||||||
- Create Stock Entry (Material Transfer) to transfer available stock from existing warehouse to new warehouse
|
- Create Stock Entry (Material Transfer) to transfer available stock from existing warehouse to new warehouse
|
||||||
|
|
||||||
>Note: System will not post any accounting entries for existing stock transactions submitted prior to the activation of Perpetual Inventory as those old warehouses will not be linked to account.
|
>Note: System will not post any accounting entries for existing stock transactions submitted prior to the activation of Perpetual Inventory as those old warehouses will not be linked to account.
|
||||||
@ -47,11 +46,13 @@ Consider following Chart of Accounts and Warehouse setup for your company:
|
|||||||
> - Accounts Receivable
|
> - Accounts Receivable
|
||||||
> - Jane Doe
|
> - Jane Doe
|
||||||
> - Stock Assets
|
> - Stock Assets
|
||||||
> - Stock In Hand
|
> - Stores
|
||||||
|
> - Finished Goods
|
||||||
|
> - Work In Progress
|
||||||
> - Tax Assets
|
> - Tax Assets
|
||||||
> - VAT
|
> - VAT
|
||||||
> - Fixed Assets
|
> - Fixed Assets
|
||||||
> - Office Equipments
|
> - Fixed Asset Warehouse
|
||||||
>- Liabilities (Cr)
|
>- Liabilities (Cr)
|
||||||
> - Current Liabilities
|
> - Current Liabilities
|
||||||
> - Accounts Payable
|
> - Accounts Payable
|
||||||
@ -74,10 +75,10 @@ Consider following Chart of Accounts and Warehouse setup for your company:
|
|||||||
|
|
||||||
#### Warehouse - Account Configuration
|
#### Warehouse - Account Configuration
|
||||||
|
|
||||||
>- Stores - Stock In Hand
|
>- Stores
|
||||||
>- Work In Progress - Stock In Hand
|
>- Work In Progress
|
||||||
>- Finished Goods - Stock In Hand
|
>- Finished Goods
|
||||||
>- Fixed Asset Warehouse - Office Equipments
|
>- Fixed Asset Warehouse
|
||||||
|
|
||||||
### **Purchase Receipt**
|
### **Purchase Receipt**
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ Consider following Chart of Accounts and Warehouse setup for your company:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
As stock balance increases through Purchase Receipt, "Stock In Hand" account has been debited and a temporary account "Stock Receipt But Not Billed" account has been credited, to maintain double entry accounting system.
|
As stock balance increases through Purchase Receipt, "Store" and "Fixed Asset Warehouse" accounts have been debited and a temporary account "Stock Receipt But Not Billed" account has been credited, to maintain double entry accounting system.
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -180,7 +181,7 @@ Here "Stock Received But Not Billed" account has been debited and nullified the
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
As item has delivered from "Stores" warehouse, "Stock In Hand" account has been credited and equal amount will be debited to the expense account "Cost of Goods Sold". The debit/credit amount is equal to the total buying cost of the selling items. And buying cost is calculated based on valuation method (FIFO / Moving Average) or serial no cost for serialized items.
|
As item has delivered from "Stores" warehouse, "Stores" account has been credited and equal amount will be debited to the expense account "Cost of Goods Sold". The debit/credit amount is equal to the total buying cost of the selling items. And buying cost is calculated based on valuation method (FIFO / Moving Average) or serial no cost for serialized items.
|
||||||
|
|
||||||
In this eample, Buying cost of RM0001 = (2200/10)*5 = 1100
|
In this eample, Buying cost of RM0001 = (2200/10)*5 = 1100
|
||||||
|
|
||||||
@ -198,7 +199,7 @@ In this eample, Buying cost of RM0001 = (2200/10)*5 = 1100
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
Here apart from normal account entries for invoice, "Stock In Hand" and "Cost of Goods Sold" accounts are also affected based on buying cost.
|
Here apart from normal account entries for invoice, "Stores" and "Cost of Goods Sold" accounts are also affected based on buying cost.
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
|
@ -2,8 +2,5 @@ import webnotes
|
|||||||
from webnotes.utils import cint
|
from webnotes.utils import cint
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
import patches.september_2012.repost_stock
|
|
||||||
patches.september_2012.repost_stock.execute()
|
|
||||||
|
|
||||||
import patches.march_2013.p08_create_aii_accounts
|
import patches.march_2013.p08_create_aii_accounts
|
||||||
patches.march_2013.p08_create_aii_accounts.execute()
|
patches.march_2013.p08_create_aii_accounts.execute()
|
@ -44,7 +44,6 @@ def add_group_accounts():
|
|||||||
|
|
||||||
def add_ledger_accounts():
|
def add_ledger_accounts():
|
||||||
accounts_to_add = [
|
accounts_to_add = [
|
||||||
["Stock In Hand", "Stock Assets", "Ledger", ""],
|
|
||||||
["Cost of Goods Sold", "Stock Expenses", "Ledger", "Expense Account"],
|
["Cost of Goods Sold", "Stock Expenses", "Ledger", "Expense Account"],
|
||||||
["Stock Adjustment", "Stock Expenses", "Ledger", "Expense Account"],
|
["Stock Adjustment", "Stock Expenses", "Ledger", "Expense Account"],
|
||||||
["Expenses Included In Valuation", "Stock Expenses", "Ledger", "Expense Account"],
|
["Expenses Included In Valuation", "Stock Expenses", "Ledger", "Expense Account"],
|
||||||
|
@ -106,8 +106,9 @@ class DocType:
|
|||||||
})
|
})
|
||||||
global_defaults.save()
|
global_defaults.save()
|
||||||
|
|
||||||
webnotes.conn.set_value("Accounts Settings", None, "auto_accounting_for_stock", 1)
|
accounts_settings = webnotes.bean("Accounts Settings")
|
||||||
webnotes.conn.set_default("auto_accounting_for_stock", 1)
|
accounts_settings.doc.auto_accounting_for_stock = 1
|
||||||
|
accounts_settings.save()
|
||||||
|
|
||||||
stock_settings = webnotes.bean("Stock Settings")
|
stock_settings = webnotes.bean("Stock Settings")
|
||||||
stock_settings.doc.item_naming_by = "Item Code"
|
stock_settings.doc.item_naming_by = "Item Code"
|
||||||
|
@ -305,10 +305,11 @@ class DocType(BuyingController):
|
|||||||
def get_rate(self,arg):
|
def get_rate(self,arg):
|
||||||
return get_obj('Purchase Common').get_rate(arg,self)
|
return get_obj('Purchase Common').get_rate(arg,self)
|
||||||
|
|
||||||
def get_gl_entries_for_stock(self):
|
def get_gl_entries_for_stock(self, warehouse_account=None):
|
||||||
against_stock_account = self.get_company_default("stock_received_but_not_billed")
|
against_stock_account = self.get_company_default("stock_received_but_not_billed")
|
||||||
|
|
||||||
gl_entries = super(DocType, self).get_gl_entries_for_stock(against_stock_account, None)
|
gl_entries = super(DocType, self).get_gl_entries_for_stock(warehouse_account,
|
||||||
|
against_stock_account)
|
||||||
return gl_entries
|
return gl_entries
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,10 +8,12 @@ from __future__ import unicode_literals
|
|||||||
import webnotes, unittest
|
import webnotes, unittest
|
||||||
from webnotes.utils import flt
|
from webnotes.utils import flt
|
||||||
from stock.doctype.stock_ledger_entry.stock_ledger_entry import *
|
from stock.doctype.stock_ledger_entry.stock_ledger_entry import *
|
||||||
|
from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||||
|
|
||||||
|
|
||||||
class TestStockEntry(unittest.TestCase):
|
class TestStockEntry(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
set_perpetual_inventory(0)
|
||||||
if hasattr(self, "old_default_company"):
|
if hasattr(self, "old_default_company"):
|
||||||
webnotes.conn.set_default("company", self.old_default_company)
|
webnotes.conn.set_default("company", self.old_default_company)
|
||||||
|
|
||||||
@ -81,14 +83,14 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
|
|
||||||
def test_material_receipt_gl_entry(self):
|
def test_material_receipt_gl_entry(self):
|
||||||
self._clear_stock_account_balance()
|
self._clear_stock_account_balance()
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
set_perpetual_inventory()
|
||||||
|
|
||||||
mr = webnotes.bean(copy=test_records[0])
|
mr = webnotes.bean(copy=test_records[0])
|
||||||
mr.insert()
|
mr.insert()
|
||||||
mr.submit()
|
mr.submit()
|
||||||
|
|
||||||
stock_in_hand_account = webnotes.conn.get_value("Warehouse", mr.doclist[1].t_warehouse,
|
stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse",
|
||||||
"account")
|
"master_name": mr.doclist[1].t_warehouse})
|
||||||
|
|
||||||
self.check_stock_ledger_entries("Stock Entry", mr.doc.name,
|
self.check_stock_ledger_entries("Stock Entry", mr.doc.name,
|
||||||
[["_Test Item", "_Test Warehouse - _TC", 50.0]])
|
[["_Test Item", "_Test Warehouse - _TC", 50.0]])
|
||||||
@ -111,7 +113,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
|
|
||||||
def test_material_issue_gl_entry(self):
|
def test_material_issue_gl_entry(self):
|
||||||
self._clear_stock_account_balance()
|
self._clear_stock_account_balance()
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
set_perpetual_inventory()
|
||||||
|
|
||||||
self._insert_material_receipt()
|
self._insert_material_receipt()
|
||||||
|
|
||||||
@ -122,8 +124,9 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
self.check_stock_ledger_entries("Stock Entry", mi.doc.name,
|
self.check_stock_ledger_entries("Stock Entry", mi.doc.name,
|
||||||
[["_Test Item", "_Test Warehouse - _TC", -40.0]])
|
[["_Test Item", "_Test Warehouse - _TC", -40.0]])
|
||||||
|
|
||||||
stock_in_hand_account = webnotes.conn.get_value("Warehouse", mi.doclist[1].s_warehouse,
|
stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse",
|
||||||
"account")
|
"master_name": mi.doclist[1].s_warehouse})
|
||||||
|
|
||||||
self.check_gl_entries("Stock Entry", mi.doc.name,
|
self.check_gl_entries("Stock Entry", mi.doc.name,
|
||||||
sorted([
|
sorted([
|
||||||
[stock_in_hand_account, 0.0, 4000.0],
|
[stock_in_hand_account, 0.0, 4000.0],
|
||||||
@ -146,7 +149,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
|
|
||||||
def test_material_transfer_gl_entry(self):
|
def test_material_transfer_gl_entry(self):
|
||||||
self._clear_stock_account_balance()
|
self._clear_stock_account_balance()
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
set_perpetual_inventory()
|
||||||
|
|
||||||
self._insert_material_receipt()
|
self._insert_material_receipt()
|
||||||
|
|
||||||
@ -157,10 +160,12 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
self.check_stock_ledger_entries("Stock Entry", mtn.doc.name,
|
self.check_stock_ledger_entries("Stock Entry", mtn.doc.name,
|
||||||
[["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]])
|
[["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]])
|
||||||
|
|
||||||
stock_in_hand_account = webnotes.conn.get_value("Warehouse", mtn.doclist[1].s_warehouse,
|
stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse",
|
||||||
"account")
|
"master_name": mtn.doclist[1].s_warehouse})
|
||||||
fixed_asset_account = webnotes.conn.get_value("Warehouse", mtn.doclist[1].t_warehouse,
|
|
||||||
"account")
|
fixed_asset_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse",
|
||||||
|
"master_name": mtn.doclist[1].t_warehouse})
|
||||||
|
|
||||||
|
|
||||||
self.check_gl_entries("Stock Entry", mtn.doc.name,
|
self.check_gl_entries("Stock Entry", mtn.doc.name,
|
||||||
sorted([
|
sorted([
|
||||||
@ -180,7 +185,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
|
|
||||||
def test_repack_no_change_in_valuation(self):
|
def test_repack_no_change_in_valuation(self):
|
||||||
self._clear_stock_account_balance()
|
self._clear_stock_account_balance()
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
set_perpetual_inventory()
|
||||||
|
|
||||||
self._insert_material_receipt()
|
self._insert_material_receipt()
|
||||||
|
|
||||||
@ -197,11 +202,11 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
order by account desc""", repack.doc.name, as_dict=1)
|
order by account desc""", repack.doc.name, as_dict=1)
|
||||||
self.assertFalse(gl_entries)
|
self.assertFalse(gl_entries)
|
||||||
|
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
def test_repack_with_change_in_valuation(self):
|
def test_repack_with_change_in_valuation(self):
|
||||||
self._clear_stock_account_balance()
|
self._clear_stock_account_balance()
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
set_perpetual_inventory()
|
||||||
|
|
||||||
self._insert_material_receipt()
|
self._insert_material_receipt()
|
||||||
|
|
||||||
@ -210,8 +215,8 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
repack.insert()
|
repack.insert()
|
||||||
repack.submit()
|
repack.submit()
|
||||||
|
|
||||||
stock_in_hand_account = webnotes.conn.get_value("Warehouse",
|
stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse",
|
||||||
repack.doclist[2].t_warehouse, "account")
|
"master_name": repack.doclist[2].t_warehouse})
|
||||||
|
|
||||||
self.check_gl_entries("Stock Entry", repack.doc.name,
|
self.check_gl_entries("Stock Entry", repack.doc.name,
|
||||||
sorted([
|
sorted([
|
||||||
@ -219,7 +224,7 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
["Stock Adjustment - _TC", 0.0, 1000.0],
|
["Stock Adjustment - _TC", 0.0, 1000.0],
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
set_perpetual_inventory(0)
|
||||||
|
|
||||||
def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
|
def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle):
|
||||||
expected_sle.sort(key=lambda x: x[0])
|
expected_sle.sort(key=lambda x: x[0])
|
||||||
|
@ -89,6 +89,9 @@ class DocType(DocListController):
|
|||||||
where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)):
|
where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)):
|
||||||
webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code))
|
webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code))
|
||||||
|
|
||||||
|
if not self.doc.stock_uom:
|
||||||
|
self.doc.stock_uom = item_det.stock_uom
|
||||||
|
|
||||||
def get_item_details(self):
|
def get_item_details(self):
|
||||||
return webnotes.conn.sql("""select name, has_batch_no, docstatus,
|
return webnotes.conn.sql("""select name, has_batch_no, docstatus,
|
||||||
is_stock_item, has_serial_no, serial_no_series
|
is_stock_item, has_serial_no, serial_no_series
|
||||||
@ -98,11 +101,6 @@ class DocType(DocListController):
|
|||||||
def validate_serial_no(self):
|
def validate_serial_no(self):
|
||||||
item_det = self.get_item_details()
|
item_det = self.get_item_details()
|
||||||
|
|
||||||
if not self.doc.stock_uom:
|
|
||||||
self.doc.stock_uom = item_det.stock_uom
|
|
||||||
|
|
||||||
self.validate_serial_no(item_det)
|
|
||||||
|
|
||||||
if item_det.has_serial_no=="No":
|
if item_det.has_serial_no=="No":
|
||||||
if self.doc.serial_no:
|
if self.doc.serial_no:
|
||||||
webnotes.throw(_("Serial Number should be blank for Non Serialized Item" + ": " + self.doc.item),
|
webnotes.throw(_("Serial Number should be blank for Non Serialized Item" + ": " + self.doc.item),
|
||||||
|
@ -295,12 +295,12 @@ class DocType(StockController):
|
|||||||
|
|
||||||
webnotes.conn.set(self.doc, "stock_value_difference", json.dumps(stock_value_difference))
|
webnotes.conn.set(self.doc, "stock_value_difference", json.dumps(stock_value_difference))
|
||||||
|
|
||||||
def get_gl_entries_for_stock(self):
|
def get_gl_entries_for_stock(self, warehouse_account=None):
|
||||||
if not self.doc.cost_center:
|
if not self.doc.cost_center:
|
||||||
msgprint(_("Please enter Cost Center"), raise_exception=1)
|
msgprint(_("Please enter Cost Center"), raise_exception=1)
|
||||||
|
|
||||||
return super(DocType, self).get_gl_entries_for_stock(self.doc.expense_account,
|
return super(DocType, self).get_gl_entries_for_stock(warehouse_account,
|
||||||
self.doc.cost_center)
|
self.doc.expense_account, self.doc.cost_center)
|
||||||
|
|
||||||
|
|
||||||
def validate_expense_account(self):
|
def validate_expense_account(self):
|
||||||
|
@ -270,7 +270,9 @@ def make_stock_entry_from_pro(pro_id, purpose, current_date):
|
|||||||
st = webnotes.bean(make_stock_entry(pro_id, purpose))
|
st = webnotes.bean(make_stock_entry(pro_id, purpose))
|
||||||
st.doc.posting_date = current_date
|
st.doc.posting_date = current_date
|
||||||
st.doc.fiscal_year = "2013"
|
st.doc.fiscal_year = "2013"
|
||||||
st.doc.expense_adjustment_account = "Stock in Hand - WP"
|
for d in st.doclist.get({"parentfield": "mtn_details"}):
|
||||||
|
d.expense_account = "Stock Adjustment - " + company_abbr
|
||||||
|
d.cost_center = "Main - " + company_abbr
|
||||||
st.insert()
|
st.insert()
|
||||||
webnotes.conn.commit()
|
webnotes.conn.commit()
|
||||||
st.submit()
|
st.submit()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user