Merge branch 'master' of github.com:webnotes/erpnext

This commit is contained in:
Akhilesh Darjee 2013-09-19 11:31:43 +05:30
commit 680ba8d912
8 changed files with 464 additions and 61 deletions

View File

@ -88,6 +88,9 @@ Contents
1. [Sales Return](docs.user.stock.sales_return.html)
1. [Purchase Return](docs.user.stock.purchase_return.html)
1. [Projected Quantity](docs.user.stock.projected_quantity.html)
1. [Accounting for Stock](docs.user.stock.accounting_for_stock.html)
1. [Perpetual Inventory](docs.user.stock.perpetual_inventory.html)
1. [Perpetual Inventory Migration](docs.user.stock.periodic_to_perpetual.html)
1. [Accounts](docs.user.accounts.html)
1. [Chart of Accounts](docs.user.setup.accounting.html)
1. [Chart of Cost Centers](docs.user.setup.cost_centers.html)

View File

@ -0,0 +1,42 @@
---
{
"_label": "Accounting of Inventory / Stock"
}
---
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:
### **Auto / Perpetual Inventory**
In this process, for each stock transactions, the system posts relevant accounting entries to sync stock balance and accounting balance. This is the default setting in ERPNext for new accounts.
When you buy and receive items, those items are booked as the companys 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. As a result, the value as per Stock Ledger always remains same with the relevant account balance. This improves accuracy of Balance Sheet and Profit and Loss statement.
To check accounting entries for a particular stock transaction, please check [**examples**](docs.user.stock.perpetual_inventory.html)
#### **Advantages**
Perpetual Inventory system will make it easier for you to maintain accuracy of company's asset and expense values. Stock balances will always be synced with relevant account balances, so no more periodic manual entry has to be done to balance them.
In case of new back-dated stock transactions or cancellation/amendment of an existing transaction, all the future Stock Ledger entries and GL Entries will be recalculated for all items of that transaction.
The same is applicable if any cost is added to the submitted Purchase Receipt, later through the Landed Cost Wizard.
>Note: Perpetual Inventory totally depends upon the item valuation rate. Hence, you have to be more careful entering valuation rate while making any incoming stock transactions like Purchase Receipt, Material Receipt, or Manufacturing / Repack.
-
### **Periodic Inventory**
In this method, accounting entries are manually created periodically, to sync stock balance and relevant account balance. The system does not create accounting entries automatically for assets, at the time of material purchases or sales.
In an accounting period, when you buy and receive items, an expense is booked in your accounting system. You sell and deliver some of these items.
At the end of an accounting period, the total value of items to be sold, need to be booked as the companys assets, often known as stock-in-hand.
The difference between the value of the items remaining to be sold and the previous periods stock-in-hand value can be positive or negative. If positive, this value is removed from expenses (cost-of-goods-sold) and is added to assets (stock-in-hand / fixed-assets). If negative, a reverse entry is passed.
This complete process is called Periodic Inventory.
If you are an existing user using Periodic Inventory and want to use Perpetual Inventory, you have to follow some steps to migrate. For details, check [**Migration From Periodic Inventory**](docs.user.stock.periodic_to_perpetual.html)

View File

@ -0,0 +1,31 @@
---
{
"_label": "Migration from Periodic Inventory"
}
---
Migration from Periodic Inventory is not a one click setting, it involves some special steps. As Perpetual Inventory always maintains 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:
- Nullify the balance of account heads (stock-in-hand / fixed-asset) which you are using to maintain available stock value, through a Journal Voucher.
- As existing warehouses are linked to stock transactions which does not have corresponding accounting entries, those warehouses can not be used for perpetual inventory. You have to create new warehouses for the future stock transactions which will be linked to their respective accounts. While creating new warehouses, select an account group under which the child account for the warehouse will be created.
- Setup the following default accounts for each Company
- Stock Received But Not Billed
- Stock Adjustment Account
- Expenses Included In Valuation
- Cost Center
- Activate Perpetual Inventory
> Setup > Accounts Settings > Make Accounting Entry For Every Stock Movement
![Activation](img/accounting-for-stock-1.png)
<br><br>
- Create Stock Entry (Material Transfer) to transfer available stock from existing warehouse to new warehouse. As stock will be available in the new warehouse, you should select the new warehouse for all the future transactions.
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 any account. If you create any new transaction or modify/amend existing transactions, with old warehouse, there will be no corresponding accounting entries. You have to manually sync stock and account balance through Journal Voucher.
> Note: If you are already using old Perpetual Inventory system, it will be deactivated automatically. You need to follow the above steps to reactivate it.

