Merge branch 'frappe:develop' into fix-pricing-rule-item-group-uom
diff --git a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
index dff883a..a0ea433 100644
--- a/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
+++ b/erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
@@ -202,6 +202,7 @@
    "fieldname": "reference_type",
    "fieldtype": "Select",
    "label": "Reference Type",
+   "no_copy": 1,
    "options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement"
   },
   {
@@ -209,13 +210,15 @@
    "fieldtype": "Dynamic Link",
    "in_list_view": 1,
    "label": "Reference Name",
+   "no_copy": 1,
    "options": "reference_type"
   },
   {
    "depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance'])",
    "fieldname": "reference_due_date",
    "fieldtype": "Select",
-   "label": "Reference Due Date"
+   "label": "Reference Due Date",
+   "no_copy": 1
   },
   {
    "fieldname": "project",
@@ -274,19 +277,22 @@
    "fieldname": "reference_detail_no",
    "fieldtype": "Data",
    "hidden": 1,
-   "label": "Reference Detail No"
+   "label": "Reference Detail No",
+   "no_copy": 1
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-08-30 21:27:32.200299",
+ "modified": "2022-10-13 17:07:17.999191",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Journal Entry Account",
+ "naming_rule": "Random",
  "owner": "Administrator",
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 9af3188..826d71b 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -268,6 +268,18 @@
 	return item_details
 
 
+def update_pricing_rule_uom(pricing_rule, args):
+	child_doc = {"Item Code": "items", "Item Group": "item_groups", "Brand": "brands"}.get(
+		pricing_rule.apply_on
+	)
+
+	apply_on_field = frappe.scrub(pricing_rule.apply_on)
+
+	for row in pricing_rule.get(child_doc):
+		if row.get(apply_on_field) == args.get(apply_on_field):
+			pricing_rule.uom = row.uom
+
+
 def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=False):
 	from erpnext.accounts.doctype.pricing_rule.utils import (
 		get_applied_pricing_rules,
@@ -324,6 +336,7 @@
 
 			if isinstance(pricing_rule, str):
 				pricing_rule = frappe.get_cached_doc("Pricing Rule", pricing_rule)
+				update_pricing_rule_uom(pricing_rule, args)
 				pricing_rule.apply_rule_on_other_items = get_pricing_rule_items(pricing_rule) or []
 
 			if pricing_rule.get("suggestion"):
@@ -440,12 +453,15 @@
 		if pricing_rule.currency == args.currency:
 			pricing_rule_rate = pricing_rule.rate
 
+		# TODO https://github.com/frappe/erpnext/pull/23636 solve this in some other way.
 		if pricing_rule_rate:
+			is_blank_uom = pricing_rule.get("uom") != args.get("uom")
 			# Override already set price list rate (from item price)
 			# if pricing_rule_rate > 0
 			item_details.update(
 				{
-					"price_list_rate": pricing_rule_rate * args.get("conversion_factor", 1),
+					"price_list_rate": pricing_rule_rate
+					* (args.get("conversion_factor", 1) if is_blank_uom else 1),
 				}
 			)
 		item_details.update({"discount_percentage": 0.0})
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index 0a9db6b..fbe5678 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -595,6 +595,121 @@
 		frappe.get_doc("Item Price", {"item_code": "Water Flask"}).delete()
 		item.delete()
 
+	def test_item_price_with_blank_uom_pricing_rule(self):
+		properties = {
+			"item_code": "Item Blank UOM",
+			"stock_uom": "Nos",
+			"sales_uom": "Box",
+			"uoms": [dict(uom="Box", conversion_factor=10)],
+		}
+		item = make_item(properties=properties)
+
+		make_item_price("Item Blank UOM", "_Test Price List", 100)
+
+		pricing_rule_record = {
+			"doctype": "Pricing Rule",
+			"title": "_Test Item Blank UOM Rule",
+			"apply_on": "Item Code",
+			"items": [
+				{
+					"item_code": "Item Blank UOM",
+				}
+			],
+			"selling": 1,
+			"currency": "INR",
+			"rate_or_discount": "Rate",
+			"rate": 101,
+			"company": "_Test Company",
+		}
+		rule = frappe.get_doc(pricing_rule_record)
+		rule.insert()
+
+		si = create_sales_invoice(
+			do_not_save=True, item_code="Item Blank UOM", uom="Box", conversion_factor=10
+		)
+		si.selling_price_list = "_Test Price List"
+		si.save()
+
+		# If UOM is blank consider it as stock UOM and apply pricing_rule on all UOM.
+		# rate is 101, Selling UOM is Box that have conversion_factor of 10 so 101 * 10 = 1010
+		self.assertEqual(si.items[0].price_list_rate, 1010)
+		self.assertEqual(si.items[0].rate, 1010)
+
+		si.delete()
+
+		si = create_sales_invoice(do_not_save=True, item_code="Item Blank UOM", uom="Nos")
+		si.selling_price_list = "_Test Price List"
+		si.save()
+
+		# UOM is blank so consider it as stock UOM and apply pricing_rule on all UOM.
+		# rate is 101, Selling UOM is Nos that have conversion_factor of 1 so 101 * 1 = 101
+		self.assertEqual(si.items[0].price_list_rate, 101)
+		self.assertEqual(si.items[0].rate, 101)
+
+		si.delete()
+		rule.delete()
+		frappe.get_doc("Item Price", {"item_code": "Item Blank UOM"}).delete()
+
+		item.delete()
+
+	def test_item_price_with_selling_uom_pricing_rule(self):
+		properties = {
+			"item_code": "Item UOM other than Stock",
+			"stock_uom": "Nos",
+			"sales_uom": "Box",
+			"uoms": [dict(uom="Box", conversion_factor=10)],
+		}
+		item = make_item(properties=properties)
+
+		make_item_price("Item UOM other than Stock", "_Test Price List", 100)
+
+		pricing_rule_record = {
+			"doctype": "Pricing Rule",
+			"title": "_Test Item UOM other than Stock Rule",
+			"apply_on": "Item Code",
+			"items": [
+				{
+					"item_code": "Item UOM other than Stock",
+					"uom": "Box",
+				}
+			],
+			"selling": 1,
+			"currency": "INR",
+			"rate_or_discount": "Rate",
+			"rate": 101,
+			"company": "_Test Company",
+		}
+		rule = frappe.get_doc(pricing_rule_record)
+		rule.insert()
+
+		si = create_sales_invoice(
+			do_not_save=True, item_code="Item UOM other than Stock", uom="Box", conversion_factor=10
+		)
+		si.selling_price_list = "_Test Price List"
+		si.save()
+
+		# UOM is Box so apply pricing_rule only on Box UOM.
+		# Selling UOM is Box and as both UOM are same no need to multiply by conversion_factor.
+		self.assertEqual(si.items[0].price_list_rate, 101)
+		self.assertEqual(si.items[0].rate, 101)
+
+		si.delete()
+
+		si = create_sales_invoice(do_not_save=True, item_code="Item UOM other than Stock", uom="Nos")
+		si.selling_price_list = "_Test Price List"
+		si.save()
+
+		# UOM is Box so pricing_rule won't apply as selling_uom is Nos.
+		# As Pricing Rule is not applied price of 100 will be fetched from Item Price List.
+		self.assertEqual(si.items[0].price_list_rate, 100)
+		self.assertEqual(si.items[0].rate, 100)
+
+		si.delete()
+		rule.delete()
+		frappe.get_doc("Item Price", {"item_code": "Item UOM other than Stock"}).delete()
+
+		item.delete()
+
 	def test_pricing_rule_for_different_currency(self):
 		make_item("Test Sanitizer Item")
 
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 11ae540..f87fecf 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -111,6 +111,12 @@
 		)
 
 		if apply_on_field == "item_code":
+			if args.get("uom", None):
+				item_conditions += (
+					" and ({child_doc}.uom='{item_uom}' or IFNULL({child_doc}.uom, '')='')".format(
+						child_doc=child_doc, item_uom=args.get("uom")
+					)
+				)
 			if "variant_of" not in args:
 				args.variant_of = frappe.get_cached_value("Item", args.item_code, "variant_of")
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index ec861a2..c3a9855 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -31,7 +31,7 @@
 		super.onload();
 
 		// Ignore linked advances
-		this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry'];
+		this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice'];
 
 		if(!this.frm.doc.__islocal) {
 			// show credit_to in print format
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 5dbe7eb..3d74b8f 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -1415,6 +1415,7 @@
 			"Stock Ledger Entry",
 			"Repost Item Valuation",
 			"Payment Ledger Entry",
+			"Purchase Invoice",
 		)
 		self.update_advance_tax_references(cancel=1)
 
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 301d3e1..1ba7824 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -3228,6 +3228,22 @@
 
 		self.assertTrue(return_si.docstatus == 1)
 
+	def test_sales_invoice_with_payable_tax_account(self):
+		si = create_sales_invoice(do_not_submit=True)
+		si.append(
+			"taxes",
+			{
+				"charge_type": "Actual",
+				"account_head": "Creditors - _TC",
+				"description": "Test",
+				"cost_center": "Main - _TC",
+				"tax_amount": 10,
+				"total": 10,
+				"dont_recompute_tax": 0,
+			},
+		)
+		self.assertRaises(frappe.ValidationError, si.submit)
+
 
 def get_sales_invoice_for_e_invoice():
 	si = make_sales_invoice_for_ewaybill()
@@ -3320,7 +3336,7 @@
 			"asset": args.asset or None,
 			"cost_center": args.cost_center or "_Test Cost Center - _TC",
 			"serial_no": args.serial_no,
-			"conversion_factor": 1,
+			"conversion_factor": args.get("conversion_factor", 1),
 			"incoming_rate": args.incoming_rate or 0,
 			"batch_no": args.batch_no or None,
 		},
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 95ba3d8..d7bf991 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -460,10 +460,6 @@
 
 		frappe.flags.ignore_party_validation = False
 
-		if entry.voucher_type in ("Payment Entry", "Journal Entry"):
-			if hasattr(doc, "update_expense_claim"):
-				doc.update_expense_claim()
-
 
 def check_if_advance_entry_modified(args):
 	"""
@@ -1171,6 +1167,10 @@
 		where voucher_type=%s and voucher_no=%s""",
 		(voucher_type, voucher_no),
 	)
