Optimisation of warehouse_account_map (#13454)

diff --git a/erpnext/accounts/doctype/account/test_account.py b/erpnext/accounts/doctype/account/test_account.py
index a4253e2..55383dc 100644
--- a/erpnext/accounts/doctype/account/test_account.py
+++ b/erpnext/accounts/doctype/account/test_account.py
@@ -101,7 +101,7 @@
 def get_inventory_account(company, warehouse=None):
 	account = None
 	if warehouse:
-		account = get_warehouse_account(warehouse, company)
+		account = get_warehouse_account(frappe.get_doc("Warehouse", warehouse))
 	else:
 		account = get_company_default_inventory_account(company)
 
diff --git a/erpnext/stock/__init__.py b/erpnext/stock/__init__.py
index e447415..8ef1415 100644
--- a/erpnext/stock/__init__.py
+++ b/erpnext/stock/__init__.py
@@ -15,33 +15,39 @@
 	if not frappe.flags.warehouse_account_map or frappe.flags.in_test:
 		warehouse_account = frappe._dict()
 
-		for d in frappe.get_all('Warehouse', filters = {"is_group": 0},
-			fields = ["name", "account", "parent_warehouse", "company"]):
+		for d in frappe.get_all('Warehouse',
+			fields = ["name", "account", "parent_warehouse", "company"],
+			order_by="lft, rgt"):
 			if not d.account:
-				d.account = get_warehouse_account(d.name, d.company)
+				d.account = get_warehouse_account(d, warehouse_account)
 
 			if d.account:
-				d.account_currency = frappe.db.get_value('Account', d.account, 'account_currency')
+				d.account_currency = frappe.db.get_value('Account', d.account, 'account_currency', cache=True)
 				warehouse_account.setdefault(d.name, d)
-			
+
 		frappe.flags.warehouse_account_map = warehouse_account
+
 	return frappe.flags.warehouse_account_map
 
-def get_warehouse_account(warehouse, company):
-	lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
-	account = frappe.db.sql("""
-		select
-			account from `tabWarehouse`
-		where
-			lft <= %s and rgt >= %s and company = %s
-			and account is not null and ifnull(account, '') !=''
-		order by lft desc limit 1""", (lft, rgt, company), as_list=1)
+def get_warehouse_account(warehouse, warehouse_account=None):
+	account = warehouse.account
+	if not account and warehouse.parent_warehouse:
+		if warehouse_account:
+			account = warehouse_account.get(warehouse.parent_warehouse).account
+		else:
+			account = frappe.db.sql("""
+				select
+					account from `tabWarehouse`
+				where
+					lft <= %s and rgt >= %s and company = %s
+					and account is not null and ifnull(account, '') !=''
+				order by lft desc limit 1""", (warehouse.lft, warehouse.rgt, warehouse.company), as_list=1)
 
-	account = account[0][0] if account else None
-	
+			account = account[0][0] if account else None
+
 	if not account:
-		account = get_company_default_inventory_account(company)
-	
+		account = get_company_default_inventory_account(warehouse.company)
+
 	return account
 	
 def get_company_default_inventory_account(company):
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 0eee6ba..9c47f98 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -3,7 +3,7 @@
 
 from __future__ import unicode_literals
 import frappe, erpnext
-from frappe.utils import cint, validate_email_add
+from frappe.utils import cint
 from frappe import throw, _
 from frappe.utils.nestedset import NestedSet
 from erpnext.stock import get_warehouse_account
@@ -22,7 +22,7 @@
 
 	def onload(self):
 		'''load account name for General Ledger Report'''
-		account = self.account or get_warehouse_account(self.name, self.company)
+		account = self.account or get_warehouse_account(self)
 
 		if account:
 			self.set_onload('account', account)