View File

@ -0,0 +1,313 @@
---
{
"_label": "Perpetual Inventory"
}
---
In perpetual inventory, system creates accounting entries for each stock transactions, so that stock and account balance will always remain same. The account balance will be posted against their respective account heads for each Warehouse. On saving of a Warehouse, the system will automatically create an account head with the same name as warehouse. As account balance is maintained for each Warehouse, you should create Warehouses, based on the type of items (Current / Fixed Assets) it stores.
At the time of items received in a particular warehouse, the balance of asset account (linked to that warehouse) will be increased. Similarly when you deliver some items from that warehouse, an expense will be booked and the asset account will be reduced, based on the valuation amount of those items.
## **Activation**
1. Setup the following default accounts for each Company
- Stock Received But Not Billed
- Stock Adjustment Account
- Expenses Included In Valuation
- Cost Center
2. In perpetual inventory, the system will maintain seperate account balance for each warehouse under separate account head. To create that account head, enter "Create Account Under" in Warehouse master.
3. Activate Perpetual Inventory
> Setup > Accounts Settings > Make Accounting Entry For Every Stock Movement
-
## **Example**
Consider following Chart of Accounts and Warehouse setup for your company:
#### Chart of Accounts
- Assets (Dr)
- Current Assets
- Accounts Receivable
- Jane Doe
- Stock Assets
- Stores
- Finished Goods
- Work In Progress
- Tax Assets
- VAT
- Fixed Assets
- Fixed Asset Warehouse
- Liabilities (Cr)
- Current Liabilities
- Accounts Payable
- East Wind Inc.
- Stock Liabilities
- Stock Received But Not Billed
- Tax Liabilities
- Service Tax
- Income (Cr)
- Direct Income
- Sales Account
- Expenses (Dr)
- Direct Expenses
- Stock Expenses
- Cost of Goods Sold
- Expenses Included In Valuation
- Stock Adjustment
- Shipping Charges
- Customs Duty
#### Warehouse - Account Configuration
- Stores
- Work In Progress
- Finished Goods
- Fixed Asset Warehouse
### **Purchase Receipt**
Suppose you have purchased *10 nos* of item "RM0001" at *$200* and *5 nos* of item "Desktop" at **$100** from supplier "East Wind Inc". Following are the details of Purchase Receipt:
<b>Supplier:</b> East Wind Inc.
<b>Items:</b>
<table class="table table-bordered">
<thead>
<tr>
<th>Item</th><th>Warehouse</th><th>Qty</th>
<th>Rate</th><th>Amount</th><th>Valuation Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>RM0001</td><td>Stores</td><td>10</td><td>200</td><td>2000</td><td>2200</td>
</tr>
<tr>
<td>Desktop</td><td>Fixed Asset Warehouse</td>
<td>5</td><td>100</td><td>500</td><td>550</td>
</tr>
</tbody>
</table>
**Taxes:**
<table class="table table-bordered">
<thead>
<tr><th>Account</th><th>Amount</th><th>Category</th></tr>
</thead>
<tbody>
<tr><td>Shipping Charges</td><td>100</td><td>Total and Valuation</td></tr>
<tr><td>VAT</td><td>120</td><td>Total</td></tr>
<tr><td>Customs Duty</td><td>150</td><td>Valuation</td></tr>
</tbody>
</table>
**Stock Ledger**
![pr_stock_ledger](img/accounting-for-stock-2.png)
**General Ledger**
![pr_general_ledger](img/accounting-for-stock-3.png)
As stock balance increases through Purchase Receipt, "Store" and "Fixed Asset Warehouse" accounts are debited and a temporary account "Stock Receipt But Not Billed" account is credited, to maintain double entry accounting system.
--
### **Purchase Invoice**
On receiving Bill from supplier, for the above Purchase Receipt, you will make Purchase Invoice for the same. The general ledger entries are as follows:
**General Ledger**
![pi_general_ledger](img/accounting-for-stock-4.png)
Here "Stock Received But Not Billed" account is debited and nullified the effect of Purchase Receipt. "Expenses Included In Valuation" account has been credited which ensures the valuation expense accounts are not booked (debited) twice (in Purchase Invoice and Delivery Note).
--
### **Delivery Note**
Lets say, you have an order from "Jane Doe" to deliver 5 nos of item "RM0001" at $300. Following are the details of Delivery Note:
**Customer:** Jane Doe
**Items:**
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Warehouse</th><th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>RM0001</td><td>Stores</td><td>5</td><td>300</td><td>1500</td></tr>
</tbody>
</table>
**Taxes:**
<table class="table table-bordered">
<thead>
<tr><th>Account</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>Service Tax</td><td>150</td></tr>
<tr><td>VAT</td><td>100</td></tr>
</tbody>
</table>
**Stock Ledger**
![dn_stock_ledger](img/accounting-for-stock-5.png)
**General Ledger**
![dn_general_ledger](img/accounting-for-stock-6.png)
As item is delivered from "Stores" warehouse, "Stores" account is credited and equal amount is debited to the expense account "Cost of Goods Sold". The debit/credit amount is equal to the total valuation amount (buying cost) of the selling items. And valuation amount is calculated based on your prefferred valuation method (FIFO / Moving Average) or actual cost of serialized items.
<pre>
<code>
In this example, we have considered valuation method as FIFO.
Valuation Rate = Purchase Rate + Charges Included in Valuation
= 200 + (250 * (2000 / 2500) / 10)
= 220
Total Valuation Amount = 220 * 5
= 1100
</code>
</pre>
--
### **Sales Invoice with Update Stock**
Lets say, you did not make Delivery Note against the above order and instead you have made Sales Invoice directly, with "Update Stock" options. The details of the Sales Invoice are same as the above Delivery Note.
**Stock Ledger**
![si_stock_ledger](img/accounting-for-stock-7.png)
**General Ledger**
![si_general_ledger](img/accounting-for-stock-8.png)
Here, apart from normal account entries for invoice, "Stores" and "Cost of Goods Sold" accounts are also affected based on the valuation amount.
--
### **Stock Entry (Material Receipt)**
**Items:**
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Target Warehouse</th><th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>RM0001</td><td>Stores</td><td>50</td><td>220</td><td>11000</td></tr>
</tbody>
</table>
**Stock Ledger**
![mr_stock_ledger](img/accounting-for-stock-9.png)
**General Ledger**
![mr_stock_ledger](img/accounting-for-stock-10.png)
--
### **Stock Entry (Material Issue)**
**Items:**
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Source Warehouse</th><th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>RM0001</td><td>Stores</td><td>10</td><td>220</td><td>2200</td></tr>
</tbody>
</table>
**Stock Ledger**
![mi_stock_ledger](img/accounting-for-stock-11.png)
**General Ledger**
![mi_stock_ledger](img/accounting-for-stock-12.png)
--
### **Stock Entry (Material Transfer)**
**Items:**
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Source Warehouse</th><th>Target Warehouse</th>
<th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>RM0001</td><td>Stores</td><td>Work In Progress</td>
<td>10</td><td>220</td><td>2200</td></tr>
</tbody>
</table>
**Stock Ledger**
![mtn_stock_ledger](img/accounting-for-stock-13.png)
**General Ledger**
![mtn_general_ledger](img/accounting-for-stock-14.png)
--
### **Stock Entry (Sales Return - Sales Invoice booked)**
**Items:**
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Target Warehouse</th><th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>RM0001</td><td>Stores</td><td>2</td><td>200</td><td>400</td></tr>
</tbody>
</table>
**Stock Ledger**
![sret_stock_ledger](img/accounting-for-stock-15.png)
**General Ledger**
![sret_general_ledger](img/accounting-for-stock-16.png)
--
### **Stock Entry (Purchase Return)**
**Items:**
<table class="table table-bordered">
<thead>
<tr><th>Item</th><th>Source Warehouse</th><th>Qty</th><th>Rate</th><th>Amount</th></tr>
</thead>
<tbody>
<tr><td>RM0001</td><td>Stores</td><td>4</td><td>220</td><td>880</td></tr>
</tbody>
</table>
**Stock Ledger**
![pret_stock_ledger](img/accounting-for-stock-17.png)
**General Ledger**
![pret_general_ledger](img/accounting-for-stock-18.png)