+	ple = qb.DocType("Payment Ledger Entry")
+	qb.from_(ple).delete().where(
+		(ple.voucher_type == voucher_type) & (ple.voucher_no == voucher_no)
+	).run()
 
 
 def sort_stock_vouchers_by_posting_date(
@@ -1368,9 +1368,8 @@
 			frappe.delete_doc("Desktop Icon", icon)
 
 
-def create_payment_ledger_entry(
-	gl_entries, cancel=0, adv_adj=0, update_outstanding="Yes", from_repost=0
-):
+def get_payment_ledger_entries(gl_entries, cancel=0):
+	ple_map = []
 	if gl_entries:
 		ple = None
 
@@ -1410,44 +1409,57 @@
 					dr_or_cr *= -1
 					dr_or_cr_account_currency *= -1
 
-				ple = frappe.get_doc(
-					{
-						"doctype": "Payment Ledger Entry",
-						"posting_date": gle.posting_date,
-						"company": gle.company,
-						"account_type": account_type,
-						"account": gle.account,
-						"party_type": gle.party_type,
-						"party": gle.party,
-						"cost_center": gle.cost_center,
-						"finance_book": gle.finance_book,
-						"due_date": gle.due_date,
-						"voucher_type": gle.voucher_type,
-						"voucher_no": gle.voucher_no,
-						"against_voucher_type": gle.against_voucher_type
-						if gle.against_voucher_type
-						else gle.voucher_type,
-						"against_voucher_no": gle.against_voucher if gle.against_voucher else gle.voucher_no,
-						"account_currency": gle.account_currency,
-						"amount": dr_or_cr,
-						"amount_in_account_currency": dr_or_cr_account_currency,
-						"delinked": True if cancel else False,
-						"remarks": gle.remarks,
-					}
+				ple = frappe._dict(
+					doctype="Payment Ledger Entry",
+					posting_date=gle.posting_date,
+					company=gle.company,
+					account_type=account_type,
+					account=gle.account,
+					party_type=gle.party_type,
+					party=gle.party,
+					cost_center=gle.cost_center,
+					finance_book=gle.finance_book,
+					due_date=gle.due_date,
+					voucher_type=gle.voucher_type,
+					voucher_no=gle.voucher_no,
+					against_voucher_type=gle.against_voucher_type
+					if gle.against_voucher_type
+					else gle.voucher_type,
+					against_voucher_no=gle.against_voucher if gle.against_voucher else gle.voucher_no,
+					account_currency=gle.account_currency,
+					amount=dr_or_cr,
+					amount_in_account_currency=dr_or_cr_account_currency,
+					delinked=True if cancel else False,
+					remarks=gle.remarks,
 				)
 
 				dimensions_and_defaults = get_dimensions()
 				if dimensions_and_defaults:
 					for dimension in dimensions_and_defaults[0]:
-						ple.set(dimension.fieldname, gle.get(dimension.fieldname))
+						ple[dimension.fieldname] = gle.get(dimension.fieldname)
 
-				if cancel:
-					delink_original_entry(ple)
-				ple.flags.ignore_permissions = 1
-				ple.flags.adv_adj = adv_adj
-				ple.flags.from_repost = from_repost
-				ple.flags.update_outstanding = update_outstanding
-				ple.submit()
+				ple_map.append(ple)
+	return ple_map
+
+
+def create_payment_ledger_entry(
+	gl_entries, cancel=0, adv_adj=0, update_outstanding="Yes", from_repost=0
+):
+	if gl_entries:
+		ple_map = get_payment_ledger_entries(gl_entries, cancel=cancel)
+
+		for entry in ple_map:
+
+			ple = frappe.get_doc(entry)
+
+			if cancel:
+				delink_original_entry(ple)
+
+			ple.flags.ignore_permissions = 1
+			ple.flags.adv_adj = adv_adj
+			ple.flags.from_repost = from_repost
+			ple.flags.update_outstanding = update_outstanding
+			ple.submit()
 
 
 def update_voucher_outstanding(voucher_type, voucher_no, account, party_type, party):
@@ -1467,7 +1479,12 @@
 
 	# on cancellation outstanding can be an empty list
 	voucher_outstanding = ple_query.get_voucher_outstandings(vouchers, common_filter=common_filter)
-	if voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"] and voucher_outstanding:
+	if (
+		voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]
+		and party_type
+		and party
+		and voucher_outstanding
+	):
 		outstanding = voucher_outstanding[0]
 		ref_doc = frappe.get_doc(voucher_type, voucher_no)
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index bcedd4d..c224b61 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -18,7 +18,7 @@
 from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
 	get_party_tax_withholding_details,
 )
-from erpnext.accounts.party import get_party_account_currency
+from erpnext.accounts.party import get_party_account, get_party_account_currency
 from erpnext.buying.utils import check_on_hold_or_closed_status, validate_for_items
 from erpnext.controllers.buying_controller import BuyingController
 from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
@@ -558,6 +558,7 @@
 			target.set_advances()
 
 		target.set_payment_schedule()
+		target.credit_to = get_party_account("Supplier", source.supplier, source.company)
 
 	def update_item(obj, target, source_parent):
 		target.amount = flt(obj.amount) - flt(obj.billed_amt)
diff --git a/erpnext/buying/report/procurement_tracker/procurement_tracker.py b/erpnext/buying/report/procurement_tracker/procurement_tracker.py
index d70ac46..71019e8 100644
--- a/erpnext/buying/report/procurement_tracker/procurement_tracker.py
+++ b/erpnext/buying/report/procurement_tracker/procurement_tracker.py
@@ -127,32 +127,27 @@
 	return columns
 
 
-def get_conditions(filters):
-	conditions = ""
-
+def apply_filters_on_query(filters, parent, child, query):
 	if filters.get("company"):
-		conditions += " AND parent.company=%s" % frappe.db.escape(filters.get("company"))
+		query = query.where(parent.company == filters.get("company"))
 
 	if filters.get("cost_center") or filters.get("project"):
-		conditions += """
-			AND (child.`cost_center`=%s OR child.`project`=%s)
-			""" % (
-			frappe.db.escape(filters.get("cost_center")),
-			frappe.db.escape(filters.get("project")),
+		query = query.where(
+			(child.cost_center == filters.get("cost_center")) | (child.project == filters.get("project"))
 		)
 
 	if filters.get("from_date"):
-		conditions += " AND parent.transaction_date>='%s'" % filters.get("from_date")
+		query = query.where(parent.transaction_date >= filters.get("from_date"))
 
 	if filters.get("to_date"):
-		conditions += " AND parent.transaction_date<='%s'" % filters.get("to_date")
-	return conditions
+		query = query.where(parent.transaction_date <= filters.get("to_date"))
+
+	return query
 
 
 def get_data(filters):
-	conditions = get_conditions(filters)
-	purchase_order_entry = get_po_entries(conditions)
-	mr_records, procurement_record_against_mr = get_mapped_mr_details(conditions)
+	purchase_order_entry = get_po_entries(filters)
+	mr_records, procurement_record_against_mr = get_mapped_mr_details(filters)
 	pr_records = get_mapped_pr_records()
 	pi_records = get_mapped_pi_records()
 
@@ -187,11 +182,15 @@
 	return procurement_record
 
 
-def get_mapped_mr_details(conditions):
+def get_mapped_mr_details(filters):
 	mr_records = {}
-	mr_details = frappe.db.sql(
-		"""
-		SELECT
+	parent = frappe.qb.DocType("Material Request")
+	child = frappe.qb.DocType("Material Request Item")
+
+	query = (
+		frappe.qb.from_(parent)
+		.from_(child)
+		.select(
 			parent.transaction_date,
 			parent.per_ordered,
 			parent.owner,
@@ -203,18 +202,13 @@
 			child.uom,
 			parent.status,
 			child.project,
-			child.cost_center
-		FROM `tabMaterial Request` parent, `tabMaterial Request Item` child
-		WHERE
-			parent.per_ordered>=0
-			AND parent.name=child.parent
-			AND parent.docstatus=1
-			{conditions}
-		""".format(
-			conditions=conditions
-		),
-		as_dict=1,
-	)  # nosec
+			child.cost_center,
+		)
+		.where((parent.per_ordered >= 0) & (parent.name == child.parent) & (parent.docstatus == 1))
+	)
+	query = apply_filters_on_query(filters, parent, child, query)
+
+	mr_details = query.run(as_dict=True)
 
 	procurement_record_against_mr = []
 	for record in mr_details:
@@ -241,46 +235,49 @@
 
 
 def get_mapped_pi_records():
-	return frappe._dict(
-		frappe.db.sql(
-			"""
-		SELECT
-			pi_item.po_detail,
-			pi_item.base_amount
-		FROM `tabPurchase Invoice Item` as pi_item
-		INNER JOIN `tabPurchase Order` as po
-		ON pi_item.`purchase_order` = po.`name`
-		WHERE
-			pi_item.docstatus = 1
-			AND po.status not in ('Closed','Completed','Cancelled')
-			AND pi_item.po_detail IS NOT NULL
-		"""
+	po = frappe.qb.DocType("Purchase Order")
+	pi_item = frappe.qb.DocType("Purchase Invoice Item")
+	pi_records = (
+		frappe.qb.from_(pi_item)
+		.inner_join(po)
+		.on(pi_item.purchase_order == po.name)
+		.select(pi_item.po_detail, pi_item.base_amount)
+		.where(
+			(pi_item.docstatus == 1)
+			& (po.status.notin(("Closed", "Completed", "Cancelled")))
+			& (pi_item.po_detail.isnotnull())
 		)
-	)
+	).run()
+
+	return frappe._dict(pi_records)
 
 
 def get_mapped_pr_records():
-	return frappe._dict(
-		frappe.db.sql(
-			"""
-		SELECT
-			pr_item.purchase_order_item,
-			pr.posting_date
-		FROM `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item
-		WHERE
-			pr.docstatus=1
-			AND pr.name=pr_item.parent
-			AND pr_item.purchase_order_item IS NOT NULL
-			AND pr.status not in  ('Closed','Completed','Cancelled')
-		"""
+	pr = frappe.qb.DocType("Purchase Receipt")
+	pr_item = frappe.qb.DocType("Purchase Receipt Item")
+	pr_records = (
+		frappe.qb.from_(pr)
+		.from_(pr_item)
+		.select(pr_item.purchase_order_item, pr.posting_date)
+		.where(
+			(pr.docstatus == 1)
+			& (pr.name == pr_item.parent)
+			& (pr_item.purchase_order_item.isnotnull())
+			& (pr.status.notin(("Closed", "Completed", "Cancelled")))
 		)
-	)
+	).run()
+
+	return frappe._dict(pr_records)
 
 
-def get_po_entries(conditions):
-	return frappe.db.sql(
-		"""
-		SELECT
+def get_po_entries(filters):
+	parent = frappe.qb.DocType("Purchase Order")
+	child = frappe.qb.DocType("Purchase Order Item")
+
+	query = (
+		frappe.qb.from_(parent)
+		.from_(child)
+		.select(
 			child.name,
 			child.parent,
 			child.cost_center,
@@ -297,17 +294,15 @@
 			parent.transaction_date,
 			parent.supplier,
 			parent.status,
-			parent.owner
-		FROM `tabPurchase Order` parent, `tabPurchase Order Item` child
-		WHERE
-			parent.docstatus = 1
-			AND parent.name = child.parent
-			AND parent.status not in  ('Closed','Completed','Cancelled')
-			{conditions}
-		GROUP BY
-			parent.name, child.item_code
-		""".format(
-			conditions=conditions
-		),
-		as_dict=1,
-	)  # nosec
+			parent.owner,
+		)
+		.where(
+			(parent.docstatus == 1)
+			& (parent.name == child.parent)
+			& (parent.status.notin(("Closed", "Completed", "Cancelled")))
+		)
+		.groupby(parent.name, child.item_code)
+	)
+	query = apply_filters_on_query(filters, parent, child, query)
+
+	return query.run(as_dict=True)
diff --git a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
index a5c4649..e10c0e2 100644
--- a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
+++ b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py
@@ -6,6 +6,7 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import IfNull
 from frappe.utils import date_diff, flt, getdate
 
 
@@ -16,9 +17,7 @@
 	validate_filters(filters)
 
 	columns = get_columns(filters)
-	conditions = get_conditions(filters)
-
-	data = get_data(conditions, filters)
+	data = get_data(filters)
 
 	if not data:
 		return [], [], None, []
@@ -37,60 +36,61 @@
 		frappe.throw(_("To Date cannot be before From Date."))
 
 
