[optimization] [minor] pass filtered stock ledger entries to get_buying_amount
diff --git a/accounts/report/gross_profit/gross_profit.py b/accounts/report/gross_profit/gross_profit.py
index dcef5b8..3aba234 100644
--- a/accounts/report/gross_profit/gross_profit.py
+++ b/accounts/report/gross_profit/gross_profit.py
@@ -10,9 +10,7 @@
 	if not filters: filters = {}
 	
 	stock_ledger_entries = get_stock_ledger_entries(filters)
-	
 	source = get_source_data(filters)
-	
 	item_sales_bom = get_item_sales_bom()
 	
 	columns = ["Delivery Note/Sales Invoice::120", "Link::30", "Posting Date:Date", "Posting Time", 
@@ -20,12 +18,12 @@
 		"Qty:Float", "Selling Rate:Currency", "Avg. Buying Rate:Currency", 
 		"Selling Amount:Currency", "Buying Amount:Currency",
 		"Gross Profit:Currency", "Gross Profit %:Percent", "Project:Link/Project"]
-	
 	data = []
 	for row in source:
 		selling_amount = flt(row.amount)
-		buying_amount = get_buying_amount(row.item_code, row.warehouse, -1*row.qty, 
-			row.parenttype, row.name, row.item_row, stock_ledger_entries, 
+
+		buying_amount = get_buying_amount(row.item_code, row.parenttype, row.name, row.item_row,
+			stock_ledger_entries.get((row.item_code, row.warehouse), []), 
 			item_sales_bom.get(row.parenttype, {}).get(row.name, webnotes._dict()))
 		
 		buying_amount = buying_amount > 0 and buying_amount or 0
@@ -56,8 +54,17 @@
 		query += """ and company=%(company)s"""
 	
 	query += " order by item_code desc, warehouse desc, posting_date desc, posting_time desc, name desc"
+	
+	res = webnotes.conn.sql(query, filters, as_dict=True)
+	
+	out = {}
+	for r in res:
+		if (r.item_code, r.warehouse) not in out:
+			out[(r.item_code, r.warehouse)] = []
+		
+		out[(r.item_code, r.warehouse)].append(r)
 
-	return webnotes.conn.sql(query, filters, as_dict=True)
+	return out
 	
 def get_item_sales_bom():
 	item_sales_bom = {}
diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py
index eb2e9ef..033ac83 100644
--- a/controllers/selling_controller.py
+++ b/controllers/selling_controller.py
@@ -103,8 +103,8 @@
 			for item in self.doclist.get({"parentfield": self.fname}):
 				if item.item_code in self.stock_items or \
 						(item_sales_bom and item_sales_bom.get(item.item_code)):
-					buying_amount = get_buying_amount(item.item_code, item.warehouse, -1*item.qty, 
-						self.doc.doctype, self.doc.name, item.name, stock_ledger_entries, 
+					buying_amount = get_buying_amount(item.item_code, self.doc.doctype, self.doc.name, item.name, 
+						stock_ledger_entries.get((item.item_code, item.warehouse), []), 
 						item_sales_bom)
 					
 					item.buying_amount = buying_amount >= 0.01 and buying_amount or 0
diff --git a/controllers/stock_controller.py b/controllers/stock_controller.py
index 8384973..1aeca1b 100644
--- a/controllers/stock_controller.py
+++ b/controllers/stock_controller.py
@@ -38,11 +38,13 @@
 			return gl_entries
 		
 	def get_stock_ledger_entries(self, item_list=None, warehouse_list=None):
+		out = {}
+		
 		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,
+			res = 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 
@@ -51,6 +53,14 @@
 				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)
+				
+			for r in res:
+				if (r.item_code, r.warehouse) not in out:
+					out[(r.item_code, r.warehouse)] = []
+		
+				out[(r.item_code, r.warehouse)].append(r)
+
+		return out
 
 	def get_distinct_item_warehouse(self):
 		item_list = []
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 4a78421..3fda3ba 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -112,5 +112,4 @@
 		where Key_name="posting_sort_index" """):
 		webnotes.conn.commit()
 		webnotes.conn.sql("""alter table `tabStock Ledger Entry` 
-			add index posting_sort_index(posting_date, posting_time, name)""")
-		webnotes.conn.begin()
\ No newline at end of file
+			add index posting_sort_index(posting_date, posting_time, name)""")
\ No newline at end of file
diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.py b/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 36f872e..dbe2d2a 100644
--- a/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -290,9 +290,8 @@
 		
 		self.doc.stock_value_difference = 0.0
 		for d in self.entries:
-			self.doc.stock_value_difference -= get_buying_amount(d.item_code, d.warehouse, 
-				d.actual_qty, self.doc.doctype, self.doc.name, d.voucher_detail_no, 
-				stock_ledger_entries)
+			self.doc.stock_value_difference -= get_buying_amount(d.item_code, self.doc.doctype, self.doc.name,
+				d.voucher_detail_no, stock_ledger_entries.get((d.item_code, d.warehouse), []))
 		webnotes.conn.set(self.doc, "stock_value_difference", self.doc.stock_value_difference)
 		
 	def make_gl_entries(self):
diff --git a/stock/utils.py b/stock/utils.py
index d53d271..96eeef6 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -152,32 +152,28 @@
 				wlist.append([w])
 	return wlist
 
-def get_buying_amount(item_code, warehouse, qty, voucher_type, voucher_no, voucher_detail_no, 
+def get_buying_amount(item_code, voucher_type, voucher_no, voucher_detail_no, 
 		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]:
 			if bom_item.get("parent_detail_docname")==voucher_detail_no:
-				buying_amount += _get_buying_amount(voucher_type, voucher_no, voucher_detail_no,
-					bom_item.item_code, bom_item.warehouse or warehouse, 
-					bom_item.total_qty or (bom_item.qty * qty), stock_ledger_entries)
+				buying_amount += _get_buying_amount(voucher_type, voucher_no, voucher_detail_no, stock_ledger_entries)
 		return buying_amount
 	else:
 		# doesn't have sales bom
-		return _get_buying_amount(voucher_type, voucher_no, voucher_detail_no, 
-			item_code, warehouse, qty, stock_ledger_entries)
+		return _get_buying_amount(voucher_type, voucher_no, voucher_detail_no, stock_ledger_entries)
 		
-def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, qty, 
-		stock_ledger_entries):
-	relevant_stock_ledger_entries = [sle for sle in stock_ledger_entries 
-		if sle.item_code == item_code and sle.warehouse == warehouse]
-		
-	for i, sle in enumerate(relevant_stock_ledger_entries):
+def _get_buying_amount(voucher_type, voucher_no, item_row, stock_ledger_entries):
+	# IMP NOTE
+	# stock_ledger_entries should already be filtered by item_code and warehouse and 
+	# sorted by posting_date desc, posting_time desc
+	for i, sle in enumerate(stock_ledger_entries):
 		if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
 			sle.voucher_detail_no == item_row:
-				previous_stock_value = len(relevant_stock_ledger_entries) > i+1 and \
-					flt(relevant_stock_ledger_entries[i+1].stock_value) or 0.0
+				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)