View File

@ -2,7 +2,7 @@
{
"creation": "2013-04-10 11:45:37",
"docstatus": 0,
"modified": "2013-09-10 10:52:20",
"modified": "2013-09-19 10:38:58",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -158,10 +158,77 @@
"doctype": "DocField",
"fieldname": "communication_history",
"fieldtype": "Section Break",
"label": "Communication History",
"label": "Communication",
"options": "icon-comments",
"print_hide": 1
},
{
"default": "__user",
"doctype": "DocField",
"fieldname": "lead_owner",
"fieldtype": "Link",
"in_filter": 1,
"label": "Lead Owner",
"oldfieldname": "lead_owner",
"oldfieldtype": "Link",
"options": "Profile",
"search_index": 1
},
{
"depends_on": "eval:!doc.__islocal",
"description": "Date on which the lead was last contacted",
"doctype": "DocField",
"fieldname": "last_contact_date",
"fieldtype": "Date",
"label": "Last Contact Date",
"no_copy": 1,
"oldfieldname": "last_contact_date",
"oldfieldtype": "Date",
"print_hide": 1,
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "col_break123",
"fieldtype": "Column Break",
"width": "50%"
},
{
"allow_on_submit": 0,
"description": "Your sales person who will contact the lead in future",
"doctype": "DocField",
"fieldname": "contact_by",
"fieldtype": "Link",
"hidden": 0,
"in_filter": 1,
"label": "Next Contact By",
"oldfieldname": "contact_by",
"oldfieldtype": "Link",
"options": "Profile",
"print_hide": 0,
"reqd": 0,
"width": "100px"
},
{
"allow_on_submit": 0,
"description": "Your sales person will get a reminder on this date to contact the lead",
"doctype": "DocField",
"fieldname": "contact_date",
"fieldtype": "Date",
"in_filter": 1,
"label": "Next Contact Date",
"no_copy": 1,
"oldfieldname": "contact_date",
"oldfieldtype": "Date",
"reqd": 0,
"width": "100px"
},
{
"doctype": "DocField",
"fieldname": "sec_break123",
"fieldtype": "Section Break",
"options": "Simple"
},
{
"allow_on_submit": 0,
"doctype": "DocField",
@ -274,18 +341,6 @@
"oldfieldtype": "Select",
"options": "\nClient\nChannel Partner\nConsultant"
},
{
"default": "__user",
"doctype": "DocField",
"fieldname": "lead_owner",
"fieldtype": "Link",
"in_filter": 1,
"label": "Lead Owner",
"oldfieldname": "lead_owner",
"oldfieldtype": "Link",
"options": "Profile",
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "market_segment",
@ -347,49 +402,6 @@
"oldfieldtype": "Link",
"options": "Quotation Lost Reason"
},
{
"allow_on_submit": 0,
"description": "Your sales person who will contact the lead in future",
"doctype": "DocField",
"fieldname": "contact_by",
"fieldtype": "Link",
"hidden": 0,
"in_filter": 1,
"label": "Next Contact By",
"oldfieldname": "contact_by",
"oldfieldtype": "Link",
"options": "Profile",
"print_hide": 0,
"reqd": 0,
"width": "100px"
},
{
"allow_on_submit": 0,
"description": "Your sales person will get a reminder on this date to contact the lead",
"doctype": "DocField",
"fieldname": "contact_date",
"fieldtype": "Date",
"in_filter": 1,
"label": "Next Contact Date",
"no_copy": 1,
"oldfieldname": "contact_date",
"oldfieldtype": "Date",
"reqd": 0,
"width": "100px"
},
{
"depends_on": "eval:!doc.__islocal",
"description": "Date on which the lead was last contacted",
"doctype": "DocField",
"fieldname": "last_contact_date",
"fieldtype": "Date",
"label": "Last Contact Date",
"no_copy": 1,
"oldfieldname": "last_contact_date",
"oldfieldtype": "Date",
"print_hide": 1,
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "company",

View File

@ -75,8 +75,8 @@ class DocType(DocListController):
bin_list = webnotes.conn.sql("select * from tabBin where item_code=%s",
self.doc.item_code, as_dict=1)
for bin in bin_list:
if bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \
or bin.planned_qty > 0 and cstr(bin.stock_uom) != cstr(self.doc.stock_uom):
if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \
or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(self.doc.stock_uom):
matched = False
break

View File

@ -886,7 +886,8 @@ def make_return_jv(stock_entry):
"account": r.get("account"),
"against_invoice": r.get("against_invoice"),
"against_voucher": r.get("against_voucher"),
"balance": get_balance_on(r.get("account"), se.doc.posting_date)
"balance": get_balance_on(r.get("account"), se.doc.posting_date) \
if r.get("account") else 0
})
return jv_list

View File

@ -243,7 +243,8 @@ class TransactionBase(StatusUpdater):
def delete_events(self):
webnotes.delete_doc("Event", webnotes.conn.sql_list("""select name from `tabEvent`
where ref_type=%s and ref_name=%s""", (self.doc.doctype, self.doc.name)))
where ref_type=%s and ref_name=%s""", (self.doc.doctype, self.doc.name)),
ignore_permissions=True)
def _add_calendar_event(self, opts):
opts = webnotes._dict(opts)