-def get_conditions(filters):
-	conditions = ""
-	if filters.get("from_date") and filters.get("to_date"):
-		conditions += " and po.transaction_date between %(from_date)s and %(to_date)s"
+def get_data(filters):
+	po = frappe.qb.DocType("Purchase Order")
+	po_item = frappe.qb.DocType("Purchase Order Item")
+	pi_item = frappe.qb.DocType("Purchase Invoice Item")
 
-	for field in ["company", "name"]:
+	query = (
+		frappe.qb.from_(po)
+		.from_(po_item)
+		.left_join(pi_item)
+		.on(pi_item.po_detail == po_item.name)
+		.select(
+			po.transaction_date.as_("date"),
+			po_item.schedule_date.as_("required_date"),
+			po_item.project,
+			po.name.as_("purchase_order"),
+			po.status,
+			po.supplier,
+			po_item.item_code,
+			po_item.qty,
+			po_item.received_qty,
+			(po_item.qty - po_item.received_qty).as_("pending_qty"),
+			IfNull(pi_item.qty, 0).as_("billed_qty"),
+			po_item.base_amount.as_("amount"),
+			(po_item.received_qty * po_item.base_rate).as_("received_qty_amount"),
+			(po_item.billed_amt * IfNull(po.conversion_rate, 1)).as_("billed_amount"),
+			(po_item.base_amount - (po_item.billed_amt * IfNull(po.conversion_rate, 1))).as_(
+				"pending_amount"
+			),
+			po.set_warehouse.as_("warehouse"),
+			po.company,
+			po_item.name,
+		)
+		.where(
+			(po_item.parent == po.name) & (po.status.notin(("Stopped", "Closed"))) & (po.docstatus == 1)
+		)
+		.groupby(po_item.name)
+		.orderby(po.transaction_date)
+	)
+
+	for field in ("company", "name"):
 		if filters.get(field):
-			conditions += f" and po.{field} = %({field})s"
+			query = query.where(po[field] == filters.get(field))
+
+	if filters.get("from_date") and filters.get("to_date"):
+		query = query.where(
+			po.transaction_date.between(filters.get("from_date"), filters.get("to_date"))
+		)
 
 	if filters.get("status"):
-		conditions += " and po.status in %(status)s"
+		query = query.where(po.status.isin(filters.get("status")))
 
 	if filters.get("project"):
-		conditions += " and poi.project = %(project)s"
+		query = query.where(po_item.project == filters.get("project"))
 
-	return conditions
-
-
-def get_data(conditions, filters):
-	data = frappe.db.sql(
-		"""
-		SELECT
-			po.transaction_date as date,
-			poi.schedule_date as required_date,
-			poi.project,
-			po.name as purchase_order,
-			po.status, po.supplier, poi.item_code,
-			poi.qty, poi.received_qty,
-			(poi.qty - poi.received_qty) AS pending_qty,
-			IFNULL(pii.qty, 0) as billed_qty,
-			poi.base_amount as amount,
-			(poi.received_qty * poi.base_rate) as received_qty_amount,
-			(poi.billed_amt * IFNULL(po.conversion_rate, 1)) as billed_amount,
-			(poi.base_amount - (poi.billed_amt * IFNULL(po.conversion_rate, 1))) as pending_amount,
-			po.set_warehouse as warehouse,
-			po.company, poi.name
-		FROM
-			`tabPurchase Order` po,
-			`tabPurchase Order Item` poi
-		LEFT JOIN `tabPurchase Invoice Item` pii
-			ON pii.po_detail = poi.name
-		WHERE
-			poi.parent = po.name
-			and po.status not in ('Stopped', 'Closed')
-			and po.docstatus = 1
-			{0}
-		GROUP BY poi.name
-		ORDER BY po.transaction_date ASC
-	""".format(
-			conditions
-		),
-		filters,
-		as_dict=1,
-	)
+	data = query.run(as_dict=True)
 
 	return data
 
diff --git a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py
index 3013b6d..a728290 100644
--- a/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py
+++ b/erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py
@@ -16,8 +16,7 @@
 		return [], []
 
 	columns = get_columns(filters)
-	conditions = get_conditions(filters)
-	supplier_quotation_data = get_data(filters, conditions)
+	supplier_quotation_data = get_data(filters)
 
 	data, chart_data = prepare_data(supplier_quotation_data, filters)
 	message = get_message()
@@ -25,50 +24,51 @@
 	return columns, data, message, chart_data
 
 
-def get_conditions(filters):
-	conditions = ""
+def get_data(filters):
+	sq = frappe.qb.DocType("Supplier Quotation")
+	sq_item = frappe.qb.DocType("Supplier Quotation Item")
+
+	query = (
+		frappe.qb.from_(sq_item)
+		.from_(sq)
+		.select(
+			sq_item.parent,
+			sq_item.item_code,
+			sq_item.qty,
+			sq_item.stock_qty,
+			sq_item.amount,
+			sq_item.uom,
+			sq_item.stock_uom,
+			sq_item.request_for_quotation,
+			sq_item.lead_time_days,
+			sq.supplier.as_("supplier_name"),
+			sq.valid_till,
+		)
+		.where(
+			(sq_item.parent == sq.name)
+			& (sq_item.docstatus < 2)
+			& (sq.company == filters.get("company"))
+			& (sq.transaction_date.between(filters.get("from_date"), filters.get("to_date")))
+		)
+		.orderby(sq.transaction_date, sq_item.item_code)
+	)
+
 	if filters.get("item_code"):
-		conditions += " AND sqi.item_code = %(item_code)s"
+		query = query.where(sq_item.item_code == filters.get("item_code"))
 
 	if filters.get("supplier_quotation"):
-		conditions += " AND sqi.parent in %(supplier_quotation)s"
+		query = query.where(sq_item.parent.isin(filters.get("supplier_quotation")))
 
 	if filters.get("request_for_quotation"):
-		conditions += " AND sqi.request_for_quotation = %(request_for_quotation)s"
+		query = query.where(sq_item.request_for_quotation == filters.get("request_for_quotation"))
 
 	if filters.get("supplier"):
-		conditions += " AND sq.supplier in %(supplier)s"
+		query = query.where(sq.supplier.isin(filters.get("supplier")))
 
 	if not filters.get("include_expired"):
-		conditions += " AND sq.status != 'Expired'"
+		query = query.where(sq.status != "Expired")
 
-	return conditions
-
-
-def get_data(filters, conditions):
-	supplier_quotation_data = frappe.db.sql(
-		"""
-		SELECT
-			sqi.parent, sqi.item_code,
-			sqi.qty, sqi.stock_qty, sqi.amount,
-			sqi.uom, sqi.stock_uom,
-			sqi.request_for_quotation,
-			sqi.lead_time_days, sq.supplier as supplier_name, sq.valid_till
-		FROM
-			`tabSupplier Quotation Item` sqi,
-			`tabSupplier Quotation` sq
-		WHERE
-			sqi.parent = sq.name
-			AND sqi.docstatus < 2
-			AND sq.company = %(company)s
-			AND sq.transaction_date between %(from_date)s and %(to_date)s
-			{0}
-			order by sq.transaction_date, sqi.item_code""".format(
-			conditions
-		),
-		filters,
-		as_dict=1,
-	)
+	supplier_quotation_data = query.run(as_dict=True)
 
 	return supplier_quotation_data
 
diff --git a/erpnext/crm/doctype/lead/lead.json b/erpnext/crm/doctype/lead/lead.json
index 99c00ad..8f8a086 100644
--- a/erpnext/crm/doctype/lead/lead.json
+++ b/erpnext/crm/doctype/lead/lead.json
@@ -375,7 +375,7 @@
    "depends_on": "eval:!doc.__islocal",
    "fieldname": "notes_tab",
    "fieldtype": "Tab Break",
-   "label": "Notes"
+   "label": "Comments"
   },
   {
    "collapsible": 1,
@@ -506,7 +506,7 @@
   {
    "fieldname": "dashboard_tab",
    "fieldtype": "Tab Break",
-   "label": "Dashboard",
+   "label": "Connections",
    "show_dashboard": 1
   }
  ],
@@ -514,7 +514,7 @@
  "idx": 5,
  "image_field": "image",
  "links": [],
- "modified": "2022-08-09 18:26:17.101521",
+ "modified": "2022-10-13 12:42:04.277879",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Lead",
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index fed0c7c..07641d2 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -544,14 +544,14 @@
    "depends_on": "eval:!doc.__islocal",
    "fieldname": "dashboard_tab",
    "fieldtype": "Tab Break",
-   "label": "Dashboard",
+   "label": "Connections",
    "show_dashboard": 1
   },
   {
    "depends_on": "eval:!doc.__islocal",
    "fieldname": "notes_tab",
    "fieldtype": "Tab Break",
-   "label": "Notes"
+   "label": "Comments"
   },
   {
    "fieldname": "notes_html",
@@ -622,7 +622,7 @@
  "icon": "fa fa-info-sign",
  "idx": 195,
  "links": [],
- "modified": "2022-08-09 18:26:37.235964",
+ "modified": "2022-10-13 12:42:21.545636",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Opportunity",
diff --git a/erpnext/crm/doctype/prospect/prospect.json b/erpnext/crm/doctype/prospect/prospect.json
index 820a6c7..d32311b 100644
--- a/erpnext/crm/doctype/prospect/prospect.json
+++ b/erpnext/crm/doctype/prospect/prospect.json
@@ -128,7 +128,7 @@
    "depends_on": "eval:!doc.__islocal",
    "fieldname": "notes_section",
    "fieldtype": "Tab Break",
-   "label": "Notes"
+   "label": "Comments"
   },
   {
    "depends_on": "eval: !doc.__islocal",
@@ -218,7 +218,7 @@
  ],
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2022-08-09 18:26:56.950185",
+ "modified": "2022-10-13 12:29:33.674561",
  "modified_by": "Administrator",
  "module": "CRM",
  "name": "Prospect",
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index b8f51f8..6bc17a3 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -274,8 +274,6 @@
 	"Timesheet": "erpnext.controllers.website_list_for_contact.has_website_permission",
 }
 
-dump_report_map = "erpnext.startup.report_data_map.data_map"
-
 before_tests = "erpnext.setup.utils.before_tests"
 
 standard_queries = {
diff --git a/erpnext/projects/workspace/projects/projects.json b/erpnext/projects/workspace/projects/projects.json
index 1253649..4bdb1db 100644
--- a/erpnext/projects/workspace/projects/projects.json
+++ b/erpnext/projects/workspace/projects/projects.json
@@ -5,7 +5,7 @@
    "label": "Open Projects"
   }
  ],
- "content": "[{\"type\":\"chart\",\"data\":{\"chart_name\":\"Open Projects\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Task\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Project\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Timesheet\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Project Billing Summary\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports & Masters</b></span>\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Projects\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Time Tracking\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}}]",
+ "content": "[{\"type\":\"chart\",\"data\":{\"chart_name\":\"Open Projects\",\"col\":12}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Your Shortcuts</b></span>\",\"col\":12}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Task\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Project\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Timesheet\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Project Billing Summary\",\"col\":3}},{\"type\":\"shortcut\",\"data\":{\"shortcut_name\":\"Dashboard\",\"col\":3}},{\"type\":\"spacer\",\"data\":{\"col\":12}},{\"type\":\"header\",\"data\":{\"text\":\"<span class=\\\"h4\\\"><b>Reports &amp; Masters</b></span>\",\"col\":12}},{\"type\":\"card\",\"data\":{\"card_name\":\"Projects\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Time Tracking\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Reports\",\"col\":4}},{\"type\":\"card\",\"data\":{\"card_name\":\"Settings\",\"col\":4}}]",
  "creation": "2020-03-02 15:46:04.874669",
  "docstatus": 0,
  "doctype": "Workspace",
