Merge branch 'develop' into perf-fix-get-cached-value-for-accounts
diff --git a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
index fefec0e..f091a4f 100644
--- a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
+++ b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
@@ -76,7 +76,7 @@
 
 def build_result(account, dates, gl_entries):
 	result = [[getdate(date), 0.0] for date in dates]
-	root_type = frappe.db.get_value("Account", account, "root_type")
+	root_type = frappe.get_cached_value("Account", account, "root_type")
 
 	# start with the first date
 	date_index = 0
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index 9dff116..ec0ba08 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -58,7 +58,7 @@
 	def validate_parent(self):
 		"""Fetch Parent Details and validate parent account"""
 		if self.parent_account:
-			par = frappe.db.get_value(
+			par = frappe.get_cached_value(
 				"Account", self.parent_account, ["name", "is_group", "company"], as_dict=1
 			)
 			if not par:
@@ -82,7 +82,7 @@
 
 	def set_root_and_report_type(self):
 		if self.parent_account:
-			par = frappe.db.get_value(
+			par = frappe.get_cached_value(
 				"Account", self.parent_account, ["report_type", "root_type"], as_dict=1
 			)
 
@@ -92,7 +92,7 @@
 				self.root_type = par.root_type
 
 		if self.is_group:
-			db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1)
+			db_value = self.get_doc_before_save()
 			if db_value:
 				if self.report_type != db_value.report_type:
 					frappe.db.sql(
@@ -111,13 +111,13 @@
 			)
 
 	def validate_root_details(self):
-		# does not exists parent
-		if frappe.db.exists("Account", self.name):
-			if not frappe.db.get_value("Account", self.name, "parent_account"):
-				throw(_("Root cannot be edited."), RootNotEditable)
+		doc_before_save = self.get_doc_before_save()
+
+		if doc_before_save and not doc_before_save.parent_account:
+			throw(_("Root cannot be edited."), RootNotEditable)
 
 		if not self.parent_account and not self.is_group:
-			frappe.throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
+			throw(_("The root account {0} must be a group").format(frappe.bold(self.name)))
 
 	def validate_root_company_and_sync_account_to_children(self):
 		# ignore validation while creating new compnay or while syncing to child companies
@@ -127,7 +127,9 @@
 			return
 		ancestors = get_root_company(self.company)
 		if ancestors:
-			if frappe.get_value("Company", self.company, "allow_account_creation_against_child_company"):
+			if frappe.get_cached_value(
+				"Company", self.company, "allow_account_creation_against_child_company"
+			):
 				return
 			if not frappe.db.get_value(
 				"Account", {"account_name": self.account_name, "company": ancestors[0]}, "name"
@@ -138,7 +140,7 @@
 			if not descendants:
 				return
 			parent_acc_name_map = {}
-			parent_acc_name, parent_acc_number = frappe.db.get_value(
+			parent_acc_name, parent_acc_number = frappe.get_cached_value(
 				"Account", self.parent_account, ["account_name", "account_number"]
 			)
 			filters = {
@@ -159,27 +161,28 @@
 			self.create_account_for_child_company(parent_acc_name_map, descendants, parent_acc_name)
 
 	def validate_group_or_ledger(self):
-		if self.get("__islocal"):
+		doc_before_save = self.get_doc_before_save()
+		if not doc_before_save or cint(doc_before_save.is_group) == cint(self.is_group):
 			return
 
-		existing_is_group = frappe.db.get_value("Account", self.name, "is_group")
-		if cint(self.is_group) != cint(existing_is_group):
-			if self.check_gle_exists():
-				throw(_("Account with existing transaction cannot be converted to ledger"))
-			elif self.is_group:
-				if self.account_type and not self.flags.exclude_account_type_check:
-					throw(_("Cannot covert to Group because Account Type is selected."))
-			elif self.check_if_child_exists():
-				throw(_("Account with child nodes cannot be set as ledger"))
+		if self.check_gle_exists():
+			throw(_("Account with existing transaction cannot be converted to ledger"))
+		elif self.is_group:
+			if self.account_type and not self.flags.exclude_account_type_check:
+				throw(_("Cannot covert to Group because Account Type is selected."))
+		elif self.check_if_child_exists():
+			throw(_("Account with child nodes cannot be set as ledger"))
 
 	def validate_frozen_accounts_modifier(self):
-		old_value = frappe.db.get_value("Account", self.name, "freeze_account")
-		if old_value and old_value != self.freeze_account:
-			frozen_accounts_modifier = frappe.db.get_value(
-				"Accounts Settings", None, "frozen_accounts_modifier"
-			)
-			if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles():
-				throw(_("You are not authorized to set Frozen value"))
+		doc_before_save = self.get_doc_before_save()
+		if not doc_before_save or doc_before_save.freeze_account == self.freeze_account:
+			return
+
+		frozen_accounts_modifier = frappe.get_cached_value(
+			"Accounts Settings", "Accounts Settings", "frozen_accounts_modifier"
+		)
+		if not frozen_accounts_modifier or frozen_accounts_modifier not in frappe.get_roles():
+			throw(_("You are not authorized to set Frozen value"))
 
 	def validate_balance_must_be_debit_or_credit(self):
 		from erpnext.accounts.utils import get_balance_on
@@ -223,9 +226,9 @@
 				)
 
 			# validate if parent of child company account to be added is a group
-			if frappe.db.get_value("Account", self.parent_account, "is_group") and not frappe.db.get_value(
-				"Account", parent_acc_name_map[company], "is_group"
-			):
+			if frappe.get_cached_value(
+				"Account", self.parent_account, "is_group"
+			) and not frappe.get_cached_value("Account", parent_acc_name_map[company], "is_group"):
 				msg = _(
 					"While creating account for Child Company {0}, parent account {1} found as a ledger account."
 				).format(company_bold, parent_acc_name_bold)
@@ -377,17 +380,15 @@
 
 @frappe.whitelist()
 def update_account_number(name, account_name, account_number=None, from_descendant=False):
-	account = frappe.db.get_value("Account", name, "company", as_dict=True)
+	account = frappe.get_cached_doc("Account", name)
 	if not account:
 		return
 
-	old_acc_name, old_acc_number = frappe.db.get_value(
-		"Account", name, ["account_name", "account_number"]
-	)
+	old_acc_name, old_acc_number = account.account_name, account.account_number
 
 	# check if account exists in parent company
 	ancestors = get_ancestors_of("Company", account.company)
-	allow_independent_account_creation = frappe.get_value(
+	allow_independent_account_creation = frappe.get_cached_value(
 		"Company", account.company, "allow_account_creation_against_child_company"
 	)
 
@@ -435,22 +436,24 @@
 @frappe.whitelist()
 def merge_account(old, new, is_group, root_type, company):
 	# Validate properties before merging
-	if not frappe.db.exists("Account", new):
+	new_account = frappe.get_cached_doc("Account", new)
+
+	if not new_account:
 		throw(_("Account {0} does not exist").format(new))
 
-	val = list(frappe.db.get_value("Account", new, ["is_group", "root_type", "company"]))
-
-	if val != [cint(is_group), root_type, company]:
+	if (new_account.is_group, new_account.root_type, new_account.company) != (
+		cint(is_group),
+		root_type,
+		company,
+	):
 		throw(
 			_(
 				"""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""
 			)
 		)
 
-	if is_group and frappe.db.get_value("Account", new, "parent_account") == old:
-		frappe.db.set_value(
-			"Account", new, "parent_account", frappe.db.get_value("Account", old, "parent_account")
-		)
+	if is_group and new_account.parent_account == old:
+		new_account.db_set("parent_account", frappe.get_cached_value("Account", old, "parent_account"))
 
 	frappe.rename_doc("Account", old, new, merge=1, force=1)
 
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
index 947b485..75f8f06 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/chart_of_accounts.py
@@ -53,7 +53,7 @@
 							"account_number": account_number,
 							"account_type": child.get("account_type"),
 							"account_currency": child.get("account_currency")
-							or frappe.db.get_value("Company", company, "default_currency"),
+							or frappe.get_cached_value("Company", company, "default_currency"),
 							"tax_rate": child.get("tax_rate"),
 						}
 					)
@@ -148,7 +148,7 @@
 			) or frappe.local.flags.allow_unverified_charts:
 				charts.append(content["name"])
 
-	country_code = frappe.db.get_value("Country", country, "code")
+	country_code = frappe.get_cached_value("Country", country, "code")
 	if country_code:
 		folders = ("verified",)
 		if frappe.local.flags.allow_unverified_charts:
diff --git a/erpnext/accounts/doctype/bank_account/bank_account.py b/erpnext/accounts/doctype/bank_account/bank_account.py
index addcf62..b91f0f9 100644
--- a/erpnext/accounts/doctype/bank_account/bank_account.py
+++ b/erpnext/accounts/doctype/bank_account/bank_account.py
@@ -77,6 +77,6 @@
 
 @frappe.whitelist()
 def get_bank_account_details(bank_account):
-	return frappe.db.get_value(
+	return frappe.get_cached_value(
 		"Bank Account", bank_account, ["account", "bank", "bank_account_no"], as_dict=1
 	)
diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
index cc3727c..d353270 100644
--- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
+++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
@@ -57,7 +57,7 @@
 @frappe.whitelist()
 def get_account_balance(bank_account, till_date):
 	# returns account balance till the specified date
-	account = frappe.db.get_value("Bank Account", bank_account, "account")
+	account = frappe.get_cached_value("Bank Account", bank_account, "account")
 	filters = frappe._dict(
 		{"account": account, "report_date": till_date, "include_pos_transactions": 1}
 	)
@@ -130,8 +130,10 @@
 		fieldname=["name", "deposit", "withdrawal", "bank_account"],
 		as_dict=True,
 	)[0]
-	company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
-	account_type = frappe.db.get_value("Account", second_account, "account_type")
+	company_account = frappe.get_cached_value(
+		"Bank Account", bank_transaction.bank_account, "account"
+	)
+	account_type = frappe.get_cached_value("Account", second_account, "account_type")
 	if account_type in ["Receivable", "Payable"]:
 		if not (party_type and party):
 			frappe.throw(
@@ -164,7 +166,7 @@
 		}
 	)
 
-	company = frappe.get_value("Account", company_account, "company")
+	company = frappe.get_cached_value("Account", company_account, "company")
 
 	journal_entry_dict = {
 		"voucher_type": entry_type,
@@ -219,8 +221,10 @@
 	paid_amount = bank_transaction.unallocated_amount
 	payment_type = "Receive" if bank_transaction.deposit > 0 else "Pay"
 
-	company_account = frappe.get_value("Bank Account", bank_transaction.bank_account, "account")
-	company = frappe.get_value("Account", company_account, "company")
+	company_account = frappe.get_cached_value(
+		"Bank Account", bank_transaction.bank_account, "account"
+	)
+	company = frappe.get_cached_value("Account", company_account, "company")
 	payment_entry_dict = {
 		"company": company,
 		"payment_type": payment_type,
@@ -266,7 +270,7 @@
 	# updated clear date of all the vouchers based on the bank transaction
 	vouchers = json.loads(vouchers)
 	transaction = frappe.get_doc("Bank Transaction", bank_transaction_name)
-	company_account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
+	company_account = frappe.get_cached_value("Bank Account", transaction.bank_account, "account")
 
 	if transaction.unallocated_amount == 0:
 		frappe.throw(_("This bank transaction is already fully reconciled"))
@@ -290,7 +294,7 @@
 				"The sum total of amounts of all selected vouchers should be less than the unallocated amount of the bank transaction"
 			)
 		)
-	account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
+	account = frappe.get_cached_value("Bank Account", transaction.bank_account, "account")
 
 	for voucher in vouchers:
 		gl_entry = frappe.db.get_value(
diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
index 372c53d..efb9d8c 100644
--- a/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
+++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction_upload.py
@@ -74,7 +74,7 @@
 
 
 def get_bank_mapping(bank_account):
-	bank_name = frappe.db.get_value("Bank Account", bank_account, "bank")
+	bank_name = frappe.get_cached_value("Bank Account", bank_account, "bank")
 	bank = frappe.get_doc("Bank", bank_name)
 
 	mapping = {row.file_field: row.bank_transaction_field for row in bank.bank_transaction_mapping}
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 637ac7a..53838fb 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -59,7 +59,7 @@
 		account_list = []
 		for d in self.get("accounts"):
 			if d.account:
-				account_details = frappe.db.get_value(
+				account_details = frappe.get_cached_value(
 					"Account", d.account, ["is_group", "company", "report_type"], as_dict=1
 				)
 
@@ -306,7 +306,7 @@
 
 	if args.get("fiscal_year"):
 		date_field = "schedule_date" if for_doc == "Material Request" else "transaction_date"
-		start_date, end_date = frappe.db.get_value(
+		start_date, end_date = frappe.get_cached_value(
 			"Fiscal Year", args.get("fiscal_year"), ["year_start_date", "year_end_date"]
 		)
 
@@ -379,7 +379,7 @@
 		):
 			distribution.setdefault(d.month, d.percentage_allocation)
 
-	dt = frappe.db.get_value("Fiscal Year", fiscal_year, "year_start_date")
+	dt = frappe.get_cached_value("Fiscal Year", fiscal_year, "year_start_date")
 	accumulated_percentage = 0.0
 
 	while dt <= getdate(posting_date):
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index 83c206a..325a356 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -45,8 +45,8 @@
 
 @frappe.whitelist()
 def validate_company(company):
-	parent_company, allow_account_creation_against_child_company = frappe.db.get_value(
-		"Company", {"name": company}, ["parent_company", "allow_account_creation_against_child_company"]
+	parent_company, allow_account_creation_against_child_company = frappe.get_cached_value(
+		"Company", company, ["parent_company", "allow_account_creation_against_child_company"]
 	)
 
 	if parent_company and (not allow_account_creation_against_child_company):
diff --git a/erpnext/accounts/doctype/dunning/dunning.py b/erpnext/accounts/doctype/dunning/dunning.py
index 9874d66..331adb4 100644
--- a/erpnext/accounts/doctype/dunning/dunning.py
+++ b/erpnext/accounts/doctype/dunning/dunning.py
@@ -19,7 +19,7 @@
 		self.validate_overdue_days()
 		self.validate_amount()
 		if not self.income_account:
-			self.income_account = frappe.db.get_value("Company", self.company, "default_income_account")
+			self.income_account = frappe.get_cached_value("Company", self.company, "default_income_account")
 
 	def validate_overdue_days(self):
 		self.overdue_days = (getdate(self.posting_date) - getdate(self.due_date)).days or 0
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
index 2f81c5f..03d0e49 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation/exchange_rate_revaluation.py
@@ -222,7 +222,7 @@
 
 @frappe.whitelist()
 def get_account_details(account, company, posting_date, party_type=None, party=None):
-	account_currency, account_type = frappe.db.get_value(
+	account_currency, account_type = frappe.get_cached_value(
 		"Account", account, ["account_currency", "account_type"]
 	)
 	if account_type in ["Receivable", "Payable"] and not (party_type and party):
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
index 069ab5e..4592421 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
@@ -170,4 +170,4 @@
 
 def get_from_and_to_date(fiscal_year):
 	fields = ["year_start_date as from_date", "year_end_date as to_date"]
-	return frappe.db.get_value("Fiscal Year", fiscal_year, fields, as_dict=1)
+	return frappe.get_cached_value("Fiscal Year", fiscal_year, fields, as_dict=1)
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 7227b95..f312048 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -58,7 +58,7 @@
 			validate_balance_type(self.account, adv_adj)
 			validate_frozen_account(self.account, adv_adj)
 
-			if frappe.db.get_value("Account", self.account, "account_type") not in [
+			if frappe.get_cached_value("Account", self.account, "account_type") not in [
 				"Receivable",
 				"Payable",
 			]:
@@ -120,7 +120,7 @@
 			frappe.throw(msg, title=_("Missing Cost Center"))
 
 	def validate_dimensions_for_pl_and_bs(self):
-		account_type = frappe.db.get_value("Account", self.account, "report_type")
+		account_type = frappe.get_cached_value("Account", self.account, "report_type")
 
 		for dimension in get_checks_for_pl_and_bs_accounts():
 			if (
@@ -188,7 +188,7 @@
 	def check_pl_account(self):
 		if (
 			self.is_opening == "Yes"
-			and frappe.db.get_value("Account", self.account, "report_type") == "Profit and Loss"
+			and frappe.get_cached_value("Account", self.account, "report_type") == "Profit and Loss"
 			and not self.is_cancelled
 		):
 			frappe.throw(
@@ -281,7 +281,7 @@
 
 def validate_balance_type(account, adv_adj=False):
 	if not adv_adj and account:
-		balance_must_be = frappe.db.get_value("Account", account, "balance_must_be")
+		balance_must_be = frappe.get_cached_value("Account", account, "balance_must_be")
 		if balance_must_be:
 			balance = frappe.db.sql(
 				"""select sum(debit) - sum(credit)
diff --git a/erpnext/accounts/doctype/item_tax_template/item_tax_template.py b/erpnext/accounts/doctype/item_tax_template/item_tax_template.py
index 23f36ec..7e2fca8 100644
--- a/erpnext/accounts/doctype/item_tax_template/item_tax_template.py
+++ b/erpnext/accounts/doctype/item_tax_template/item_tax_template.py
@@ -21,7 +21,7 @@
 		check_list = []
 		for d in self.get("taxes"):
 			if d.tax_type:
-				account_type = frappe.db.get_value("Account", d.tax_type, "account_type")
+				account_type = frappe.get_cached_value("Account", d.tax_type, "account_type")
 
 				if account_type not in [
 					"Tax",
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index de012b2..1714fff 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -319,7 +319,7 @@
 
 	def validate_party(self):
 		for d in self.get("accounts"):
-			account_type = frappe.db.get_value("Account", d.account, "account_type")
+			account_type = frappe.get_cached_value("Account", d.account, "account_type")
 			if account_type in ["Receivable", "Payable"]:
 				if not (d.party_type and d.party):
 					frappe.throw(
@@ -382,7 +382,7 @@
 	def validate_against_jv(self):
 		for d in self.get("accounts"):
 			if d.reference_type == "Journal Entry":
-				account_root_type = frappe.db.get_value("Account", d.account, "root_type")
+				account_root_type = frappe.get_cached_value("Account", d.account, "root_type")
 				if account_root_type == "Asset" and flt(d.debit) > 0:
 					frappe.throw(
 						_(
@@ -631,7 +631,7 @@
 	def validate_multi_currency(self):
 		alternate_currency = []
 		for d in self.get("accounts"):
-			account = frappe.db.get_value(
+			account = frappe.get_cached_value(
 				"Account", d.account, ["account_currency", "account_type"], as_dict=1
 			)
 			if account:
@@ -762,7 +762,7 @@
 					party_amount += d.debit_in_account_currency or d.credit_in_account_currency
 					party_account_currency = d.account_currency
 
-			elif frappe.db.get_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
+			elif frappe.get_cached_value("Account", d.account, "account_type") in ["Bank", "Cash"]:
 				bank_amount += d.debit_in_account_currency or d.credit_in_account_currency
 				bank_account_currency = d.account_currency
 
@@ -987,7 +987,7 @@
 					account = account_list[0].name
 
 	if account:
-		account_details = frappe.db.get_value(
+		account_details = frappe.get_cached_value(
 			"Account", account, ["account_currency", "account_type"], as_dict=1
 		)
 
@@ -1116,7 +1116,7 @@
 			"party_type": args.get("party_type"),
 			"party": ref_doc.get(args.get("party_type").lower()),
 			"cost_center": cost_center,
-			"account_type": frappe.db.get_value("Account", args.get("party_account"), "account_type"),
+			"account_type": frappe.get_cached_value("Account", args.get("party_account"), "account_type"),
 			"account_currency": args.get("party_account_currency")
 			or get_account_currency(args.get("party_account")),
 			"balance": get_balance_on(args.get("party_account")),
@@ -1283,7 +1283,7 @@
 		"account": account,
 		"balance": account_balance,
 		"party_balance": party_balance,
-		"account_currency": frappe.db.get_value("Account", account, "account_currency"),
+		"account_currency": frappe.get_cached_value("Account", account, "account_currency"),
 	}
 
 
@@ -1296,7 +1296,7 @@
 		frappe.msgprint(_("No Permission"), raise_exception=1)
 
 	company_currency = erpnext.get_company_currency(company)
-	account_details = frappe.db.get_value(
+	account_details = frappe.get_cached_value(
 		"Account", account, ["account_type", "account_currency"], as_dict=1
 	)
 
@@ -1349,7 +1349,7 @@
 ):
 	from erpnext.setup.utils import get_exchange_rate
 
-	account_details = frappe.db.get_value(
+	account_details = frappe.get_cached_value(
 		"Account", account, ["account_type", "root_type", "account_currency", "company"], as_dict=1
 	)
 
diff --git a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py
index ed35d1e..7d6ef3c 100644
--- a/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py
+++ b/erpnext/accounts/doctype/mode_of_payment/mode_of_payment.py
@@ -25,7 +25,7 @@
 	def validate_accounts(self):
 		for entry in self.accounts:
 			"""Error when Company of Ledger account doesn't match with Company Selected"""
-			if frappe.db.get_value("Account", entry.default_account, "company") != entry.company:
+			if frappe.get_cached_value("Account", entry.default_account, "company") != entry.company:
 				frappe.throw(
 					_("Account {0} does not match with Company {1} in Mode of Account: {2}").format(
 						entry.default_account, entry.company, self.name
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 51b134a..9354e44 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -725,7 +725,7 @@
 
 	def validate_transaction_reference(self):
 		bank_account = self.paid_to if self.payment_type == "Receive" else self.paid_from
-		bank_account_type = frappe.db.get_value("Account", bank_account, "account_type")
+		bank_account_type = frappe.get_cached_value("Account", bank_account, "account_type")
 
 		if bank_account_type == "Bank":
 			if not self.reference_no or not self.reference_date:
@@ -1303,7 +1303,7 @@
 				d.voucher_type, d.voucher_no, "payment_terms_template"
 			)
 			if payment_term_template:
-				allocate_payment_based_on_payment_terms = frappe.db.get_value(
+				allocate_payment_based_on_payment_terms = frappe.get_cached_value(
 					"Payment Terms Template", payment_term_template, "allocate_payment_based_on_payment_terms"
 				)
 				if allocate_payment_based_on_payment_terms:
@@ -1535,7 +1535,7 @@
 		{
 			"account_currency": get_account_currency(account),
 			"account_balance": account_balance,
-			"account_type": frappe.db.get_value("Account", account, "account_type"),
+			"account_type": frappe.get_cached_value("Account", account, "account_type"),
 		}
 	)
 
@@ -1704,9 +1704,9 @@
 	if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
 		frappe.msgprint(_("{0} is on hold till {1}").format(doc.name, doc.release_date))
 	else:
-		if doc.doctype in ("Sales Invoice", "Purchase Invoice") and frappe.get_value(
+		if doc.doctype in ("Sales Invoice", "Purchase Invoice") and frappe.get_cached_value(
 			"Payment Terms Template",
-			{"name": doc.payment_terms_template},
+			doc.payment_terms_template,
 			"allocate_payment_based_on_payment_terms",
 		):
 
diff --git a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
index ab47b61..791de25 100644
--- a/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
+++ b/erpnext/accounts/doctype/payment_gateway_account/payment_gateway_account.py
@@ -11,7 +11,7 @@
 		self.name = self.payment_gateway + " - " + self.currency
 
 	def validate(self):
-		self.currency = frappe.db.get_value("Account", self.payment_account, "account_currency")
+		self.currency = frappe.get_cached_value("Account", self.payment_account, "account_currency")
 
 		self.update_default_payment_gateway()
 		self.set_as_default_if_not_set()
diff --git a/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py b/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py
index bcbcb67..58691ab 100644
--- a/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py
+++ b/erpnext/accounts/doctype/payment_ledger_entry/payment_ledger_entry.py
@@ -97,7 +97,7 @@
 						)
 
 	def validate_dimensions_for_pl_and_bs(self):
-		account_type = frappe.db.get_value("Account", self.account, "report_type")
+		account_type = frappe.get_cached_value("Account", self.account, "report_type")
 
 		for dimension in get_checks_for_pl_and_bs_accounts():
 			if (
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py
index 29c4978..8665b70 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.py
+++ b/erpnext/accounts/doctype/payment_request/payment_request.py
@@ -53,7 +53,7 @@
 
 	def validate_currency(self):
 		ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
-		if self.payment_account and ref_doc.currency != frappe.db.get_value(
+		if self.payment_account and ref_doc.currency != frappe.get_cached_value(
 			"Account", self.payment_account, "account_currency"
 		):
 			frappe.throw(_("Transaction currency must be same as Payment Gateway currency"))
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
index 866a94d..ca98bee 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
@@ -43,7 +43,7 @@
 			make_reverse_gl_entries(voucher_type="Period Closing Voucher", voucher_no=self.name)
 
 	def validate_account_head(self):
-		closing_account_type = frappe.db.get_value("Account", self.closing_account_head, "root_type")
+		closing_account_type = frappe.get_cached_value("Account", self.closing_account_head, "root_type")
 
 		if closing_account_type not in ["Liability", "Equity"]:
 			frappe.throw(
diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
index 54a3e93..b543016 100644
--- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
+++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py
@@ -335,7 +335,8 @@
 		if (
 			self.change_amount
 			and self.account_for_change_amount
-			and frappe.db.get_value("Account", self.account_for_change_amount, "company") != self.company
+			and frappe.get_cached_value("Account", self.account_for_change_amount, "company")
+			!= self.company
 		):
 			frappe.throw(
 				_("The selected change account {} doesn't belongs to Company {}.").format(
@@ -486,7 +487,7 @@
 				customer_price_list, customer_group, customer_currency = frappe.db.get_value(
 					"Customer", self.customer, ["default_price_list", "customer_group", "default_currency"]
 				)
-				customer_group_price_list = frappe.db.get_value(
+				customer_group_price_list = frappe.get_cached_value(
 					"Customer Group", customer_group, "default_price_list"
 				)
 				selling_price_list = (
@@ -532,8 +533,8 @@
 
 		if not self.debit_to:
 			self.debit_to = get_party_account("Customer", self.customer, self.company)
-			self.party_account_currency = frappe.db.get_value(
-				"Account", self.debit_to, "account_currency", cache=True
+			self.party_account_currency = frappe.get_cached_value(
+				"Account", self.debit_to, "account_currency"
 			)
 		if not self.due_date and self.customer:
 			self.due_date = get_due_date(self.posting_date, "Customer", self.customer, self.company)
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 9a31aaf..f3105e3 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -153,8 +153,8 @@
 	def set_missing_values(self, for_validate=False):
 		if not self.credit_to:
 			self.credit_to = get_party_account("Supplier", self.supplier, self.company)
-			self.party_account_currency = frappe.db.get_value(
-				"Account", self.credit_to, "account_currency", cache=True
+			self.party_account_currency = frappe.get_cached_value(
+				"Account", self.credit_to, "account_currency"
 			)
 		if not self.due_date:
 			self.due_date = get_due_date(
@@ -175,7 +175,7 @@
 			if not self.credit_to:
 				self.raise_missing_debit_credit_account_error("Supplier", self.supplier)
 
-		account = frappe.db.get_value(
+		account = frappe.get_cached_value(
 			"Account", self.credit_to, ["account_type", "report_type", "account_currency"], as_dict=True
 		)
 
@@ -673,7 +673,7 @@
 		exchange_rate_map, net_rate_map = get_purchase_document_details(self)
 
 		provisional_accounting_for_non_stock_items = cint(
-			frappe.db.get_value(
+			frappe.get_cached_value(
 				"Company", self.company, "enable_provisional_accounting_for_non_stock_items"
 			)
 		)
@@ -984,7 +984,7 @@
 				asset_amount = flt(item.net_amount) + flt(item.item_tax_amount / self.conversion_rate)
 				base_asset_amount = flt(item.base_net_amount + item.item_tax_amount)
 
-				item_exp_acc_type = frappe.db.get_value("Account", item.expense_account, "account_type")
+				item_exp_acc_type = frappe.get_cached_value("Account", item.expense_account, "account_type")
 				if not item.expense_account or item_exp_acc_type not in [
 					"Asset Received But Not Billed",
 					"Fixed Asset",
diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
index d9009ba..a3a5d62 100644
--- a/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
+++ b/erpnext/accounts/doctype/sales_taxes_and_charges_template/sales_taxes_and_charges_template.py
@@ -27,7 +27,7 @@
 	def set_missing_values(self):
 		for data in self.taxes:
 			if data.charge_type == "On Net Total" and flt(data.rate) == 0.0:
-				data.rate = frappe.db.get_value("Account", data.account_head, "tax_rate")
+				data.rate = frappe.get_cached_value("Account", data.account_head, "tax_rate")
 
 
 def valdiate_taxes_and_charges_template(doc):
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 67cf644..baeed03 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -296,7 +296,7 @@
 		return party.default_price_list
 
 	if party.doctype == "Customer":
-		return frappe.db.get_value("Customer Group", party.customer_group, "default_price_list")
+		return frappe.get_cached_value("Customer Group", party.customer_group, "default_price_list")
 
 
 def set_price_list(party_details, party, party_type, given_price_list, pos=None):
@@ -385,7 +385,7 @@
 	existing_gle_currency = get_party_gle_currency(party_type, party, company)
 	if existing_gle_currency:
 		if account:
-			account_currency = frappe.db.get_value("Account", account, "account_currency", cache=True)
+			account_currency = frappe.get_cached_value("Account", account, "account_currency")
 		if (account and account_currency != existing_gle_currency) or not account:
 			account = get_party_gle_account(party_type, party, company)
 
@@ -402,7 +402,7 @@
 def get_party_account_currency(party_type, party, company):
 	def generator():
 		party_account = get_party_account(party_type, party, company)
-		return frappe.db.get_value("Account", party_account, "account_currency", cache=True)
+		return frappe.get_cached_value("Account", party_account, "account_currency")
 
 	return frappe.local_cache("party_account_currency", (party_type, party, company), generator)
 
@@ -474,15 +474,15 @@
 		else:
 			companies.append(account.company)
 
-		party_account_currency = frappe.db.get_value(
-			"Account", account.account, "account_currency", cache=True
-		)
+		party_account_currency = frappe.get_cached_value("Account", account.account, "account_currency")
 		if frappe.db.get_default("Company"):
 			company_default_currency = frappe.get_cached_value(
 				"Company", frappe.db.get_default("Company"), "default_currency"
 			)
 		else:
-			company_default_currency = frappe.db.get_value("Company", account.company, "default_currency")
+			company_default_currency = frappe.get_cached_value(
+				"Company", account.company, "default_currency"
+			)
 
 		validate_party_gle_currency(doc.doctype, doc.name, account.company, party_account_currency)
 
@@ -801,7 +801,7 @@
 	)
 
 	for d in companies:
-		company_default_currency = frappe.db.get_value("Company", d.company, "default_currency")
+		company_default_currency = frappe.get_cached_value("Company", d.company, "default_currency")
 		party_account_currency = get_party_account_currency(party_type, party, d.company)
 
 		if party_account_currency == company_default_currency:
diff --git a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py
index fbc1a69..b0a0e05 100644
--- a/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py
+++ b/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py
@@ -21,7 +21,7 @@
 	if not filters.get("account"):
 		return columns, []
 
-	account_currency = frappe.db.get_value("Account", filters.account, "account_currency")
+	account_currency = frappe.get_cached_value("Account", filters.account, "account_currency")
 
 	data = get_entries(filters)
 
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index 75e983a..d4f2011 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -180,7 +180,7 @@
 	filters = frappe._dict(filters or {})
 
 	if filters.include_default_book_entries:
-		company_fb = frappe.db.get_value("Company", company, "default_finance_book")
+		company_fb = frappe.get_cached_value("Company", company, "default_finance_book")
 		cond = """ AND (finance_book in (%s, %s, '') OR finance_book IS NULL)
 			""" % (
 			frappe.db.escape(filters.finance_book),
diff --git a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
index 330e442..e93fb61 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -641,7 +641,7 @@
 				"rgt": root_rgt,
 				"company": d.name,
 				"finance_book": filters.get("finance_book"),
-				"company_fb": frappe.db.get_value("Company", d.name, "default_finance_book"),
+				"company_fb": frappe.get_cached_value("Company", d.name, "default_finance_book"),
 			},
 			as_dict=True,
 		)
diff --git a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py
index cafe95b..6b0d3c9 100644
--- a/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py
+++ b/erpnext/accounts/report/customer_ledger_summary/customer_ledger_summary.py
@@ -220,8 +220,8 @@
 
 		if self.filters.party_type == "Customer":
 			if self.filters.get("customer_group"):
-				lft, rgt = frappe.db.get_value(
-					"Customer Group", self.filters.get("customer_group"), ["lft", "rgt"]
+				lft, rgt = frappe.get_cached_value(
+					"Customer Group", self.filters["customer_group"], ["lft", "rgt"]
 				)
 
 				conditions.append(
diff --git a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py
index ecad9f1..5939a26 100644
--- a/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py
+++ b/erpnext/accounts/report/dimension_wise_accounts_balance_report/dimension_wise_accounts_balance_report.py
@@ -90,7 +90,7 @@
 	gl_filters["dimensions"] = set(dimension_list)
 
 	if filters.get("include_default_book_entries"):
-		gl_filters["company_fb"] = frappe.db.get_value(
+		gl_filters["company_fb"] = frappe.get_cached_value(
 			"Company", filters.company, "default_finance_book"
 		)
 
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 3682577..8c6fe43 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -440,7 +440,7 @@
 		}
 
 		if filters.get("include_default_book_entries"):
-			gl_filters["company_fb"] = frappe.db.get_value("Company", company, "default_finance_book")
+			gl_filters["company_fb"] = frappe.get_cached_value("Company", company, "default_finance_book")
 
 		for key, value in filters.items():
 			if value:
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index 82f38da..f0167f1 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -174,7 +174,7 @@
 		order_by_statement = "order by account, posting_date, creation"
 
 	if filters.get("include_default_book_entries"):
-		filters["company_fb"] = frappe.db.get_value(
+		filters["company_fb"] = frappe.get_cached_value(
 			"Company", filters.get("company"), "default_finance_book"
 		)
 
@@ -286,9 +286,11 @@
 
 	all_accounts = []
 	for d in accounts:
-		if frappe.db.exists("Account", d):
-			lft, rgt = frappe.db.get_value("Account", d, ["lft", "rgt"])
-			children = frappe.get_all("Account", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
+		account = frappe.get_cached_doc("Account", d)
+		if account:
+			children = frappe.get_all(
+				"Account", filters={"lft": [">=", account.lft], "rgt": ["<=", account.rgt]}
+			)
 			all_accounts += [c.name for c in children]
 		else:
 			frappe.throw(_("Account: {0} does not exist").format(d))
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 6d2cd8e..3af01fd 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -38,7 +38,7 @@
 	if not filters.fiscal_year:
 		frappe.throw(_("Fiscal Year {0} is required").format(filters.fiscal_year))
 
-	fiscal_year = frappe.db.get_value(
+	fiscal_year = frappe.get_cached_value(
 		"Fiscal Year", filters.fiscal_year, ["year_start_date", "year_end_date"], as_dict=True
 	)
 	if not fiscal_year:
@@ -177,7 +177,7 @@
 		"year_start_date": filters.year_start_date,
 		"project": filters.project,
 		"finance_book": filters.finance_book,
-		"company_fb": frappe.db.get_value("Company", filters.company, "default_finance_book"),
+		"company_fb": frappe.get_cached_value("Company", filters.company, "default_finance_book"),
 	}
 
 	if accounting_dimensions:
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 103c154..41702d6 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -975,7 +975,7 @@
 def create_payment_gateway_account(gateway, payment_channel="Email"):
 	from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account
 
-	company = frappe.db.get_value("Global Defaults", None, "default_company")
+	company = frappe.get_cached_value("Global Defaults", "Global Defaults", "default_company")
 	if not company:
 		return