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():