@@ -170,9 +170,27 @@
    "link_type": "Report",
    "onboard": 0,
    "type": "Link"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Settings",
+   "link_count": 1,
+   "onboard": 0,
+   "type": "Card Break"
+  },
+  {
+   "hidden": 0,
+   "is_query_report": 0,
+   "label": "Projects Settings",
+   "link_count": 0,
+   "link_to": "Projects Settings",
+   "link_type": "DocType",
+   "onboard": 0,
+   "type": "Link"
   }
  ],
- "modified": "2022-06-28 12:31:30.167740",
+ "modified": "2022-10-11 22:39:10.436311",
  "modified_by": "Administrator",
  "module": "Projects",
  "name": "Projects",
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index c17610b..7fecb18 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -426,6 +426,7 @@
 			if(!this.validate_company_and_party()) {
 				this.frm.fields_dict["items"].grid.grid_rows[item.idx - 1].remove();
 			} else {
+				item.pricing_rules = ''
 				return this.frm.call({
 					method: "erpnext.stock.get_item_details.get_item_details",
 					child: item,
@@ -1045,6 +1046,7 @@
 	uom(doc, cdt, cdn) {
 		var me = this;
 		var item = frappe.get_doc(cdt, cdn);
+		item.pricing_rules = ''
 		if(item.item_code && item.uom) {
 			return this.frm.call({
 				method: "erpnext.stock.get_item_details.get_conversion_factor",
@@ -1121,6 +1123,7 @@
 
 	qty(doc, cdt, cdn) {
 		let item = frappe.get_doc(cdt, cdn);
+		item.pricing_rules = ''
 		this.conversion_factor(doc, cdt, cdn, true);
 		this.calculate_stock_uom_rate(doc, cdt, cdn);
 		this.apply_pricing_rule(item, true);
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 25806d6..f0e9e4b 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -18,6 +18,7 @@
 	update_linked_doc,
 	validate_inter_company_party,
 )
+from erpnext.accounts.party import get_party_account
 from erpnext.controllers.selling_controller import SellingController
 from erpnext.manufacturing.doctype.production_plan.production_plan import (
 	get_items_for_material_requests,
@@ -727,6 +728,8 @@
 		if source.loyalty_points and source.order_type == "Shopping Cart":
 			target.redeem_loyalty_points = 1
 
+		target.debit_to = get_party_account("Customer", source.customer, source.company)
+
 	def update_item(source, target, source_parent):
 		target.amount = flt(source.amount) - flt(source.billed_amt)
 		target.base_amount = target.amount * flt(source_parent.conversion_rate)
diff --git a/erpnext/startup/report_data_map.py b/erpnext/startup/report_data_map.py
deleted file mode 100644
index f8c1b6c..0000000
--- a/erpnext/startup/report_data_map.py
+++ /dev/null
@@ -1,327 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-
-# mappings for table dumps
-# "remember to add indexes!"
-
-data_map = {
-	"Company": {"columns": ["name"], "conditions": ["docstatus < 2"]},
-	"Fiscal Year": {
-		"columns": ["name", "year_start_date", "year_end_date"],
-		"conditions": ["docstatus < 2"],
-	},
-	# Accounts
-	"Account": {
-		"columns": ["name", "parent_account", "lft", "rgt", "report_type", "company", "is_group"],
-		"conditions": ["docstatus < 2"],
-		"order_by": "lft",
-		"links": {
-			"company": ["Company", "name"],
-		},
-	},
-	"Cost Center": {
-		"columns": ["name", "lft", "rgt"],
-		"conditions": ["docstatus < 2"],
-		"order_by": "lft",
-	},
-	"GL Entry": {
-		"columns": [
-			"name",
-			"account",
-			"posting_date",
-			"cost_center",
-			"debit",
-			"credit",
-			"is_opening",
-			"company",
-			"voucher_type",
-			"voucher_no",
-			"remarks",
-		],
-		"order_by": "posting_date, account",
-		"links": {
-			"account": ["Account", "name"],
-			"company": ["Company", "name"],
-			"cost_center": ["Cost Center", "name"],
-		},
-	},
-	# Stock
-	"Item": {
-		"columns": [
-			"name",
-			"if(item_name=name, '', item_name) as item_name",
-			"description",
-			"item_group as parent_item_group",
-			"stock_uom",
-			"brand",
-			"valuation_method",
-		],
-		# "conditions": ["docstatus < 2"],
-		"order_by": "name",
-		"links": {"parent_item_group": ["Item Group", "name"], "brand": ["Brand", "name"]},
-	},
-	"Item Group": {
-		"columns": ["name", "parent_item_group"],
-		# "conditions": ["docstatus < 2"],
-		"order_by": "lft",
-	},
-	"Brand": {"columns": ["name"], "conditions": ["docstatus < 2"], "order_by": "name"},
-	"Project": {"columns": ["name"], "conditions": ["docstatus < 2"], "order_by": "name"},
-	"Warehouse": {"columns": ["name"], "conditions": ["docstatus < 2"], "order_by": "name"},
-	"Stock Ledger Entry": {
-		"columns": [
-			"name",
-			"posting_date",
-			"posting_time",
-			"item_code",
-			"warehouse",
-			"actual_qty as qty",
-			"voucher_type",
-			"voucher_no",
-			"project",
-			"incoming_rate as incoming_rate",
-			"stock_uom",
-			"serial_no",
-			"qty_after_transaction",
-			"valuation_rate",
-		],
-		"order_by": "posting_date, posting_time, creation",
-		"links": {
-			"item_code": ["Item", "name"],
-			"warehouse": ["Warehouse", "name"],
-			"project": ["Project", "name"],
-		},
-		"force_index": "posting_sort_index",
-	},
-	"Serial No": {
-		"columns": ["name", "purchase_rate as incoming_rate"],
-		"conditions": ["docstatus < 2"],
-		"order_by": "name",
-	},
-	"Stock Entry": {
-		"columns": ["name", "purpose"],
-		"conditions": ["docstatus=1"],
-		"order_by": "posting_date, posting_time, name",
-	},
-	"Material Request Item": {
-		"columns": ["item.name as name", "item_code", "warehouse", "(qty - ordered_qty) as qty"],
-		"from": "`tabMaterial Request Item` item, `tabMaterial Request` main",
-		"conditions": [
-			"item.parent = main.name",
-			"main.docstatus=1",
-			"main.status != 'Stopped'",
-			"ifnull(warehouse, '')!=''",
-			"qty > ordered_qty",
-		],
-		"links": {"item_code": ["Item", "name"], "warehouse": ["Warehouse", "name"]},
-	},
-	"Purchase Order Item": {
-		"columns": [
-			"item.name as name",
-			"item_code",
-			"warehouse",
-			"(qty - received_qty)*conversion_factor as qty",
-		],
-		"from": "`tabPurchase Order Item` item, `tabPurchase Order` main",
-		"conditions": [
-			"item.parent = main.name",
-			"main.docstatus=1",
-			"main.status != 'Stopped'",
-			"ifnull(warehouse, '')!=''",
-			"qty > received_qty",
-		],
-		"links": {"item_code": ["Item", "name"], "warehouse": ["Warehouse", "name"]},
-	},
-	"Sales Order Item": {
-		"columns": [
-			"item.name as name",
-			"item_code",
-			"(qty - delivered_qty)*conversion_factor as qty",
-			"warehouse",
-		],
-		"from": "`tabSales Order Item` item, `tabSales Order` main",
-		"conditions": [
-			"item.parent = main.name",
-			"main.docstatus=1",
-			"main.status != 'Stopped'",
-			"ifnull(warehouse, '')!=''",
-			"qty > delivered_qty",
-		],
-		"links": {"item_code": ["Item", "name"], "warehouse": ["Warehouse", "name"]},
-	},
-	# Sales
-	"Customer": {
-		"columns": [
-			"name",
-			"if(customer_name=name, '', customer_name) as customer_name",
-			"customer_group as parent_customer_group",
-			"territory as parent_territory",
-		],
-		"conditions": ["docstatus < 2"],
-		"order_by": "name",
-		"links": {
-			"parent_customer_group": ["Customer Group", "name"],
-			"parent_territory": ["Territory", "name"],
-		},
-	},
-	"Customer Group": {
-		"columns": ["name", "parent_customer_group"],
-		"conditions": ["docstatus < 2"],
-		"order_by": "lft",
-	},
-	"Territory": {
-		"columns": ["name", "parent_territory"],
-		"conditions": ["docstatus < 2"],
-		"order_by": "lft",
-	},
-	"Sales Invoice": {
-		"columns": ["name", "customer", "posting_date", "company"],
-		"conditions": ["docstatus=1"],
-		"order_by": "posting_date",
-		"links": {"customer": ["Customer", "name"], "company": ["Company", "name"]},
-	},
-	"Sales Invoice Item": {
-		"columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"],
-		"conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
-		"order_by": "parent",
-		"links": {"parent": ["Sales Invoice", "name"], "item_code": ["Item", "name"]},
-	},
-	"Sales Order": {
-		"columns": ["name", "customer", "transaction_date as posting_date", "company"],
-		"conditions": ["docstatus=1"],
-		"order_by": "transaction_date",
-		"links": {"customer": ["Customer", "name"], "company": ["Company", "name"]},
-	},
-	"Sales Order Item[Sales Analytics]": {
-		"columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"],
-		"conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
-		"order_by": "parent",
-		"links": {"parent": ["Sales Order", "name"], "item_code": ["Item", "name"]},
-	},
-	"Delivery Note": {
-		"columns": ["name", "customer", "posting_date", "company"],
-		"conditions": ["docstatus=1"],
-		"order_by": "posting_date",
-		"links": {"customer": ["Customer", "name"], "company": ["Company", "name"]},
-	},
-	"Delivery Note Item[Sales Analytics]": {
-		"columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"],
-		"conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
-		"order_by": "parent",
-		"links": {"parent": ["Delivery Note", "name"], "item_code": ["Item", "name"]},
-	},
-	"Supplier": {
-		"columns": [
-			"name",
-			"if(supplier_name=name, '', supplier_name) as supplier_name",
-			"supplier_group as parent_supplier_group",
-		],
-		"conditions": ["docstatus < 2"],
-		"order_by": "name",
-		"links": {
-			"parent_supplier_group": ["Supplier Group", "name"],
-		},
-	},
-	"Supplier Group": {
-		"columns": ["name", "parent_supplier_group"],
-		"conditions": ["docstatus < 2"],
-		"order_by": "name",
-	},
-	"Purchase Invoice": {
-		"columns": ["name", "supplier", "posting_date", "company"],
-		"conditions": ["docstatus=1"],
-		"order_by": "posting_date",
-		"links": {"supplier": ["Supplier", "name"], "company": ["Company", "name"]},
-	},
-	"Purchase Invoice Item": {
-		"columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"],
-		"conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
-		"order_by": "parent",
-		"links": {"parent": ["Purchase Invoice", "name"], "item_code": ["Item", "name"]},
-	},
-	"Purchase Order": {
-		"columns": ["name", "supplier", "transaction_date as posting_date", "company"],
-		"conditions": ["docstatus=1"],
-		"order_by": "posting_date",
-		"links": {"supplier": ["Supplier", "name"], "company": ["Company", "name"]},
-	},
-	"Purchase Order Item[Purchase Analytics]": {
-		"columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"],
-		"conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
-		"order_by": "parent",
-		"links": {"parent": ["Purchase Order", "name"], "item_code": ["Item", "name"]},
-	},
-	"Purchase Receipt": {
-		"columns": ["name", "supplier", "posting_date", "company"],
-		"conditions": ["docstatus=1"],
-		"order_by": "posting_date",
-		"links": {"supplier": ["Supplier", "name"], "company": ["Company", "name"]},
-	},
-	"Purchase Receipt Item[Purchase Analytics]": {
-		"columns": ["name", "parent", "item_code", "stock_qty as qty", "base_net_amount"],
-		"conditions": ["docstatus=1", "ifnull(parent, '')!=''"],
-		"order_by": "parent",
-		"links": {"parent": ["Purchase Receipt", "name"], "item_code": ["Item", "name"]},
-	},
-	# Support
-	"Issue": {
-		"columns": ["name", "status", "creation", "resolution_date", "first_responded_on"],
-		"conditions": ["docstatus < 2"],
-		"order_by": "creation",
-	},
-	# Manufacturing
-	"Work Order": {
-		"columns": [
-			"name",
-			"status",
-			"creation",
-			"planned_start_date",
-			"planned_end_date",
-			"status",
-			"actual_start_date",
-			"actual_end_date",
-			"modified",
-		],
-		"conditions": ["docstatus = 1"],
-		"order_by": "creation",
-	},
-	# Medical
-	"Patient": {
-		"columns": [
-			"name",
-			"creation",
-			"owner",
-			"if(patient_name=name, '', patient_name) as patient_name",
-		],
-		"conditions": ["docstatus < 2"],
-		"order_by": "name",
-		"links": {"owner": ["User", "name"]},
-	},
-	"Patient Appointment": {
-		"columns": [
-			"name",
-			"appointment_type",
-			"patient",
-			"practitioner",
-			"appointment_date",
-			"department",
-			"status",
-			"company",
-		],
-		"order_by": "name",
-		"links": {
-			"practitioner": ["Healthcare Practitioner", "name"],
-			"appointment_type": ["Appointment Type", "name"],
-		},
-	},
-	"Healthcare Practitioner": {
-		"columns": ["name", "department"],
-		"order_by": "name",
-		"links": {
-			"department": ["Department", "name"],
-		},
-	},
-	"Appointment Type": {"columns": ["name"], "order_by": "name"},
-	"Medical Department": {"columns": ["name"], "order_by": "name"},
-}
diff --git a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
index edd2553..e0f2479 100644
--- a/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
+++ b/erpnext/stock/doctype/repost_item_valuation/test_repost_item_valuation.py
@@ -9,6 +9,7 @@
 from frappe.utils import nowdate
 from frappe.utils.data import add_to_date, today
 
+from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.accounts.utils import repost_gle_for_stock_vouchers
 from erpnext.controllers.stock_controller import create_item_wise_repost_entries
 from erpnext.stock.doctype.item.test_item import make_item
@@ -272,3 +273,57 @@
 			[{"credit": 50, "debit": 0}],
 			gle_filters={"account": "Stock In Hand - TCP1"},
 		)
+
+	def test_duplicate_ple_on_repost(self):
+		from erpnext.accounts import utils
+
+		# lower numbers to simplify test
+		orig_chunk_size = utils.GL_REPOSTING_CHUNK
+		utils.GL_REPOSTING_CHUNK = 2
+		self.addCleanup(setattr, utils, "GL_REPOSTING_CHUNK", orig_chunk_size)
+
+		rate = 100
+		item = self.make_item()
+		item.valuation_rate = 90
+		item.allow_negative_stock = 1
+		item.save()
+
+		company = "_Test Company with perpetual inventory"
+
+		# consume non-existing stock
+		sinv = create_sales_invoice(
+			company=company,
+			posting_date=today(),
+			debit_to="Debtors - TCP1",
+			income_account="Sales - TCP1",
+			expense_account="Cost of Goods Sold - TCP1",
+			warehouse="Stores - TCP1",
+			update_stock=1,
+			currency="INR",
+			item_code=item.name,
+			cost_center="Main - TCP1",
+			qty=1,
+			rate=rate,
+		)
+
+		# backdated receipt triggers repost
+		make_stock_entry(
+			item=item.name,
+			company=company,
+			qty=5,
+			rate=rate,
+			target="Stores - TCP1",
+			posting_date=add_to_date(today(), days=-1),
+		)
+
+		ple_entries = frappe.db.get_list(
+			"Payment Ledger Entry",
+			filters={"voucher_type": sinv.doctype, "voucher_no": sinv.name, "delinked": 0},
+		)
+
+		# assert successful deduplication on PLE
+		self.assertEqual(len(ple_entries), 1)
+
+		# outstanding should not be affected
+		sinv.reload()
+		self.assertEqual(sinv.outstanding_amount, 100)
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index ab784ca..6e06d23 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -9,6 +9,7 @@
 from frappe.contacts.address_and_contact import load_address_and_contact
 from frappe.utils import cint, flt
 from frappe.utils.nestedset import NestedSet
+from pypika.terms import ExistsCriterion
 
 from erpnext.stock import get_warehouse_account
 
@@ -266,3 +267,23 @@
 		frappe.throw(_("Warehouse not found against the account {0}").format(account))
 
 	return warehouses
+
+
+# Will be use for frappe.qb
+def apply_warehouse_filter(query, sle, filters):
+	if warehouse := filters.get("warehouse"):
+		warehouse_table = frappe.qb.DocType("Warehouse")
+
+		lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
+		chilren_subquery = (
+			frappe.qb.from_(warehouse_table)
+			.select(warehouse_table.name)
+			.where(
+				(warehouse_table.lft >= lft)
+				& (warehouse_table.rgt <= rgt)
+				& (warehouse_table.name == sle.warehouse)
+			)
+		)
+		query = query.where(ExistsCriterion(chilren_subquery))
+
+	return query
diff --git a/erpnext/stock/report/batch_item_expiry_status/batch_item_expiry_status.py b/erpnext/stock/report/batch_item_expiry_status/batch_item_expiry_status.py
index 3d9b046..ef7d6e6 100644
--- a/erpnext/stock/report/batch_item_expiry_status/batch_item_expiry_status.py
+++ b/erpnext/stock/report/batch_item_expiry_status/batch_item_expiry_status.py
@@ -4,6 +4,7 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import IfNull
 from frappe.utils import cint, getdate
 
 
@@ -54,31 +55,28 @@
 	return columns
 
 
-def get_conditions(filters):
-	conditions = ""
+def get_stock_ledger_entries(filters):
 	if not filters.get("from_date"):
 		frappe.throw(_("'From Date' is required"))
 
-	if filters.get("to_date"):
-		conditions += " and posting_date <= '%s'" % filters["to_date"]
-	else:
+	if not filters.get("to_date"):
 		frappe.throw(_("'To Date' is required"))
 
-	return conditions
-
-
-def get_stock_ledger_entries(filters):
-	conditions = get_conditions(filters)
-	return frappe.db.sql(
-		"""select item_code, batch_no, warehouse,
-		posting_date, actual_qty
-		from `tabStock Ledger Entry`
-		where is_cancelled = 0
-		and docstatus < 2 and ifnull(batch_no, '') != '' %s order by item_code, warehouse"""
-		% conditions,
-		as_dict=1,
+	sle = frappe.qb.DocType("Stock Ledger Entry")
+	query = (
+		frappe.qb.from_(sle)
+		.select(sle.item_code, sle.batch_no, sle.warehouse, sle.posting_date, sle.actual_qty)
+		.where(
+			(sle.is_cancelled == 0)
+			& (sle.docstatus < 2)
+			& (IfNull(sle.batch_no, "") != "")
+			& (sle.posting_date <= filters["to_date"])
+		)
+		.orderby(sle.item_code, sle.warehouse)
 	)
 
+	return query.run(as_dict=True)
+
 
 def get_item_warehouse_batch_map(filters, float_precision):
 	sle = get_stock_ledger_entries(filters)
@@ -112,7 +110,7 @@
 
 def get_item_details(filters):
 	item_map = {}
-	for d in frappe.db.sql("select name, item_name, description from tabItem", as_dict=1):
+	for d in (frappe.qb.from_("Item").select("name", "item_name", "description")).run(as_dict=True):
 		item_map.setdefault(d.name, d)
 
 	return item_map
diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
index 8a13300..0d57938 100644
--- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
+++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py
@@ -5,6 +5,9 @@
 import frappe
 from frappe import _
 from frappe.utils import cint, flt, getdate
+from pypika import functions as fn
+
+from erpnext.stock.doctype.warehouse.warehouse import apply_warehouse_filter
 
 
 def execute(filters=None):
@@ -64,37 +67,40 @@
 	return columns
 
 
-def get_conditions(filters):
-	conditions = ""
-	if not filters.get("from_date"):
-		frappe.throw(_("'From Date' is required"))
-
-	if filters.get("to_date"):
-		conditions += " and posting_date <= '%s'" % filters["to_date"]
-	else:
-		frappe.throw(_("'To Date' is required"))
-
-	for field in ["item_code", "warehouse", "batch_no", "company"]:
-		if filters.get(field):
-			conditions += " and {0} = {1}".format(field, frappe.db.escape(filters.get(field)))
-
-	return conditions
-
-
 # get all details
 def get_stock_ledger_entries(filters):
-	conditions = get_conditions(filters)
-	return frappe.db.sql(
-		"""
-		select item_code, batch_no, warehouse, posting_date, sum(actual_qty) as actual_qty
-		from `tabStock Ledger Entry`
-		where is_cancelled = 0 and docstatus < 2 and ifnull(batch_no, '') != '' %s
-		group by voucher_no, batch_no, item_code, warehouse
-		order by item_code, warehouse"""
-		% conditions,
-		as_dict=1,
+	if not filters.get("from_date"):
+		frappe.throw(_("'From Date' is required"))
+	if not filters.get("to_date"):
+		frappe.throw(_("'To Date' is required"))
+
+	sle = frappe.qb.DocType("Stock Ledger Entry")
+	query = (
+		frappe.qb.from_(sle)
+		.select(
+			sle.item_code,
+			sle.warehouse,
+			sle.batch_no,
+			sle.posting_date,
+			fn.Sum(sle.actual_qty).as_("actual_qty"),
+		)
+		.where(
+			(sle.docstatus < 2)
+			& (sle.is_cancelled == 0)
+			& (fn.IfNull(sle.batch_no, "") != "")
+			& (sle.posting_date <= filters["to_date"])
+		)
+		.groupby(sle.voucher_no, sle.batch_no, sle.item_code, sle.warehouse)
+		.orderby(sle.item_code, sle.warehouse)
 	)
 
+	query = apply_warehouse_filter(query, sle, filters)
+	for field in ["item_code", "batch_no", "company"]:
+		if filters.get(field):
+			query = query.where(sle[field] == filters.get(field))
+
+	return query.run(as_dict=True)
+
 
 def get_item_warehouse_batch_map(filters, float_precision):
 	sle = get_stock_ledger_entries(filters)
@@ -127,7 +133,9 @@
 
 def get_item_details(filters):
 	item_map = {}
-	for d in frappe.db.sql("select name, item_name, description, stock_uom from tabItem", as_dict=1):
+	for d in (frappe.qb.from_("Item").select("name", "item_name", "description", "stock_uom")).run(
+		as_dict=1
+	):
 		item_map.setdefault(d.name, d)
 
 	return item_map
diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.py b/erpnext/stock/report/delayed_item_report/delayed_item_report.py
index 9df24d6..546a834 100644
--- a/erpnext/stock/report/delayed_item_report/delayed_item_report.py
+++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.py
@@ -21,56 +21,54 @@
 		return self.get_columns(), self.get_data() or []
 
 	def get_data(self, consolidated=False):
-		conditions = ""
-
 		doctype = self.filters.get("based_on")
-		child_doc = "%s Item" % doctype
+		sales_order_field = "sales_order" if doctype == "Sales Invoice" else "against_sales_order"
+
+		parent = frappe.qb.DocType(doctype)
+		child = frappe.qb.DocType(f"{doctype} Item")
+
+		query = (
+			frappe.qb.from_(child)
+			.from_(parent)
+			.select(
+				child.item_code,
+				child.item_name,
+				child.item_group,
+				child.qty,
+				child.rate,
+				child.amount,
+				child.so_detail,
+				child[sales_order_field].as_("sales_order"),
+				parent.shipping_address_name,
+				parent.po_no,
+				parent.customer,
+				parent.posting_date,
+				parent.name,
+				parent.grand_total,
+			)
+			.where(
+				(child.parent == parent.name)
+				& (parent.docstatus == 1)
+				& (parent.posting_date.between(self.filters.get("from_date"), self.filters.get("to_date")))
+				& (child[sales_order_field].notnull())
+				& (child[sales_order_field] != "")
+			)
+		)
 
 		if doctype == "Sales Invoice":
-			conditions = " and `tabSales Invoice`.update_stock = 1 and `tabSales Invoice`.is_pos = 0"
+			query = query.where((parent.update_stock == 1) & (parent.is_pos == 0))
 
 		if self.filters.get("item_group"):
-			conditions += " and `tab%s`.item_group = %s" % (
-				child_doc,
-				frappe.db.escape(self.filters.get("item_group")),
-			)
-
-		for field in ["customer", "customer_group", "company"]:
-			if self.filters.get(field):
-				conditions += " and `tab%s`.%s = %s" % (
-					doctype,
-					field,
-					frappe.db.escape(self.filters.get(field)),
-				)
-
-		sales_order_field = "against_sales_order"
-		if doctype == "Sales Invoice":
-			sales_order_field = "sales_order"
+			query = query.where(child.item_group == self.filters.get("item_group"))
 
 		if self.filters.get("sales_order"):
-			conditions = " and `tab%s`.%s = '%s'" % (
-				child_doc,
-				sales_order_field,
-				self.filters.get("sales_order"),
-			)
+			query = query.where(child[sales_order_field] == self.filters.get("sales_order"))
 
-		self.transactions = frappe.db.sql(
-			""" SELECT `tab{child_doc}`.item_code, `tab{child_doc}`.item_name,
-				`tab{child_doc}`.item_group, `tab{child_doc}`.qty, `tab{child_doc}`.rate, `tab{child_doc}`.amount,
-				`tab{child_doc}`.so_detail, `tab{child_doc}`.{so_field} as sales_order,
-				`tab{doctype}`.shipping_address_name, `tab{doctype}`.po_no, `tab{doctype}`.customer,
-				`tab{doctype}`.posting_date, `tab{doctype}`.name, `tab{doctype}`.grand_total
-			FROM `tab{child_doc}`, `tab{doctype}`
-			WHERE
-				`tab{child_doc}`.parent = `tab{doctype}`.name and `tab{doctype}`.docstatus = 1 and
-				`tab{doctype}`.posting_date between %(from_date)s and %(to_date)s and
-				`tab{child_doc}`.{so_field} is not null and `tab{child_doc}`.{so_field} != '' {cond}
-		""".format(
-				cond=conditions, doctype=doctype, child_doc=child_doc, so_field=sales_order_field
-			),
-			{"from_date": self.filters.get("from_date"), "to_date": self.filters.get("to_date")},
-			as_dict=1,
-		)
+		for field in ("customer", "customer_group", "company"):
+			if self.filters.get(field):
+				query = query.where(parent[field] == self.filters.get(field))
+
+		self.transactions = query.run(as_dict=True)
 
 		if self.transactions:
 			self.filter_transactions_data(consolidated)
diff --git a/erpnext/stock/report/item_prices/item_prices.py b/erpnext/stock/report/item_prices/item_prices.py
index 87f1a42..ab47b4a 100644
--- a/erpnext/stock/report/item_prices/item_prices.py
+++ b/erpnext/stock/report/item_prices/item_prices.py
@@ -4,6 +4,7 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import IfNull, Sum
 from frappe.utils import flt
 
 
@@ -12,8 +13,7 @@
 		filters = {}
 
 	columns = get_columns(filters)
-	conditions = get_condition(filters)
-	item_map = get_item_details(conditions)
+	item_map = get_item_details(filters)
 	pl = get_price_list()
 	last_purchase_rate = get_last_purchase_rate()
 	bom_rate = get_item_bom_rate()
@@ -63,18 +63,24 @@
 	return columns
 
 
-def get_item_details(conditions):
+def get_item_details(filters):
 	"""returns all items details"""
 
 	item_map = {}
 
-	for i in frappe.db.sql(
-		"""select name, item_group, item_name, description,
-		brand, stock_uom from tabItem %s
-		order by item_code, item_group"""
-		% (conditions),
-		as_dict=1,
-	):
+	item = frappe.qb.DocType("Item")
+	query = (
+		frappe.qb.from_(item)
+		.select(item.name, item.item_group, item.item_name, item.description, item.brand, item.stock_uom)
+		.orderby(item.item_code, item.item_group)
+	)
+
+	if filters.get("items") == "Enabled Items only":
+		query = query.where(item.disabled == 0)
+	elif filters.get("items") == "Disabled Items only":
+		query = query.where(item.disabled == 1)
+
+	for i in query.run(as_dict=True):
 		item_map.setdefault(i.name, i)
 
 	return item_map
@@ -85,19 +91,38 @@
 
 	rate = {}
 
-	price_list = frappe.db.sql(
-		"""select ip.item_code, ip.buying, ip.selling,
-		concat(ifnull(cu.symbol,ip.currency), " ", round(ip.price_list_rate,2), " - ", ip.price_list) as price
-		from `tabItem Price` ip, `tabPrice List` pl, `tabCurrency` cu
-		where ip.price_list=pl.name and pl.currency=cu.name and pl.enabled=1""",
-		as_dict=1,
-	)
+	ip = frappe.qb.DocType("Item Price")
+	pl = frappe.qb.DocType("Price List")
+	cu = frappe.qb.DocType("Currency")
 
-	for j in price_list:
-		if j.price:
-			rate.setdefault(j.item_code, {}).setdefault("Buying" if j.buying else "Selling", []).append(
-				j.price
+	price_list = (
+		frappe.qb.from_(ip)
+		.from_(pl)
+		.from_(cu)
+		.select(
+			ip.item_code,
+			ip.buying,
+			ip.selling,
+			(IfNull(cu.symbol, ip.currency)).as_("currency"),
+			ip.price_list_rate,
+			ip.price_list,
+		)
+		.where((ip.price_list == pl.name) & (pl.currency == cu.name) & (pl.enabled == 1))
+	).run(as_dict=True)
+
+	for d in price_list:
+		d.update(
+			{"price": "{0} {1} - {2}".format(d.currency, round(d.price_list_rate, 2), d.price_list)}
+		)
+		d.pop("currency")
+		d.pop("price_list_rate")
+		d.pop("price_list")
+
+		if d.price:
+			rate.setdefault(d.item_code, {}).setdefault("Buying" if d.buying else "Selling", []).append(
+				d.price
 			)
+
 	item_rate_map = {}
 
 	for item in rate:
@@ -112,30 +137,39 @@
 def get_last_purchase_rate():
 	item_last_purchase_rate_map = {}
 
-	query = """select * from (
-				(select
-					po_item.item_code,
-					po.transaction_date as posting_date,
-					po_item.base_rate
-				from `tabPurchase Order` po, `tabPurchase Order Item` po_item
-					where po.name = po_item.parent and po.docstatus = 1)
-				union
-				(select
-					pr_item.item_code,
-					pr.posting_date,
-					pr_item.base_rate
-				from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item
-					where pr.name = pr_item.parent and pr.docstatus = 1)
-				union
-				(select
-					pi_item.item_code,
-					pi.posting_date,
-					pi_item.base_rate
-				from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
-					where pi.name = pi_item.parent and pi.docstatus = 1 and pi.update_stock = 1)
-				) result order by result.item_code asc, result.posting_date asc"""
+	po = frappe.qb.DocType("Purchase Order")
+	pr = frappe.qb.DocType("Purchase Receipt")
+	pi = frappe.qb.DocType("Purchase Invoice")
+	po_item = frappe.qb.DocType("Purchase Order Item")
+	pr_item = frappe.qb.DocType("Purchase Receipt Item")
+	pi_item = frappe.qb.DocType("Purchase Invoice Item")
 
-	for d in frappe.db.sql(query, as_dict=1):
+	query = (
+		frappe.qb.from_(
+			(
+				frappe.qb.from_(po)
+				.from_(po_item)
+				.select(po_item.item_code, po.transaction_date.as_("posting_date"), po_item.base_rate)
+				.where((po.name == po_item.parent) & (po.docstatus == 1))
+			)
+			+ (
+				frappe.qb.from_(pr)
+				.from_(pr_item)
+				.select(pr_item.item_code, pr.posting_date, pr_item.base_rate)
+				.where((pr.name == pr_item.parent) & (pr.docstatus == 1))
+			)
+			+ (
+				frappe.qb.from_(pi)
+				.from_(pi_item)
+				.select(pi_item.item_code, pi.posting_date, pi_item.base_rate)
+				.where((pi.name == pi_item.parent) & (pi.docstatus == 1) & (pi.update_stock == 1))
+			)
+		)
+		.select("*")
+		.orderby("item_code", "posting_date")
+	)
+
+	for d in query.run(as_dict=True):
 		item_last_purchase_rate_map[d.item_code] = d.base_rate
 
 	return item_last_purchase_rate_map
@@ -146,12 +180,15 @@
 
 	item_bom_map = {}
 
-	for b in frappe.db.sql(
-		"""select item, (total_cost/quantity) as bom_rate
-		from `tabBOM` where is_active=1 and is_default=1""",
-		as_dict=1,
-	):
-		item_bom_map.setdefault(b.item, flt(b.bom_rate))
+	bom = frappe.qb.DocType("BOM")
+	bom_data = (
+		frappe.qb.from_(bom)
+		.select(bom.item, (bom.total_cost / bom.quantity).as_("bom_rate"))
+		.where((bom.is_active == 1) & (bom.is_default == 1))
+	).run(as_dict=True)
+
+	for d in bom_data:
+		item_bom_map.setdefault(d.item, flt(d.bom_rate))
 
 	return item_bom_map
 
@@ -161,25 +198,17 @@
 
 	item_val_rate_map = {}
 
-	for d in frappe.db.sql(
-		"""select item_code,
-		sum(actual_qty*valuation_rate)/sum(actual_qty) as val_rate
-		from tabBin where actual_qty > 0 group by item_code""",
-		as_dict=1,
-	):
+	bin = frappe.qb.DocType("Bin")
+	bin_data = (
+		frappe.qb.from_(bin)
+		.select(
+			bin.item_code, Sum(bin.actual_qty * bin.valuation_rate) / Sum(bin.actual_qty).as_("val_rate")
+		)
+		.where(bin.actual_qty > 0)
+		.groupby(bin.item_code)
+	).run(as_dict=True)
+
+	for d in bin_data:
 		item_val_rate_map.setdefault(d.item_code, d.val_rate)
 
 	return item_val_rate_map
-
-
-def get_condition(filters):
-	"""Get Filter Items"""
-
-	if filters.get("items") == "Enabled Items only":
-		conditions = " where disabled=0 "
-	elif filters.get("items") == "Disabled Items only":
-		conditions = " where disabled=1 "
-	else:
-		conditions = ""
-
-	return conditions
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index 679d234..0fc642e 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -10,10 +10,10 @@
 from frappe.query_builder.functions import CombineDatetime
 from frappe.utils import cint, date_diff, flt, getdate
 from frappe.utils.nestedset import get_descendants_of
-from pypika.terms import ExistsCriterion
 
 import erpnext
 from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
+from erpnext.stock.doctype.warehouse.warehouse import apply_warehouse_filter
 from erpnext.stock.report.stock_ageing.stock_ageing import FIFOSlots, get_average_age
 from erpnext.stock.utils import add_additional_uom_columns, is_reposting_item_valuation_in_progress
 
@@ -270,18 +270,8 @@
 	if company := filters.get("company"):
 		query = query.where(sle.company == company)
 
-	if warehouse := filters.get("warehouse"):
-		lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
-		chilren_subquery = (
-			frappe.qb.from_(warehouse_table)
-			.select(warehouse_table.name)
-			.where(
-				(warehouse_table.lft >= lft)
-				& (warehouse_table.rgt <= rgt)
-				& (warehouse_table.name == sle.warehouse)
-			)
-		)
-		query = query.where(ExistsCriterion(chilren_subquery))
+	if filters.get("warehouse"):
+		query = apply_warehouse_filter(query, sle, filters)
 	elif warehouse_type := filters.get("warehouse_type"):
 		query = (
 			query.join(warehouse_table)
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index e18d4c7..a951197 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -6,11 +6,11 @@
 from frappe import _
 from frappe.query_builder.functions import CombineDatetime
 from frappe.utils import cint, flt
-from pypika.terms import ExistsCriterion
 
 from erpnext.stock.doctype.inventory_dimension.inventory_dimension import get_inventory_dimensions
 from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
 from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import get_stock_balance_for
+from erpnext.stock.doctype.warehouse.warehouse import apply_warehouse_filter
 from erpnext.stock.utils import (
 	is_reposting_item_valuation_in_progress,
 	update_included_uom_in_report,
@@ -295,20 +295,7 @@
 		if filters.get(field):
 			query = query.where(sle[field] == filters.get(field))
 
-	if warehouse := filters.get("warehouse"):
-		lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
-
-		warehouse_table = frappe.qb.DocType("Warehouse")
-		chilren_subquery = (
-			frappe.qb.from_(warehouse_table)
-			.select(warehouse_table.name)
-			.where(
-				(warehouse_table.lft >= lft)
-				& (warehouse_table.rgt <= rgt)
-				& (warehouse_table.name == sle.warehouse)
-			)
-		)
-		query = query.where(ExistsCriterion(chilren_subquery))
+	query = apply_warehouse_filter(query, sle, filters)
 
 	return query.run(as_dict=True)
 
diff --git a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
index 49e797d..f477d8f 100644
--- a/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
+++ b/erpnext/stock/report/stock_projected_qty/stock_projected_qty.py
@@ -5,6 +5,7 @@
 import frappe
 from frappe import _
 from frappe.utils import flt, today
+from pypika.terms import ExistsCriterion
 
 from erpnext.accounts.doctype.pos_invoice.pos_invoice import get_pos_reserved_qty
 from erpnext.stock.utils import (
@@ -218,10 +219,26 @@
 
 
 def get_bin_list(filters):
-	conditions = []
+	bin = frappe.qb.DocType("Bin")
+	query = (
+		frappe.qb.from_(bin)
+		.select(
+			bin.item_code,
+			bin.warehouse,
+			bin.actual_qty,
+			bin.planned_qty,
+			bin.indented_qty,
+			bin.ordered_qty,
+			bin.reserved_qty,
+			bin.reserved_qty_for_production,
+			bin.reserved_qty_for_sub_contract,
+			bin.projected_qty,
+		)
+		.orderby(bin.item_code, bin.warehouse)
+	)
 
 	if filters.item_code:
-		conditions.append("item_code = '%s' " % filters.item_code)
+		query = query.where(bin.item_code == filters.item_code)
 
 	if filters.warehouse:
 		warehouse_details = frappe.db.get_value(
@@ -229,21 +246,20 @@
 		)
 
 		if warehouse_details:
-			conditions.append(
-				" exists (select name from `tabWarehouse` wh \
-				where wh.lft >= %s and wh.rgt <= %s and bin.warehouse = wh.name)"
-				% (warehouse_details.lft, warehouse_details.rgt)
+			wh = frappe.qb.DocType("Warehouse")
+			query = query.where(
+				ExistsCriterion(
+					frappe.qb.from_(wh)
+					.select(wh.name)
+					.where(
+						(wh.lft >= warehouse_details.lft)
+						& (wh.rgt <= warehouse_details.rgt)
+						& (bin.warehouse == wh.name)
+					)
+				)
 			)
 
-	bin_list = frappe.db.sql(
-		"""select item_code, warehouse, actual_qty, planned_qty, indented_qty,
-		ordered_qty, reserved_qty, reserved_qty_for_production, reserved_qty_for_sub_contract, projected_qty
-		from tabBin bin {conditions} order by item_code, warehouse
-		""".format(
-			conditions=" where " + " and ".join(conditions) if conditions else ""
-		),
-		as_dict=1,
-	)
+	bin_list = query.run(as_dict=True)
 
 	return bin_list
 
@@ -251,45 +267,43 @@
 def get_item_map(item_code, include_uom):
 	"""Optimization: get only the item doc and re_order_levels table"""
 
-	condition = ""
-	if item_code:
-		condition = "and item_code = {0}".format(frappe.db.escape(item_code, percent=False))
+	bin = frappe.qb.DocType("Bin")
+	item = frappe.qb.DocType("Item")
 
-	cf_field = cf_join = ""
-	if include_uom:
-		cf_field = ", ucd.conversion_factor"
-		cf_join = (
-			"left join `tabUOM Conversion Detail` ucd on ucd.parent=item.name and ucd.uom=%(include_uom)s"
+	query = (
+		frappe.qb.from_(item)
+		.select(item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom)
+		.where(
+			(item.is_stock_item == 1)
+			& (item.disabled == 0)
+			& (
+				(item.end_of_life > today()) | (item.end_of_life.isnull()) | (item.end_of_life == "0000-00-00")
+			)
+			& (ExistsCriterion(frappe.qb.from_(bin).select(bin.name).where(bin.item_code == item.name)))
 		)
-
-	items = frappe.db.sql(
-		"""
-		select item.name, item.item_name, item.description, item.item_group, item.brand, item.stock_uom{cf_field}
-		from `tabItem` item
-		{cf_join}
-		where item.is_stock_item = 1
-		and item.disabled=0
-		{condition}
-		and (item.end_of_life > %(today)s or item.end_of_life is null or item.end_of_life='0000-00-00')
-		and exists (select name from `tabBin` bin where bin.item_code=item.name)""".format(
-			cf_field=cf_field, cf_join=cf_join, condition=condition
-		),
-		{"today": today(), "include_uom": include_uom},
-		as_dict=True,
 	)
 
-	condition = ""
 	if item_code:
-		condition = "where parent={0}".format(frappe.db.escape(item_code, percent=False))
+		query = query.where(item.item_code == item_code)
+
+	if include_uom:
+		ucd = frappe.qb.DocType("UOM Conversion Detail")
+		query = query.left_join(ucd).on((ucd.parent == item.name) & (ucd.uom == include_uom))
+
+	items = query.run(as_dict=True)
+
+	ir = frappe.qb.DocType("Item Reorder")
+	query = frappe.qb.from_(ir).select("*")
+
+	if item_code:
+		query = query.where(ir.parent == item_code)
 
 	reorder_levels = frappe._dict()
-	for ir in frappe.db.sql(
-		"""select * from `tabItem Reorder` {condition}""".format(condition=condition), as_dict=1
-	):
-		if ir.parent not in reorder_levels:
-			reorder_levels[ir.parent] = []
+	for d in query.run(as_dict=True):
+		if d.parent not in reorder_levels:
+			reorder_levels[d.parent] = []
 
-		reorder_levels[ir.parent].append(ir)
+		reorder_levels[d.parent].append(d)
 
 	item_map = frappe._dict()
 	for item in items:
diff --git a/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py b/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
index 5430fe6..8c76908 100644
--- a/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
+++ b/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
@@ -4,6 +4,7 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import IfNull
 from frappe.utils import flt
 
 
@@ -70,31 +71,33 @@
 	return columns
 
 
-def get_conditions(filters):
-	conditions = ""
-	values = []
+def get_consumed_details(filters):
+	item = frappe.qb.DocType("Item")
+	sle = frappe.qb.DocType("Stock Ledger Entry")
+
+	query = (
+		frappe.qb.from_(sle)
+		.from_(item)
+		.select(
+			sle.item_code,
+			item.item_name,
+			item.description,
+			item.stock_uom,
+			sle.actual_qty,
+			sle.stock_value_difference,
+			sle.voucher_no,
+			sle.voucher_type,
+		)
+		.where((sle.is_cancelled == 0) & (sle.item_code == item.name) & (sle.actual_qty < 0))
+	)
 
 	if filters.get("from_date") and filters.get("to_date"):
-		conditions = "and sle.posting_date>=%s and sle.posting_date<=%s"
-		values = [filters.get("from_date"), filters.get("to_date")]
+		query = query.where(
+			(sle.posting_date >= filters.get("from_date")) & (sle.posting_date <= filters.get("to_date"))
+		)
 
-	return conditions, values
-
-
-def get_consumed_details(filters):
-	conditions, values = get_conditions(filters)
 	consumed_details = {}
-
-	for d in frappe.db.sql(
-		"""select sle.item_code, i.item_name, i.description,
-		i.stock_uom, sle.actual_qty, sle.stock_value_difference,
-		sle.voucher_no, sle.voucher_type
-		from `tabStock Ledger Entry` sle, `tabItem` i
-		where sle.is_cancelled = 0 and sle.item_code=i.name and sle.actual_qty < 0 %s"""
-		% conditions,
-		values,
-		as_dict=1,
-	):
+	for d in query.run(as_dict=True):
 		consumed_details.setdefault(d.item_code, []).append(d)
 
 	return consumed_details
@@ -104,24 +107,54 @@
 	item_supplier_map = {}
 	supplier = filters.get("supplier")
 
-	for d in frappe.db.sql(
-		"""select pr.supplier, pri.item_code from
-		`tabPurchase Receipt` pr, `tabPurchase Receipt Item` pri
-		where pr.name=pri.parent and pr.docstatus=1 and
-		pri.item_code=(select name from `tabItem` where
-			is_stock_item=1 and name=pri.item_code)""",
-		as_dict=1,
-	):
+	item = frappe.qb.DocType("Item")
+	pr = frappe.qb.DocType("Purchase Receipt")
+	pr_item = frappe.qb.DocType("Purchase Receipt Item")
+
+	query = (
+		frappe.qb.from_(pr)
+		.from_(pr_item)
+		.select(pr.supplier, pr_item.item_code)
+		.where(
+			(pr.name == pr_item.parent)
+			& (pr.docstatus == 1)
+			& (
+				pr_item.item_code
+				== (
+					frappe.qb.from_(item)
+					.select(item.name)
+					.where((item.is_stock_item == 1) & (item.name == pr_item.item_code))
+				)
+			)
+		)
+	)
+
+	for d in query.run(as_dict=True):
 		item_supplier_map.setdefault(d.item_code, []).append(d.supplier)
 
-	for d in frappe.db.sql(
-		"""select pr.supplier, pri.item_code from
-		`tabPurchase Invoice` pr, `tabPurchase Invoice Item` pri
-		where pr.name=pri.parent and pr.docstatus=1 and
-		ifnull(pr.update_stock, 0) = 1 and pri.item_code=(select name from `tabItem`
-			where is_stock_item=1 and name=pri.item_code)""",
-		as_dict=1,
-	):
+	pi = frappe.qb.DocType("Purchase Invoice")
+	pi_item = frappe.qb.DocType("Purchase Invoice Item")
+
+	query = (
+		frappe.qb.from_(pi)
+		.from_(pi_item)
+		.select(pi.supplier, pi_item.item_code)
+		.where(
+			(pi.name == pi_item.parent)
+			& (pi.docstatus == 1)
+			& (IfNull(pi.update_stock, 0) == 1)
+			& (
+				pi_item.item_code
+				== (
+					frappe.qb.from_(item)
+					.select(item.name)
+					.where((item.is_stock_item == 1) & (item.name == pi_item.item_code))
+				)
+			)
+		)
+	)
+
+	for d in query.run(as_dict=True):
 		if d.item_code not in item_supplier_map:
 			item_supplier_map.setdefault(d.item_code, []).append(d.supplier)
 
@@ -138,7 +171,11 @@
 
 
 def get_material_transfer_vouchers():
-	return frappe.db.sql_list(
-		"""select name from `tabStock Entry` where
-		purpose='Material Transfer' and docstatus=1"""
+	se = frappe.qb.DocType("Stock Entry")
+	query = (
+		frappe.qb.from_(se)
+		.select(se.name)
+		.where((se.purpose == "Material Transfer") & (se.docstatus == 1))
 	)
+
+	return [r[0] for r in query.run()]
diff --git a/erpnext/stock/report/total_stock_summary/total_stock_summary.py b/erpnext/stock/report/total_stock_summary/total_stock_summary.py
index 21529da..c3155bd 100644
--- a/erpnext/stock/report/total_stock_summary/total_stock_summary.py
+++ b/erpnext/stock/report/total_stock_summary/total_stock_summary.py
@@ -4,60 +4,58 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import Sum
 
 
 def execute(filters=None):
 
 	if not filters:
 		filters = {}
-	columns = get_columns()
+	columns = get_columns(filters)
 	stock = get_total_stock(filters)
 
 	return columns, stock
 
 
-def get_columns():
+def get_columns(filters):
 	columns = [
-		_("Company") + ":Link/Company:250",
-		_("Warehouse") + ":Link/Warehouse:150",
 		_("Item") + ":Link/Item:150",
 		_("Description") + "::300",
 		_("Current Qty") + ":Float:100",
 	]
 
+	if filters.get("group_by") == "Warehouse":
+		columns.insert(0, _("Warehouse") + ":Link/Warehouse:150")
+	else:
+		columns.insert(0, _("Company") + ":Link/Company:250")
+
 	return columns
 
 
 def get_total_stock(filters):
-	conditions = ""
-	columns = ""
+	bin = frappe.qb.DocType("Bin")
+	item = frappe.qb.DocType("Item")
+	wh = frappe.qb.DocType("Warehouse")
+
+	query = (
+		frappe.qb.from_(bin)
+		.inner_join(item)
+		.on(bin.item_code == item.item_code)
+		.inner_join(wh)
+		.on(wh.name == bin.warehouse)
+		.where(bin.actual_qty != 0)
+	)
 
 	if filters.get("group_by") == "Warehouse":
 		if filters.get("company"):
-			conditions += " AND warehouse.company = %s" % frappe.db.escape(
-				filters.get("company"), percent=False
-			)
+			query = query.where(wh.company == filters.get("company"))
 
-		conditions += " GROUP BY ledger.warehouse, item.item_code"
-		columns += "'' as company, ledger.warehouse"
+		query = query.select(bin.warehouse).groupby(bin.warehouse)
 	else:
-		conditions += " GROUP BY warehouse.company, item.item_code"
-		columns += " warehouse.company, '' as warehouse"
+		query = query.select(wh.company).groupby(wh.company)
 
-	return frappe.db.sql(
-		"""
-			SELECT
-				%s,
-				item.item_code,
-				item.description,
-				sum(ledger.actual_qty) as actual_qty
-			FROM
-				`tabBin` AS ledger
-			INNER JOIN `tabItem` AS item
-				ON ledger.item_code = item.item_code
-			INNER JOIN `tabWarehouse` warehouse
-				ON warehouse.name = ledger.warehouse
-			WHERE
-				ledger.actual_qty != 0 %s"""
-		% (columns, conditions)
-	)
+	query = query.select(
+		item.item_code, item.description, Sum(bin.actual_qty).as_("actual_qty")
+	).groupby(item.item_code)
+
+	return query.run()
diff --git a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
index a54373f..eedf1a0 100644
--- a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
+++ b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
@@ -7,6 +7,7 @@
 
 import frappe
 from frappe import _
+from frappe.query_builder.functions import Count
 from frappe.utils import flt
 
 from erpnext.stock.report.stock_ageing.stock_ageing import FIFOSlots, get_average_age
@@ -98,7 +99,7 @@
 
 def validate_filters(filters):
 	if not (filters.get("item_code") or filters.get("warehouse")):
-		sle_count = flt(frappe.db.sql("""select count(name) from `tabStock Ledger Entry`""")[0][0])
+		sle_count = flt(frappe.qb.from_("Stock Ledger Entry").select(Count("name")).run()[0][0])
 		if sle_count > 500000:
 			frappe.throw(_("Please set filter based on Item or Warehouse"))
 	if not filters.get("company"):
@@ -108,25 +109,16 @@
 def get_warehouse_list(filters):
 	from frappe.core.doctype.user_permission.user_permission import get_permitted_documents
 
-	condition = ""
-	user_permitted_warehouse = get_permitted_documents("Warehouse")
-	value = ()
-	if user_permitted_warehouse:
-		condition = "and name in %s"
-		value = set(user_permitted_warehouse)
-	elif not user_permitted_warehouse and filters.get("warehouse"):
-		condition = "and name = %s"
-		value = filters.get("warehouse")
+	wh = frappe.qb.DocType("Warehouse")
+	query = frappe.qb.from_(wh).select(wh.name).where(wh.is_group == 0)
 
-	return frappe.db.sql(
-		"""select name
-		from `tabWarehouse` where is_group = 0
-		{condition}""".format(
-			condition=condition
-		),
-		value,
-		as_dict=1,
-	)
+	user_permitted_warehouse = get_permitted_documents("Warehouse")
+	if user_permitted_warehouse:
+		query = query.where(wh.name.isin(set(user_permitted_warehouse)))
+	elif filters.get("warehouse"):
+		query = query.where(wh.name == filters.get("warehouse"))
+
+	return query.run(as_dict=True)
 
 
 def add_warehouse_column(columns, warehouse_list):
diff --git a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
index 4e00138..472f6bc 100644
--- a/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
+++ b/erpnext/support/doctype/service_level_agreement/test_service_level_agreement.py
@@ -15,8 +15,30 @@
 
 class TestServiceLevelAgreement(unittest.TestCase):
 	def setUp(self):
+		self.create_company()
 		frappe.db.set_value("Support Settings", None, "track_service_level_agreement", 1)
-		frappe.db.sql("delete from `tabLead`")
+		lead = frappe.qb.DocType("Lead")
+		frappe.qb.from_(lead).delete().where(lead.company == self.company).run()
+
+	def create_company(self):
+		name = "_Test Support SLA"
+		company = None
+		if frappe.db.exists("Company", name):
+			company = frappe.get_doc("Company", name)
+		else:
+			company = frappe.get_doc(
+				{
+					"doctype": "Company",
+					"company_name": name,
+					"country": "India",
+					"default_currency": "INR",
+					"create_chart_of_accounts_based_on": "Standard Template",
+					"chart_of_accounts": "Standard",
+				}
+			)
+			company = company.save()
+
+		self.company = company.name
 
 	def test_service_level_agreement(self):
 		# Default Service Level Agreement
@@ -205,7 +227,7 @@
 
 		# make lead with default SLA
 		creation = datetime.datetime(2019, 3, 4, 12, 0)
-		lead = make_lead(creation=creation, index=1)
+		lead = make_lead(creation=creation, index=1, company=self.company)
 
 		self.assertEqual(lead.service_level_agreement, lead_sla.name)
 		self.assertEqual(lead.response_by, datetime.datetime(2019, 3, 4, 16, 0))
@@ -233,7 +255,7 @@
 		)
 
 		creation = datetime.datetime(2020, 3, 4, 4, 0)
-		lead = make_lead(creation, index=2)
+		lead = make_lead(creation, index=2, company=self.company)
 
 		frappe.flags.current_time = datetime.datetime(2020, 3, 4, 4, 15)
 		lead.reload()
@@ -267,7 +289,7 @@
 		)
 
 		creation = datetime.datetime(2019, 3, 4, 12, 0)
-		lead = make_lead(creation=creation, index=1)
+		lead = make_lead(creation=creation, index=1, company=self.company)
 		self.assertEqual(lead.response_by, datetime.datetime(2019, 3, 4, 16, 0))
 
 		# failed with response time only
@@ -294,7 +316,7 @@
 
 		# fulfilled with response time only
 		creation = datetime.datetime(2019, 3, 4, 12, 0)
-		lead = make_lead(creation=creation, index=2)
+		lead = make_lead(creation=creation, index=2, company=self.company)
 
 		self.assertEqual(lead.service_level_agreement, lead_sla.name)
 		self.assertEqual(lead.response_by, datetime.datetime(2019, 3, 4, 16, 0))
@@ -321,7 +343,7 @@
 			apply_sla_for_resolution=0,
 		)
 		creation = datetime.datetime(2019, 3, 4, 12, 0)
-		lead = make_lead(creation=creation, index=4)
+		lead = make_lead(creation=creation, index=4, company=self.company)
 		applied_sla = frappe.db.get_value("Lead", lead.name, "service_level_agreement")
 		self.assertFalse(applied_sla)
 
@@ -611,7 +633,7 @@
 		return frappe.get_doc("DocType", "Test SLA on Custom Dt")
 
 
-def make_lead(creation=None, index=0):
+def make_lead(creation=None, index=0, company=None):
 	return frappe.get_doc(
 		{
 			"doctype": "Lead",
@@ -621,5 +643,6 @@
 			"creation": creation,
 			"service_level_agreement_creation": creation,
 			"priority": "Medium",
+			"company": company,
 		}
 	).insert(ignore_permissions=True)
diff --git a/erpnext/utilities/doctype/video/video.py b/erpnext/utilities/doctype/video/video.py
index 15dbccd..13b7877 100644
--- a/erpnext/utilities/doctype/video/video.py
+++ b/erpnext/utilities/doctype/video/video.py
@@ -59,7 +59,7 @@
 		"Video Settings", "Video Settings", ["enable_youtube_tracking", "frequency"]
 	)
 
-	if not enable_youtube_tracking:
+	if not cint(enable_youtube_tracking):
 		return
 
 	frequency = get_frequency(frequency)