aii: stock entry
diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py
index 40606c3..f9498cb 100644
--- a/controllers/selling_controller.py
+++ b/controllers/selling_controller.py
@@ -19,9 +19,9 @@
from webnotes.utils import cint
from setup.utils import get_company_currency
-from controllers.accounts_controller import AccountsController
+from controllers.stock_controller import StockController
-class SellingController(AccountsController):
+class SellingController(StockController):
def validate(self):
self.set_total_in_words()
@@ -37,27 +37,4 @@
self.doc.grand_total or self.doc.rounded_total, company_currency)
if self.meta.get_field("in_words_export"):
self.doc.in_words_export = money_in_words(disable_rounded_total and
- self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
-
- def get_stock_ledger_entries(self):
- item_list, warehouse_list = self.get_distinct_item_warehouse()
- if item_list and warehouse_list:
- return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
- voucher_detail_no, posting_date, posting_time, stock_value,
- warehouse, actual_qty as qty from `tabStock Ledger Entry`
- where ifnull(`is_cancelled`, "No") = "No" and company = %s
- and item_code in (%s) and warehouse in (%s)
- order by item_code desc, warehouse desc, posting_date desc,
- posting_time desc, name desc""" %
- ('%s', ', '.join(['%s']*len(item_list)), ', '.join(['%s']*len(warehouse_list))),
- tuple([self.doc.company] + item_list + warehouse_list), as_dict=1)
-
- def get_distinct_item_warehouse(self):
- item_list = []
- warehouse_list = []
- for item in self.doclist.get({"parentfield": self.fname}) \
- + self.doclist.get({"parentfield": "packing_details"}):
- item_list.append(item.item_code)
- warehouse_list.append(item.warehouse)
-
- return list(set(item_list)), list(set(warehouse_list))
\ No newline at end of file
+ self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
\ No newline at end of file
diff --git a/controllers/stock_controller.py b/controllers/stock_controller.py
new file mode 100644
index 0000000..3a900aa
--- /dev/null
+++ b/controllers/stock_controller.py
@@ -0,0 +1,71 @@
+# ERPNext - web based ERP (http://erpnext.com)
+# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import unicode_literals
+import webnotes
+from controllers.accounts_controller import AccountsController
+
+class StockController(AccountsController):
+ def make_gl_entries(self, against_stock_account, amount, cost_center=None):
+ stock_in_hand_account = self.get_stock_in_hand_account()
+
+ if amount:
+ gl_entries = [
+ # stock in hand account
+ self.get_gl_dict({
+ "account": stock_in_hand_account,
+ "against": against_stock_account,
+ "debit": amount,
+ "remarks": self.doc.remarks or "Accounting Entry for Stock",
+ }, self.doc.docstatus == 2),
+
+ # account against stock in hand
+ self.get_gl_dict({
+ "account": against_stock_account,
+ "against": stock_in_hand_account,
+ "credit": amount,
+ "cost_center": cost_center or None,
+ "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_stock_ledger_entries(self, item_list=None, warehouse_list=None):
+ if not (item_list and warehouse_list):
+ item_list, warehouse_list = self.get_distinct_item_warehouse()
+
+ if item_list and warehouse_list:
+ return webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
+ voucher_detail_no, posting_date, posting_time, stock_value,
+ warehouse, actual_qty as qty from `tabStock Ledger Entry`
+ where ifnull(`is_cancelled`, "No") = "No" and company = %s
+ and item_code in (%s) and warehouse in (%s)
+ order by item_code desc, warehouse desc, posting_date desc,
+ posting_time desc, name desc""" %
+ ('%s', ', '.join(['%s']*len(item_list)), ', '.join(['%s']*len(warehouse_list))),
+ tuple([self.doc.company] + item_list + warehouse_list), as_dict=1)
+
+ def get_distinct_item_warehouse(self):
+ item_list = []
+ warehouse_list = []
+ for item in self.doclist.get({"parentfield": self.fname}) \
+ + self.doclist.get({"parentfield": "packing_details"}):
+ item_list.append(item.item_code)
+ warehouse_list.append(item.warehouse)
+
+ return list(set(item_list)), list(set(warehouse_list))
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index ba1f648..0a75914 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -234,4 +234,11 @@
cur_frm.fields_dict.customer.get_query = erpnext.utils.customer_query;
-cur_frm.fields_dict.supplier.get_query = erpnext.utils.supplier_query;
\ No newline at end of file
+cur_frm.fields_dict.supplier.get_query = erpnext.utils.supplier_query;
+
+cur_frm.fields_dict["expense_adjustment_account"].get_query = function(doc) {
+ return {
+ "query": "accounts.utils.get_account_list",
+ "filters": { "company": doc.company }
+ }
+}
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index cd20266..17e2655 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -26,12 +26,11 @@
from stock.stock_ledger import get_previous_sle
import json
-
sql = webnotes.conn.sql
-from controllers.accounts_controller import AccountsController
+from controllers.stock_controller import StockController
-class DocType(AccountsController):
+class DocType(StockController):
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
@@ -168,41 +167,24 @@
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)
+ if not self.doc.expense_adjustment_account:
+ webnotes.msgprint(_("Please enter Expense/Adjustment Account"), raise_exception=1)
+ cost_center = "Auto Inventory Accounting - %s" % (self.company_abbr,)
+ total_valuation_amount = self.get_total_valuation_amount()
+
+ super(DocType, self).make_gl_entries(self.doc.expense_adjustment_account,
+ total_valuation_amount, cost_center)
+
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):
diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt
index 2554455..0132652 100644
--- a/stock/doctype/stock_entry/stock_entry.txt
+++ b/stock/doctype/stock_entry/stock_entry.txt
@@ -1,8 +1,8 @@
[
{
- "creation": "2013-01-23 19:57:20",
+ "creation": "2013-03-07 18:50:32",
"docstatus": 0,
- "modified": "2013-01-28 17:59:20",
+ "modified": "2013-03-14 12:25:00",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -60,6 +60,7 @@
"fieldtype": "Column Break",
"oldfieldtype": "Column Break",
"print_width": "50%",
+ "read_only": 0,
"width": "50%"
},
{
@@ -76,6 +77,7 @@
"oldfieldtype": "Select",
"options": "\nSTE",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0
@@ -95,6 +97,7 @@
"oldfieldtype": "Select",
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nManufacture/Repack\nSubcontract\nSales Return\nPurchase Return",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0
@@ -105,6 +108,7 @@
"fieldtype": "Column Break",
"oldfieldtype": "Column Break",
"print_width": "50%",
+ "read_only": 0,
"width": "50%"
},
{
@@ -122,6 +126,7 @@
"oldfieldname": "posting_date",
"oldfieldtype": "Date",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
@@ -138,16 +143,26 @@
"oldfieldname": "posting_time",
"oldfieldtype": "Time",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0
},
{
+ "depends_on": "eval:sys_defaults.auto_inventory_accounting",
+ "doctype": "DocField",
+ "fieldname": "expense_adjustment_account",
+ "fieldtype": "Link",
+ "label": "Expense/Adjustment Account",
+ "options": "Account"
+ },
+ {
"doctype": "DocField",
"fieldname": "items_section",
"fieldtype": "Section Break",
"label": "Items",
- "oldfieldtype": "Section Break"
+ "oldfieldtype": "Section Break",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -163,6 +178,7 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -170,7 +186,8 @@
{
"doctype": "DocField",
"fieldname": "cb0",
- "fieldtype": "Column Break"
+ "fieldtype": "Column Break",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -186,6 +203,7 @@
"oldfieldtype": "Link",
"options": "Warehouse",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -194,7 +212,8 @@
"doctype": "DocField",
"fieldname": "sb0",
"fieldtype": "Section Break",
- "options": "Simple"
+ "options": "Simple",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -209,6 +228,7 @@
"oldfieldtype": "Table",
"options": "Stock Entry Detail",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -221,13 +241,15 @@
"label": "Get Stock and Rate",
"oldfieldtype": "Button",
"options": "get_stock_and_rate",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"doctype": "DocField",
"fieldname": "sb1",
"fieldtype": "Section Break",
- "label": "Reference"
+ "label": "Reference",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -243,6 +265,7 @@
"oldfieldtype": "Link",
"options": "Production Order",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1
@@ -253,7 +276,8 @@
"fieldname": "bom_no",
"fieldtype": "Link",
"label": "BOM No",
- "options": "BOM"
+ "options": "BOM",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -269,6 +293,7 @@
"oldfieldname": "fg_completed_qty",
"oldfieldtype": "Currency",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -287,6 +312,7 @@
"oldfieldtype": "Link",
"options": "Delivery Note",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1
@@ -305,6 +331,7 @@
"oldfieldtype": "Link",
"options": "Purchase Receipt",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1
@@ -312,7 +339,8 @@
{
"doctype": "DocField",
"fieldname": "cb1",
- "fieldtype": "Column Break"
+ "fieldtype": "Column Break",
+ "read_only": 0
},
{
"default": "1",
@@ -321,7 +349,8 @@
"doctype": "DocField",
"fieldname": "use_multi_level_bom",
"fieldtype": "Check",
- "label": "Use Multi-Level BOM"
+ "label": "Use Multi-Level BOM",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -335,6 +364,7 @@
"no_copy": 0,
"oldfieldtype": "Button",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -348,14 +378,16 @@
"label": "Sales Invoice No",
"no_copy": 1,
"options": "Sales Invoice",
- "print_hide": 1
+ "print_hide": 1,
+ "read_only": 0
},
{
"depends_on": "eval:(doc.purpose==\"Sales Return\" || doc.purpose==\"Purchase Return\")",
"doctype": "DocField",
"fieldname": "contact_section",
"fieldtype": "Section Break",
- "label": "Contact Info"
+ "label": "Contact Info",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -371,6 +403,7 @@
"oldfieldtype": "Link",
"options": "Supplier",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -406,6 +439,7 @@
"oldfieldname": "supplier_address",
"oldfieldtype": "Small Text",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -424,6 +458,7 @@
"oldfieldtype": "Link",
"options": "Customer",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -459,6 +494,7 @@
"oldfieldname": "customer_address",
"oldfieldtype": "Small Text",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -468,13 +504,15 @@
"fieldname": "more_info",
"fieldtype": "Section Break",
"label": "More Info",
- "oldfieldtype": "Section Break"
+ "oldfieldtype": "Section Break",
+ "read_only": 0
},
{
"doctype": "DocField",
"fieldname": "col4",
"fieldtype": "Column Break",
"print_width": "50%",
+ "read_only": 0,
"width": "50%"
},
{
@@ -485,7 +523,8 @@
"label": "Project Name",
"oldfieldname": "project_name",
"oldfieldtype": "Link",
- "options": "Project"
+ "options": "Project",
+ "read_only": 0
},
{
"allow_on_submit": 0,
@@ -500,6 +539,7 @@
"oldfieldtype": "Link",
"options": "Print Heading",
"print_hide": 0,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -517,6 +557,7 @@
"oldfieldtype": "Link",
"options": "Company",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0
@@ -526,6 +567,7 @@
"fieldname": "col5",
"fieldtype": "Column Break",
"print_width": "50%",
+ "read_only": 0,
"width": "50%"
},
{
@@ -558,6 +600,7 @@
"oldfieldname": "remarks",
"oldfieldtype": "Text",
"print_hide": 1,
+ "read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
@@ -569,5 +612,13 @@
{
"doctype": "DocPerm",
"role": "Manufacturing User"
+ },
+ {
+ "doctype": "DocPerm",
+ "role": "Manufacturing Manager"
+ },
+ {
+ "doctype": "DocPerm",
+ "role": "Material Manager"
}
]
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py
index a4103c3..f193826 100644
--- a/stock/doctype/stock_entry/test_stock_entry.py
+++ b/stock/doctype/stock_entry/test_stock_entry.py
@@ -168,6 +168,7 @@
"posting_time": "17:14:24",
"purpose": "Material Receipt",
"fiscal_year": "_Test Fiscal Year 2013",
+ "expense_adjustment_account": "Stock Adjustment - _TC"
},
{
"conversion_factor": 1.0,
@@ -190,6 +191,7 @@
"posting_time": "17:15",
"purpose": "Material Issue",
"fiscal_year": "_Test Fiscal Year 2013",
+ "expense_adjustment_account": "Stock Adjustment - _TC"
},
{
"conversion_factor": 1.0,
@@ -212,6 +214,7 @@
"posting_time": "17:14:24",
"purpose": "Material Transfer",
"fiscal_year": "_Test Fiscal Year 2013",
+ "expense_adjustment_account": "Stock Adjustment - _TC"
},
{
"conversion_factor": 1.0,
diff --git a/stock/stock_ledger.py b/stock/stock_ledger.py
index 883ced7..d00b243 100644
--- a/stock/stock_ledger.py
+++ b/stock/stock_ledger.py
@@ -71,7 +71,7 @@
(qty_after_transaction * valuation_rate) or 0
else:
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
-
+ # print sle.posting_date, sle.actual_qty, sle.incoming_rate, stock_queue, stock_value
# update current sle
webnotes.conn.sql("""update `tabStock Ledger Entry`
set qty_after_transaction=%s, valuation_rate=%s, stock_queue=%s,
diff --git a/stock/utils.py b/stock/utils.py
index bf5e2f9..b4d0770 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -165,8 +165,8 @@
return wlist
def get_buying_amount(item_code, warehouse, qty, voucher_type, voucher_no, voucher_detail_no,
- stock_ledger_entries, item_sales_bom):
- if item_sales_bom.get(item_code):
+ stock_ledger_entries, item_sales_bom=None):
+ if item_sales_bom and item_sales_bom.get(item_code):
# sales bom item
buying_amount = 0.0
for bom_item in item_sales_bom[item_code]:
@@ -182,13 +182,15 @@
stock_ledger_entries):
for i, sle in enumerate(stock_ledger_entries):
if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
- len(stock_ledger_entries) > i+1:
- if (sle.voucher_detail_no == item_row) or \
- (sle.item_code == item_code and sle.warehouse == warehouse and \
- abs(flt(sle.qty)) == qty):
- buying_amount = flt(stock_ledger_entries[i+1].stock_value) - \
- flt(sle.stock_value)
- return buying_amount
+ (sle.voucher_detail_no == item_row or (sle.voucher_type != "Stock Reconciliation"
+ and sle.item_code == item_code and sle.warehouse == warehouse and flt(sle.qty) == qty)):
+ # print "previous_sle", stock_ledger_entries[i+1]
+ # print "current sle", sle
+ previous_stock_value = len(stock_ledger_entries) > i+1 and \
+ flt(stock_ledger_entries[i+1].stock_value) or 0.0
+
+ buying_amount = previous_stock_value - flt(sle.stock_value)
+ return buying_amount
return 0.0
def get_sales_bom():