Merge branch 'develop' of https://github.com/frappe/erpnext into payment_request_flow
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 325a356..220b747 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
@@ -485,6 +485,10 @@
 			"default_payable_account": frappe.db.get_value(
 				"Account", {"company": company.name, "account_type": "Payable", "is_group": 0}
 			),
+			"default_provisional_account": frappe.db.get_value(
+				"Account",
+				{"company": company.name, "account_type": "Service Received But Not Billed", "is_group": 0},
+			),
 		}
 	)
 
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 1714fff..b63d57c 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -34,9 +34,6 @@
 	def __init__(self, *args, **kwargs):
 		super(JournalEntry, self).__init__(*args, **kwargs)
 
-	def get_feed(self):
-		return self.voucher_type
-
 	def validate(self):
 		if self.voucher_type == "Opening Entry":
 			self.is_opening = "Yes"
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.json b/erpnext/accounts/doctype/payment_entry/payment_entry.json
index 3fc1adf..4a7a57b 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.json
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.json
@@ -305,6 +305,7 @@
    "fieldname": "source_exchange_rate",
    "fieldtype": "Float",
    "label": "Exchange Rate",
+   "precision": "9",
    "print_hide": 1,
    "reqd": 1
   },
@@ -334,6 +335,7 @@
    "fieldname": "target_exchange_rate",
    "fieldtype": "Float",
    "label": "Exchange Rate",
+   "precision": "9",
    "print_hide": 1,
    "reqd": 1
   },
@@ -731,7 +733,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-02-23 20:08:39.559814",
+ "modified": "2022-12-08 16:25:43.824051",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Entry",
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 052b1df..79fab64 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -684,35 +684,34 @@
 		)
 
 	def validate_payment_against_negative_invoice(self):
-		if (self.payment_type == "Pay" and self.party_type == "Customer") or (
-			self.payment_type == "Receive" and self.party_type == "Supplier"
+		if (self.payment_type != "Pay" or self.party_type != "Customer") and (
+			self.payment_type != "Receive" or self.party_type != "Supplier"
 		):
+			return
 
-			total_negative_outstanding = sum(
-				abs(flt(d.outstanding_amount)) for d in self.get("references") if flt(d.outstanding_amount) < 0
+		total_negative_outstanding = sum(
+			abs(flt(d.outstanding_amount)) for d in self.get("references") if flt(d.outstanding_amount) < 0
+		)
+
+		paid_amount = self.paid_amount if self.payment_type == "Receive" else self.received_amount
+		additional_charges = sum(flt(d.amount) for d in self.deductions)
+
+		if not total_negative_outstanding:
+			if self.party_type == "Customer":
+				msg = _("Cannot pay to Customer without any negative outstanding invoice")
+			else:
+				msg = _("Cannot receive from Supplier without any negative outstanding invoice")
+
+			frappe.throw(msg, InvalidPaymentEntry)
+
+		elif paid_amount - additional_charges > total_negative_outstanding:
+			frappe.throw(
+				_("Paid Amount cannot be greater than total negative outstanding amount {0}").format(
+					total_negative_outstanding
+				),
+				InvalidPaymentEntry,
 			)
 
-			paid_amount = self.paid_amount if self.payment_type == "Receive" else self.received_amount
-			additional_charges = sum([flt(d.amount) for d in self.deductions])
-
-			if not total_negative_outstanding:
-				frappe.throw(
-					_("Cannot {0} {1} {2} without any negative outstanding invoice").format(
-						_(self.payment_type),
-						(_("to") if self.party_type == "Customer" else _("from")),
-						self.party_type,
-					),
-					InvalidPaymentEntry,
-				)
-
-			elif paid_amount - additional_charges > total_negative_outstanding:
-				frappe.throw(
-					_("Paid Amount cannot be greater than total negative outstanding amount {0}").format(
-						total_negative_outstanding
-					),
-					InvalidPaymentEntry,
-				)
-
 	def set_title(self):
 		if frappe.flags.in_import and self.title:
 			# do not set title dynamically if title exists during data import.
@@ -1188,6 +1187,7 @@
 
 	ple = qb.DocType("Payment Ledger Entry")
 	common_filter = []
+	accounting_dimensions_filter = []
 	posting_and_due_date = []
 
 	# confirm that Supplier is not blocked
@@ -1217,7 +1217,7 @@
 	# Add cost center condition
 	if args.get("cost_center"):
 		condition += " and cost_center='%s'" % args.get("cost_center")
-		common_filter.append(ple.cost_center == args.get("cost_center"))
+		accounting_dimensions_filter.append(ple.cost_center == args.get("cost_center"))
 
 	date_fields_dict = {
 		"posting_date": ["from_posting_date", "to_posting_date"],
@@ -1243,6 +1243,7 @@
 		posting_date=posting_and_due_date,
 		min_outstanding=args.get("outstanding_amt_greater_than"),
 		max_outstanding=args.get("outstanding_amt_less_than"),
+		accounting_dimensions=accounting_dimensions_filter,
 	)
 
 	outstanding_invoices = split_invoices_based_on_payment_terms(outstanding_invoices)
diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
index 8961167..3003c68 100644
--- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
+++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
@@ -25,7 +25,8 @@
    "in_list_view": 1,
    "label": "Type",
    "options": "DocType",
-   "reqd": 1
+   "reqd": 1,
+   "search_index": 1
   },
   {
    "columns": 2,
@@ -35,7 +36,8 @@
    "in_list_view": 1,
    "label": "Name",
    "options": "reference_doctype",
-   "reqd": 1
+   "reqd": 1,
+   "search_index": 1
   },
   {
    "fieldname": "due_date",
@@ -104,7 +106,7 @@
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-09-26 17:06:55.597389",
+ "modified": "2022-12-12 12:31:44.919895",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Entry Reference",
@@ -113,5 +115,6 @@
  "quick_entry": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 52efd33..ff212f2 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -23,6 +23,7 @@
 	def __init__(self, *args, **kwargs):
 		super(PaymentReconciliation, self).__init__(*args, **kwargs)
 		self.common_filter_conditions = []
+		self.accounting_dimension_filter_conditions = []
 		self.ple_posting_date_filter = []
 
 	@frappe.whitelist()
@@ -193,6 +194,7 @@
 			posting_date=self.ple_posting_date_filter,
 			min_outstanding=self.minimum_invoice_amount if self.minimum_invoice_amount else None,
 			max_outstanding=self.maximum_invoice_amount if self.maximum_invoice_amount else None,
+			accounting_dimensions=self.accounting_dimension_filter_conditions,
 		)
 
 		if self.invoice_limit:
@@ -381,7 +383,7 @@
 		self.common_filter_conditions.append(ple.company == self.company)
 
 		if self.get("cost_center") and (get_invoices or get_return_invoices):
-			self.common_filter_conditions.append(ple.cost_center == self.cost_center)
+			self.accounting_dimension_filter_conditions.append(ple.cost_center == self.cost_center)
 
 		if get_invoices:
 			if self.from_invoice_date:
diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
index dae029b..6030134 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
@@ -8,6 +8,8 @@
 from frappe.tests.utils import FrappeTestCase
 from frappe.utils import add_days, nowdate
 
+from erpnext import get_default_cost_center
+from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
 from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.accounts.party import get_party_account
@@ -20,6 +22,7 @@
 		self.create_item()
 		self.create_customer()
 		self.create_account()
+		self.create_cost_center()
 		self.clear_old_entries()
 
 	def tearDown(self):
@@ -216,6 +219,22 @@
 		)
 		return je
 
+	def create_cost_center(self):
+		# Setup cost center
+		cc_name = "Sub"
+
+		self.main_cc = frappe.get_doc("Cost Center", get_default_cost_center(self.company))
+
+		cc_exists = frappe.db.get_list("Cost Center", filters={"cost_center_name": cc_name})
+		if cc_exists:
+			self.sub_cc = frappe.get_doc("Cost Center", cc_exists[0].name)
+		else:
+			sub_cc = frappe.new_doc("Cost Center")
+			sub_cc.cost_center_name = "Sub"
+			sub_cc.parent_cost_center = self.main_cc.parent_cost_center
+			sub_cc.company = self.main_cc.company
+			self.sub_cc = sub_cc.save()
+
 	def test_filter_min_max(self):
 		# check filter condition minimum and maximum amount
 		self.create_sales_invoice(qty=1, rate=300)
@@ -578,3 +597,24 @@
 		self.assertEqual(len(pr.payments), 1)
 		self.assertEqual(pr.payments[0].amount, amount)
 		self.assertEqual(pr.payments[0].currency, "EUR")
+
+	def test_differing_cost_center_on_invoice_and_payment(self):
+		"""
+		Cost Center filter should not affect outstanding amount calculation
+		"""
+
+		si = self.create_sales_invoice(qty=1, rate=100, do_not_submit=True)
+		si.cost_center = self.main_cc.name
+		si.submit()
+		pr = get_payment_entry(si.doctype, si.name)
+		pr.cost_center = self.sub_cc.name
+		pr = pr.save().submit()
+
+		pr = self.create_payment_reconciliation()
+		pr.cost_center = self.main_cc.name
+
+		pr.get_unreconciled_entries()
+
+		# check PR tool output
+		self.assertEqual(len(pr.get("invoices")), 0)
+		self.assertEqual(len(pr.get("payments")), 0)
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index b666e0d..2943500 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -255,7 +255,7 @@
 	for item in item_list:
 		args_copy = copy.deepcopy(args)
 		args_copy.update(item)
-		data = get_pricing_rule_for_item(args_copy, item.get("price_list_rate"), doc=doc)
+		data = get_pricing_rule_for_item(args_copy, doc=doc)
 		out.append(data)
 
 		if (
@@ -292,7 +292,7 @@
 			pricing_rule.uom = row.uom
 
 
-def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=False):
+def get_pricing_rule_for_item(args, doc=None, for_validate=False):
 	from erpnext.accounts.doctype.pricing_rule.utils import (
 		get_applied_pricing_rules,
 		get_pricing_rule_items,
diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
index d27f65e..5bb366a 100644
--- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
@@ -1123,7 +1123,7 @@
 			"apply_on": args.apply_on or "Item Code",
 			"applicable_for": args.applicable_for,
 			"selling": args.selling or 0,
-			"currency": "USD",
+			"currency": "INR",
 			"apply_discount_on_rate": args.apply_discount_on_rate or 0,
 			"buying": args.buying or 0,
 			"min_qty": args.min_qty or 0.0,
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index bb54b23..3989f8a 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -250,6 +250,17 @@
 			and ifnull(`tabPricing Rule`.valid_upto, '2500-12-31')"""
 		values["transaction_date"] = args.get("transaction_date")
 
+	if args.get("doctype") in [
+		"Quotation",
+		"Sales Order",
+		"Delivery Note",
+		"Sales Invoice",
+		"POS Invoice",
+	]:
+		conditions += """ and ifnull(`tabPricing Rule`.selling, 0) = 1"""
+	else:
+		conditions += """ and ifnull(`tabPricing Rule`.buying, 0) = 1"""
+
 	return conditions
 
 
@@ -669,7 +680,7 @@
 	item_details.free_item_data.append(free_item_data_args)
 
 
-def apply_pricing_rule_for_free_items(doc, pricing_rule_args, set_missing_values=False):
+def apply_pricing_rule_for_free_items(doc, pricing_rule_args):
 	if pricing_rule_args:
 		items = tuple((d.item_code, d.pricing_rules) for d in doc.items if d.is_free_item)
 
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index a03157e..6281400 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -64,12 +64,13 @@
   "tax_withholding_net_total",
   "base_tax_withholding_net_total",
   "taxes_section",
+  "tax_category",
   "taxes_and_charges",
   "column_break_58",
-  "tax_category",
-  "column_break_49",
   "shipping_rule",
+  "column_break_49",
   "incoterm",
+  "named_place",
   "section_break_51",
   "taxes",
   "totals",
@@ -1541,13 +1542,19 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 204,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-25 12:44:29.935567",
+ "modified": "2022-12-12 18:37:38.142688",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index b38bce7..4729d9c 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -61,12 +61,13 @@
   "total",
   "net_total",
   "taxes_section",
+  "tax_category",
   "taxes_and_charges",
   "column_break_38",
   "shipping_rule",
-  "incoterm",
   "column_break_55",
-  "tax_category",
+  "incoterm",
+  "named_place",
   "section_break_40",
   "taxes",
   "section_break_43",
@@ -2122,6 +2123,12 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-file-text",
@@ -2134,7 +2141,7 @@
    "link_fieldname": "consolidated_invoice"
   }
  ],
- "modified": "2022-12-05 16:18:14.532114",
+ "modified": "2022-12-12 18:34:33.409895",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/accounts/doctype/subscription/subscription.py b/erpnext/accounts/doctype/subscription/subscription.py
index 9dab4e9..8708342 100644
--- a/erpnext/accounts/doctype/subscription/subscription.py
+++ b/erpnext/accounts/doctype/subscription/subscription.py
@@ -280,7 +280,8 @@
 		self.validate_plans_billing_cycle(self.get_billing_cycle_and_interval())
 		self.validate_end_date()
 		self.validate_to_follow_calendar_months()
-		self.cost_center = erpnext.get_default_cost_center(self.get("company"))
+		if not self.cost_center:
+			self.cost_center = erpnext.get_default_cost_center(self.get("company"))
 
 	def validate_trial_period(self):
 		"""
diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
index 30ed91b..b834d14 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
@@ -121,12 +121,24 @@
 	else:
 		tax_row = get_tax_row_for_tcs(inv, tax_details, tax_amount, tax_deducted)
 
+	cost_center = get_cost_center(inv)
+	tax_row.update({"cost_center": cost_center})
+
 	if inv.doctype == "Purchase Invoice":
 		return tax_row, tax_deducted_on_advances, voucher_wise_amount
 	else:
 		return tax_row
 
 
+def get_cost_center(inv):
+	cost_center = frappe.get_cached_value("Company", inv.company, "cost_center")
+
+	if len(inv.get("taxes", [])) > 0:
+		cost_center = inv.get("taxes")[0].cost_center
+
+	return cost_center
+
+
 def get_tax_withholding_details(tax_withholding_category, posting_date, company):
 	tax_withholding = frappe.get_doc("Tax Withholding Category", tax_withholding_category)
 
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index a195c57..9d96843 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -99,6 +99,9 @@
 		# Get return entries
 		self.get_return_entries()
 
+		# Get Exchange Rate Revaluations
+		self.get_exchange_rate_revaluations()
+
 		self.data = []
 
 		for ple in self.ple_entries:
@@ -251,7 +254,8 @@
 			row.invoice_grand_total = row.invoiced
 
 			if (abs(row.outstanding) > 1.0 / 10**self.currency_precision) and (
-				abs(row.outstanding_in_account_currency) > 1.0 / 10**self.currency_precision
+				(abs(row.outstanding_in_account_currency) > 1.0 / 10**self.currency_precision)
+				or (row.voucher_no in self.err_journals)
 			):
 
 				# non-zero oustanding, we must consider this row
@@ -1028,3 +1032,17 @@
 			"data": {"labels": self.ageing_column_labels, "datasets": rows},
 			"type": "percentage",
 		}
+
+	def get_exchange_rate_revaluations(self):
+		je = qb.DocType("Journal Entry")
+		results = (
+			qb.from_(je)
+			.select(je.name)
+			.where(
+				(je.company == self.filters.company)
+				& (je.posting_date.lte(self.filters.report_date))
+				& (je.voucher_type == "Exchange Rate Revaluation")
+			)
+			.run()
+		)
+		self.err_journals = [x[0] for x in results] if results else []
diff --git a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
index bac8bee..97a9c15 100644
--- a/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
@@ -1,9 +1,10 @@
 import unittest
 
 import frappe
-from frappe.tests.utils import FrappeTestCase
-from frappe.utils import add_days, getdate, today
+from frappe.tests.utils import FrappeTestCase, change_settings
+from frappe.utils import add_days, flt, getdate, today
 
+from erpnext import get_default_cost_center
 from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.accounts.report.accounts_receivable.accounts_receivable import execute
@@ -17,10 +18,37 @@
 		frappe.db.sql("delete from `tabPayment Entry` where company='_Test Company 2'")
 		frappe.db.sql("delete from `tabGL Entry` where company='_Test Company 2'")
 		frappe.db.sql("delete from `tabPayment Ledger Entry` where company='_Test Company 2'")
+		frappe.db.sql("delete from `tabJournal Entry` where company='_Test Company 2'")
+		frappe.db.sql("delete from `tabExchange Rate Revaluation` where company='_Test Company 2'")
+
+		self.create_usd_account()
 
 	def tearDown(self):
 		frappe.db.rollback()
 
+	def create_usd_account(self):
+		name = "Debtors USD"
+		exists = frappe.db.get_list(
+			"Account", filters={"company": "_Test Company 2", "account_name": "Debtors USD"}
+		)
+		if exists:
+			self.debtors_usd = exists[0].name
+		else:
+			debtors = frappe.get_doc(
+				"Account",
+				frappe.db.get_list(
+					"Account", filters={"company": "_Test Company 2", "account_name": "Debtors"}
+				)[0].name,
+			)
+
+			debtors_usd = frappe.new_doc("Account")
+			debtors_usd.company = debtors.company
+			debtors_usd.account_name = "Debtors USD"
+			debtors_usd.account_currency = "USD"
+			debtors_usd.parent_account = debtors.parent_account
+			debtors_usd.account_type = debtors.account_type
+			self.debtors_usd = debtors_usd.save().name
+
 	def test_accounts_receivable(self):
 		filters = {
 			"company": "_Test Company 2",
@@ -33,7 +61,7 @@
 		}
 
 		# check invoice grand total and invoiced column's value for 3 payment terms
-		name = make_sales_invoice()
+		name = make_sales_invoice().name
 		report = execute(filters)
 
 		expected_data = [[100, 30], [100, 50], [100, 20]]
@@ -118,8 +146,74 @@
 			],
 		)
 
+	@change_settings(
+		"Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1}
+	)
+	def test_exchange_revaluation_for_party(self):
+		"""
+		Exchange Revaluation for party on Receivable/Payable shoule be included
+		"""
 
-def make_sales_invoice():
+		company = "_Test Company 2"
+		customer = "_Test Customer 2"
+
+		# Using Exchange Gain/Loss account for unrealized as well.
+		company_doc = frappe.get_doc("Company", company)
+		company_doc.unrealized_exchange_gain_loss_account = company_doc.exchange_gain_loss_account
+		company_doc.save()
+
+		si = make_sales_invoice(no_payment_schedule=True, do_not_submit=True)
+		si.currency = "USD"
+		si.conversion_rate = 0.90
+		si.debit_to = self.debtors_usd
+		si = si.save().submit()
+
+		# Exchange Revaluation
+		err = frappe.new_doc("Exchange Rate Revaluation")
+		err.company = company
+		err.posting_date = today()
+		accounts = err.get_accounts_data()
+		err.extend("accounts", accounts)
+		err.accounts[0].new_exchange_rate = 0.95
+		row = err.accounts[0]
+		row.new_balance_in_base_currency = flt(
+			row.new_exchange_rate * flt(row.balance_in_account_currency)
+		)
+		row.gain_loss = row.new_balance_in_base_currency - flt(row.balance_in_base_currency)
+		err.set_total_gain_loss()
+		err = err.save().submit()
+
+		# Submit JV for ERR
+		jv = frappe.get_doc(err.make_jv_entry())
+		jv = jv.save()
+		for x in jv.accounts:
+			x.cost_center = get_default_cost_center(jv.company)
+		jv.submit()
+
+		filters = {
+			"company": company,
+			"report_date": today(),
+			"range1": 30,
+			"range2": 60,
+			"range3": 90,
+			"range4": 120,
+		}
+		report = execute(filters)
+
+		expected_data_for_err = [0, -5, 0, 5]
+		row = [x for x in report[1] if x.voucher_type == jv.doctype and x.voucher_no == jv.name][0]
+		self.assertEqual(
+			expected_data_for_err,
+			[
+				row.invoiced,
+				row.paid,
+				row.credit_note,
+				row.outstanding,
+			],
+		)
+
+
+def make_sales_invoice(no_payment_schedule=False, do_not_submit=False):
 	frappe.set_user("Administrator")
 
 	si = create_sales_invoice(
@@ -134,22 +228,26 @@
 		do_not_save=1,
 	)
 
-	si.append(
-		"payment_schedule",
-		dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30),
-	)
-	si.append(
-		"payment_schedule",
-		dict(due_date=getdate(add_days(today(), 60)), invoice_portion=50.00, payment_amount=50),
-	)
-	si.append(
-		"payment_schedule",
-		dict(due_date=getdate(add_days(today(), 90)), invoice_portion=20.00, payment_amount=20),
-	)
+	if not no_payment_schedule:
+		si.append(
+			"payment_schedule",
+			dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30),
+		)
+		si.append(
+			"payment_schedule",
+			dict(due_date=getdate(add_days(today(), 60)), invoice_portion=50.00, payment_amount=50),
+		)
+		si.append(
+			"payment_schedule",
+			dict(due_date=getdate(add_days(today(), 90)), invoice_portion=20.00, payment_amount=20),
+		)
 
-	si.submit()
+	si = si.save()
 
-	return si.name
+	if not do_not_submit:
+		si = si.submit()
+
+	return si
 
 
 def make_payment(docname):
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 e93fb61..d269e1f 100644
--- a/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
+++ b/erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
@@ -533,12 +533,13 @@
 			],
 			filters={"company": company, "root_type": root_type},
 		):
-			if account.account_name not in added_accounts:
+			if account.account_number:
+				account_key = account.account_number + "-" + account.account_name
+			else:
+				account_key = account.account_name
+
+			if account_key not in added_accounts:
 				accounts.append(account)
-				if account.account_number:
-					account_key = account.account_number + "-" + account.account_name
-				else:
-					account_key = account.account_name
 				added_accounts.append(account_key)
 
 	return accounts
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index dacc809..99e86ae 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -503,7 +503,7 @@
 						invoice_portion = 100
 					elif row.invoice_portion:
 						invoice_portion = row.invoice_portion
-					else:
+					elif row.payment_amount:
 						invoice_portion = row.payment_amount * 100 / row.base_net_amount
 
 					if i == 0:
diff --git a/erpnext/accounts/report/tax_detail/tax_detail.py b/erpnext/accounts/report/tax_detail/tax_detail.py
index ba8d307..ba733c2 100644
--- a/erpnext/accounts/report/tax_detail/tax_detail.py
+++ b/erpnext/accounts/report/tax_detail/tax_detail.py
@@ -234,8 +234,11 @@
 		if field in ["item_tax_rate", "base_net_amount"]:
 			return None
 
-	if doctype == "GL Entry" and field in ["debit", "credit"]:
-		column.update({"label": _("Amount"), "fieldname": "amount"})
+	if doctype == "GL Entry":
+		if field in ["debit", "credit"]:
+			column.update({"label": _("Amount"), "fieldname": "amount"})
+		elif field == "voucher_type":
+			column.update({"fieldtype": "Data", "options": ""})
 
 	if field == "taxes_and_charges":
 		column.update({"label": _("Taxes and Charges Template")})
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 41702d6..1e573b0 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -836,6 +836,7 @@
 	posting_date=None,
 	min_outstanding=None,
 	max_outstanding=None,
+	accounting_dimensions=None,
 ):
 
 	ple = qb.DocType("Payment Ledger Entry")
@@ -866,6 +867,7 @@
 		min_outstanding=min_outstanding,
 		max_outstanding=max_outstanding,
 		get_invoices=True,
+		accounting_dimensions=accounting_dimensions or [],
 	)
 
 	for d in invoice_list:
@@ -1615,6 +1617,7 @@
 			.where(ple.delinked == 0)
 			.where(Criterion.all(filter_on_voucher_no))
 			.where(Criterion.all(self.common_filter))
+			.where(Criterion.all(self.dimensions_filter))
 			.where(Criterion.all(self.voucher_posting_date))
 			.groupby(ple.voucher_type, ple.voucher_no, ple.party_type, ple.party)
 		)
@@ -1702,6 +1705,7 @@
 		max_outstanding=None,
 		get_payments=False,
 		get_invoices=False,
+		accounting_dimensions=None,
 	):
 		"""
 		Fetch voucher amount and outstanding amount from Payment Ledger using Database CTE
@@ -1717,6 +1721,7 @@
 		self.reset()
 		self.vouchers = vouchers
 		self.common_filter = common_filter or []
+		self.dimensions_filter = accounting_dimensions or []
 		self.voucher_posting_date = posting_date or []
 		self.min_outstanding = min_outstanding
 		self.max_outstanding = max_outstanding
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 9349626..ce7de87 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -62,12 +62,13 @@
   "set_reserve_warehouse",
   "supplied_items",
   "taxes_section",
+  "tax_category",
   "taxes_and_charges",
   "column_break_53",
-  "tax_category",
-  "column_break_50",
   "shipping_rule",
+  "column_break_50",
   "incoterm",
+  "named_place",
   "section_break_52",
   "taxes",
   "totals",
@@ -1256,13 +1257,19 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-17 17:28:07.729943",
+ "modified": "2022-12-12 18:36:37.455134",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
index 98c7dc9..a9f5afb 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.js
@@ -57,44 +57,96 @@
 				});
 			}, __("Tools"));
 
-			frm.add_custom_button(__('Download PDF'), () => {
-				var suppliers = [];
-				const fields = [{
-					fieldtype: 'Link',
-					label: __('Select a Supplier'),
-					fieldname: 'supplier',
-					options: 'Supplier',
-					reqd: 1,
-					get_query: () => {
-						return {
-							filters: [
-								["Supplier", "name", "in", frm.doc.suppliers.map((row) => {return row.supplier;})]
-							]
-						}
-					}
-				}];
-
-				frappe.prompt(fields, data => {
-					var child = locals[cdt][cdn]
-
-					var w = window.open(
-						frappe.urllib.get_full_url("/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?"
-						+"doctype="+encodeURIComponent(frm.doc.doctype)
-						+"&name="+encodeURIComponent(frm.doc.name)
-						+"&supplier="+encodeURIComponent(data.supplier)
-						+"&no_letterhead=0"));
-					if(!w) {
-						frappe.msgprint(__("Please enable pop-ups")); return;
-					}
+			frm.add_custom_button(
+				__("Download PDF"),
+				() => {
+					frappe.prompt(
+						[
+							{
+								fieldtype: "Link",
+								label: "Select a Supplier",
+								fieldname: "supplier",
+								options: "Supplier",
+								reqd: 1,
+								default: frm.doc.suppliers?.length == 1 ? frm.doc.suppliers[0].supplier : "",
+								get_query: () => {
+									return {
+										filters: [
+											[
+												"Supplier",
+												"name",
+												"in",
+												frm.doc.suppliers.map((row) => {
+													return row.supplier;
+												}),
+											],
+										],
+									};
+								},
+							},
+							{
+								fieldtype: "Section Break",
+								label: "Print Settings",
+								fieldname: "print_settings",
+								collapsible: 1,
+							},
+							{
+								fieldtype: "Link",
+								label: "Print Format",
+								fieldname: "print_format",
+								options: "Print Format",
+								placeholder: "Standard",
+								get_query: () => {
+									return {
+										filters: {
+											doc_type: "Request for Quotation",
+										},
+									};
+								},
+							},
+							{
+								fieldtype: "Link",
+								label: "Language",
+								fieldname: "language",
+								options: "Language",
+								default: frappe.boot.lang,
+							},
+							{
+								fieldtype: "Link",
+								label: "Letter Head",
+								fieldname: "letter_head",
+								options: "Letter Head",
+								default: frm.doc.letter_head,
+							},
+						],
+						(data) => {
+							var w = window.open(
+								frappe.urllib.get_full_url(
+									"/api/method/erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_pdf?" +
+									new URLSearchParams({
+										doctype: frm.doc.doctype,
+										name: frm.doc.name,
+										supplier: data.supplier,
+										print_format: data.print_format || "Standard",
+										language: data.language || frappe.boot.lang,
+										letter_head: data.letter_head || frm.doc.letter_head || "",
+									}).toString()
+								)
+							);
+							if (!w) {
+								frappe.msgprint(__("Please enable pop-ups"));
+								return;
+							}
+						},
+						"Download PDF for Supplier",
+						"Download"
+					);
 				},
-				'Download PDF for Supplier',
-				'Download');
-			},
-			__("Tools"));
+				__("Tools")
+			);
 
-			frm.page.set_inner_btn_group_as_primary(__('Create'));
+			frm.page.set_inner_btn_group_as_primary(__("Create"));
 		}
-
 	},
 
 	make_supplier_quotation: function(frm) {
diff --git a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
index bdbc9ce..dbc3644 100644
--- a/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
+++ b/erpnext/buying/doctype/request_for_quotation/request_for_quotation.py
@@ -389,10 +389,17 @@
 
 
 @frappe.whitelist()
-def get_pdf(doctype, name, supplier):
-	doc = get_rfq_doc(doctype, name, supplier)
-	if doc:
-		download_pdf(doctype, name, doc=doc)
+def get_pdf(doctype, name, supplier, print_format=None, language=None, letter_head=None):
+	# permissions get checked in `download_pdf`
+	if doc := get_rfq_doc(doctype, name, supplier):
+		download_pdf(
+			doctype,
+			name,
+			print_format,
+			doc=doc,
+			language=language,
+			letter_head=letter_head or None,
+		)
 
 
 def get_rfq_doc(doctype, name, supplier):
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index bebff1c..120b2f8 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -20,9 +20,6 @@
 
 
 class Supplier(TransactionBase):
-	def get_feed(self):
-		return self.supplier_name
-
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
index 7776ab8..c5b369b 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
@@ -40,12 +40,13 @@
   "total",
   "net_total",
   "taxes_section",
+  "tax_category",
   "taxes_and_charges",
   "column_break_34",
-  "tax_category",
-  "column_break_36",
   "shipping_rule",
+  "column_break_36",
   "incoterm",
+  "named_place",
   "section_break_38",
   "taxes",
   "totals",
@@ -830,6 +831,12 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-shopping-cart",
@@ -837,7 +844,7 @@
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-17 17:27:32.179686",
+ "modified": "2022-12-12 18:35:39.740974",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Supplier Quotation",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 5a051e3..334a2d8 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -197,7 +197,7 @@
 
 		validate_einvoice_fields(self)
 
-		if self.doctype != "Material Request":
+		if self.doctype != "Material Request" and not self.ignore_pricing_rule:
 			apply_pricing_rule_on_transaction(self)
 
 	def before_cancel(self):
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 2efa545..7989a40 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -25,10 +25,6 @@
 	def __setup__(self):
 		self.flags.ignore_permlevel_for_fields = ["buying_price_list", "price_list_currency"]
 
-	def get_feed(self):
-		if self.get("supplier_name"):
-			return _("From {0} | {1} {2}").format(self.supplier_name, self.currency, self.grand_total)
-
 	def validate(self):
 		super(BuyingController, self).validate()
 		if getattr(self, "supplier", None) and not self.supplier_name:
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 0ebc8d4..8b073a4 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -19,9 +19,6 @@
 	def __setup__(self):
 		self.flags.ignore_permlevel_for_fields = ["selling_price_list", "price_list_currency"]
 
-	def get_feed(self):
-		return _("To {0} | {1} {2}").format(self.customer_name, self.currency, self.grand_total)
-
 	def onload(self):
 		super(SellingController, self).onload()
 		if self.doctype in ("Sales Order", "Delivery Note", "Sales Invoice"):
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index bf07728..d497297 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -347,16 +347,21 @@
 		)
 
 	def warn_about_bypassing_with_role(self, item, qty_or_amount, role):
-		action = _("Over Receipt/Delivery") if qty_or_amount == "qty" else _("Overbilling")
+		if qty_or_amount == "qty":
+			msg = _("Over Receipt/Delivery of {0} {1} ignored for item {2} because you have {3} role.")
+		else:
+			msg = _("Overbilling of {0} {1} ignored for item {2} because you have {3} role.")
 
-		msg = _("{0} of {1} {2} ignored for item {3} because you have {4} role.").format(
-			action,
-			_(item["target_ref_field"].title()),
-			frappe.bold(item["reduce_by"]),
-			frappe.bold(item.get("item_code")),
-			role,
+		frappe.msgprint(
+			msg.format(
+				_(item["target_ref_field"].title()),
+				frappe.bold(item["reduce_by"]),
+				frappe.bold(item.get("item_code")),
+				role,
+			),
+			indicator="orange",
+			alert=True,
 		)
-		frappe.msgprint(msg, indicator="orange", alert=True)
 
 	def update_qty(self, update_modified=True):
 		"""Updates qty or amount at row level
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 361e13c..b0ff5d4 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -14,9 +14,6 @@
 
 
 class Lead(SellingController, CRMNote):
-	def get_feed(self):
-		return "{0}: {1}".format(_(self.status), self.lead_name)
-
 	def onload(self):
 		customer = frappe.db.get_value("Customer", {"lead_name": self.name})
 		self.get("__onload").is_customer = customer
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index fd19d25..7d72c76 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -420,6 +420,7 @@
 		"erpnext.loan_management.doctype.process_loan_security_shortfall.process_loan_security_shortfall.create_process_loan_security_shortfall",
 		"erpnext.loan_management.doctype.process_loan_interest_accrual.process_loan_interest_accrual.process_loan_interest_accrual_for_term_loans",
 		"erpnext.crm.utils.open_leads_opportunities_based_on_todays_event",
+		"erpnext.stock.doctype.stock_entry.stock_entry.audit_incorrect_valuation_entries",
 	],
 	"monthly_long": [
 		"erpnext.accounts.deferred_revenue.process_deferred_accounting",
diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py
index 0d319bf..b900b21 100644
--- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py
+++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.py
@@ -10,9 +10,6 @@
 
 
 class MaintenanceVisit(TransactionBase):
-	def get_feed(self):
-		return _("To {0}").format(self.customer_name)
-
 	def validate_serial_no(self):
 		for d in self.get("purposes"):
 			if d.serial_no and not frappe.db.exists("Serial No", d.serial_no):
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 36466ff..f568264 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -1154,6 +1154,36 @@
 		except frappe.MandatoryError:
 			self.fail("Batch generation causing failing in Work Order")
 
+	@change_settings("Manufacturing Settings", {"make_serial_no_batch_from_work_order": 1})
+	def test_auto_serial_no_creation(self):
+		from erpnext.manufacturing.doctype.bom.test_bom import create_nested_bom
+
+		fg_item = frappe.generate_hash(length=20)
+		child_item = frappe.generate_hash(length=20)
+
+		bom_tree = {fg_item: {child_item: {}}}
+
+		create_nested_bom(bom_tree, prefix="")
+
+		item = frappe.get_doc("Item", fg_item)
+		item.has_serial_no = 1
+		item.serial_no_series = f"{item.name}.#####"
+		item.save()
+
+		try:
+			wo_order = make_wo_order_test_record(item=fg_item, qty=2, skip_transfer=True)
+			serial_nos = wo_order.serial_no
+			stock_entry = frappe.get_doc(make_stock_entry(wo_order.name, "Manufacture", 10))
+			stock_entry.set_work_order_details()
+			stock_entry.set_serial_no_batch_for_finished_good()
+			for row in stock_entry.items:
+				if row.item_code == fg_item:
+					self.assertTrue(row.serial_no)
+					self.assertEqual(sorted(get_serial_nos(row.serial_no)), sorted(get_serial_nos(serial_nos)))
+
+		except frappe.MandatoryError:
+			self.fail("Batch generation causing failing in Work Order")
+
 	@change_settings(
 		"Manufacturing Settings",
 		{"backflush_raw_materials_based_on": "Material Transferred for Manufacture"},
diff --git a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
index 1e1b435..cdf1541 100644
--- a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
+++ b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
@@ -4,7 +4,7 @@
 
 import frappe
 from frappe import _
-from frappe.query_builder.functions import Floor, Sum
+from frappe.query_builder.functions import Sum
 from pypika.terms import ExistsCriterion
 
 
@@ -58,9 +58,9 @@
 			bom_item.description,
 			bom_item.stock_qty,
 			bom_item.stock_uom,
-			bom_item.stock_qty * qty_to_produce / bom.quantity,
-			Sum(bin.actual_qty).as_("actual_qty"),
-			Sum(Floor(bin.actual_qty / (bom_item.stock_qty * qty_to_produce / bom.quantity))),
+			(bom_item.stock_qty / bom.quantity) * qty_to_produce,
+			Sum(bin.actual_qty),
+			Sum(bin.actual_qty) / (bom_item.stock_qty / bom.quantity),
 		)
 		.where((bom_item.parent == filters.get("bom")) & (bom_item.parenttype == "BOM"))
 		.groupby(bom_item.item_code)
diff --git a/erpnext/portal/utils.py b/erpnext/portal/utils.py
index 7be8c5d..c8b03e6 100644
--- a/erpnext/portal/utils.py
+++ b/erpnext/portal/utils.py
@@ -102,7 +102,7 @@
 	contact = frappe.new_doc("Contact")
 	contact.update({"first_name": fullname, "email_id": user})
 	contact.append("links", dict(link_doctype=doctype, link_name=party_name))
-	contact.append("email_ids", dict(email_id=user))
+	contact.append("email_ids", dict(email_id=user, is_primary=True))
 	contact.flags.ignore_mandatory = True
 	contact.insert(ignore_permissions=True)
 
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index cbf2493..4735f24 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -15,9 +15,6 @@
 
 
 class Project(Document):
-	def get_feed(self):
-		return "{0}: {1}".format(_(self.status), frappe.safe_decode(self.project_name))
-
 	def onload(self):
 		self.set_onload(
 			"activity_summary",
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 79f1b3a..2dde542 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -20,9 +20,6 @@
 class Task(NestedSet):
 	nsm_parent_field = "parent_task"
 
-	def get_feed(self):
-		return "{0}: {1}".format(_(self.status), self.subject)
-
 	def get_customer_details(self):
 		cust = frappe.db.sql("select customer_name from `tabCustomer` where name=%s", self.customer)
 		if cust:
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index 7481000..1f8a5e3 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -58,7 +58,7 @@
 
 		if (
 			in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype)
-			&& this.frm.doc.s_pos
+			&& this.frm.doc.is_pos
 			&& this.frm.doc.is_return
 		) {
 			this.set_total_amount_to_default_mop();
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index cf05d06..aa57bc2 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1130,10 +1130,13 @@
 
 	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);
+		// item.pricing_rules = ''
+		frappe.run_serially([
+			() => this.remove_pricing_rule(item),
+			() => this.conversion_factor(doc, cdt, cdn, true),
+			() => this.calculate_stock_uom_rate(doc, cdt, cdn),
+			() => this.apply_pricing_rule(item, true)
+		]);
 	}
 
 	calculate_stock_uom_rate(doc, cdt, cdn) {
@@ -1357,16 +1360,21 @@
 			var item_list = [];
 
 			$.each(this.frm.doc["items"] || [], function(i, d) {
-				if (d.item_code && !d.is_free_item) {
-					item_list.push({
-						"doctype": d.doctype,
-						"name": d.name,
-						"item_code": d.item_code,
-						"pricing_rules": d.pricing_rules,
-						"parenttype": d.parenttype,
-						"parent": d.parent,
-						"price_list_rate": d.price_list_rate
-					})
+				if (d.item_code) {
+					if (d.is_free_item) {
+						// Simply remove free items
+						me.frm.get_field("items").grid.grid_rows[i].remove();
+					} else {
+						item_list.push({
+							"doctype": d.doctype,
+							"name": d.name,
+							"item_code": d.item_code,
+							"pricing_rules": d.pricing_rules,
+							"parenttype": d.parenttype,
+							"parent": d.parent,
+							"price_list_rate": d.price_list_rate
+						})
+					}
 				}
 			});
 			return this.frm.call({
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 60c3356..12ecb01 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -27,9 +27,6 @@
 
 
 class Customer(TransactionBase):
-	def get_feed(self):
-		return self.customer_name
-
 	def onload(self):
 		"""Load address and contacts in `__onload`"""
 		load_address_and_contact(self)
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index 08918f4..eb2c0a4 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -43,12 +43,13 @@
   "total",
   "net_total",
   "taxes_section",
+  "tax_category",
   "taxes_and_charges",
   "column_break_36",
-  "tax_category",
-  "column_break_34",
   "shipping_rule",
+  "column_break_34",
   "incoterm",
+  "named_place",
   "section_break_36",
   "taxes",
   "section_break_39",
@@ -1059,13 +1060,19 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-shopping-cart",
  "idx": 82,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-17 17:20:54.984348",
+ "modified": "2022-12-12 18:32:28.671332",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Quotation",
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 6f0b381..b151dd5 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -30,6 +30,24 @@
 
 		self.assertTrue(sales_order.get("payment_schedule"))
 
+	def test_maintain_rate_in_sales_cycle_is_enforced(self):
+		from erpnext.selling.doctype.quotation.quotation import make_sales_order
+
+		maintain_rate = frappe.db.get_single_value("Selling Settings", "maintain_same_sales_rate")
+		frappe.db.set_single_value("Selling Settings", "maintain_same_sales_rate", 1)
+
+		quotation = frappe.copy_doc(test_records[0])
+		quotation.transaction_date = nowdate()
+		quotation.valid_till = add_months(quotation.transaction_date, 1)
+		quotation.insert()
+		quotation.submit()
+
+		sales_order = make_sales_order(quotation.name)
+		sales_order.items[0].rate = 1
+		self.assertRaises(frappe.ValidationError, sales_order.save)
+
+		frappe.db.set_single_value("Selling Settings", "maintain_same_sales_rate", maintain_rate)
+
 	def test_make_sales_order_with_different_currency(self):
 		from erpnext.selling.doctype.quotation.quotation import make_sales_order
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index 9ec32cb..ccea840 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -58,12 +58,13 @@
   "total",
   "net_total",
   "taxes_section",
+  "tax_category",
   "taxes_and_charges",
   "column_break_38",
-  "tax_category",
-  "column_break_49",
   "shipping_rule",
+  "column_break_49",
   "incoterm",
+  "named_place",
   "section_break_40",
   "taxes",
   "section_break_43",
@@ -1630,13 +1631,19 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-file-text",
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-17 17:22:00.413878",
+ "modified": "2022-12-12 18:34:00.681780",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Sales Order",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 78e2370..0013c95 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -194,7 +194,7 @@
 		)
 
 		if cint(frappe.db.get_single_value("Selling Settings", "maintain_same_sales_rate")):
-			self.validate_rate_with_reference_doc([["Quotation", "prev_docname", "quotation_item"]])
+			self.validate_rate_with_reference_doc([["Quotation", "prevdoc_docname", "quotation_item"]])
 
 	def update_enquiry_status(self, prevdoc, flag):
 		enq = frappe.db.sql(
diff --git a/erpnext/selling/doctype/sales_order/sales_order_dashboard.py b/erpnext/selling/doctype/sales_order/sales_order_dashboard.py
index ace2e29..5c4b578 100644
--- a/erpnext/selling/doctype/sales_order/sales_order_dashboard.py
+++ b/erpnext/selling/doctype/sales_order/sales_order_dashboard.py
@@ -12,7 +12,10 @@
 			"Auto Repeat": "reference_document",
 			"Maintenance Visit": "prevdoc_docname",
 		},
-		"internal_links": {"Quotation": ["items", "prevdoc_docname"]},
+		"internal_links": {
+			"Quotation": ["items", "prevdoc_docname"],
+			"Material Request": ["items", "material_request"],
+		},
 		"transactions": [
 			{
 				"label": _("Fulfillment"),
diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js
index 91748bc..f3f931e 100644
--- a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js
+++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js
@@ -45,6 +45,12 @@
 			}
 		},
 		{
+			"fieldname": "warehouse",
+			"label": __("Warehouse"),
+			"fieldtype": "Link",
+			"options": "Warehouse"
+		},
+		{
 			"fieldname": "status",
 			"label": __("Status"),
 			"fieldtype": "MultiSelectList",
diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
index 720aa41..63d339a 100644
--- a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
+++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
@@ -53,6 +53,9 @@
 	if filters.get("status"):
 		conditions += " and so.status in %(status)s"
 
+	if filters.get("warehouse"):
+		conditions += " and soi.warehouse = %(warehouse)s"
+
 	return conditions
 
 
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index d6f2378..07ee289 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -70,9 +70,6 @@
 
 		self.abbr = self.abbr.strip()
 
-		# if self.get('__islocal') and len(self.abbr) > 5:
-		# 	frappe.throw(_("Abbreviation cannot have more than 5 characters"))
-
 		if not self.abbr.strip():
 			frappe.throw(_("Abbreviation is mandatory"))
 
diff --git a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py
index c18a4b2..4256a7d 100644
--- a/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py
+++ b/erpnext/setup/doctype/transaction_deletion_record/transaction_deletion_record.py
@@ -204,7 +204,7 @@
 
 @frappe.whitelist()
 def get_doctypes_to_be_ignored():
-	doctypes_to_be_ignored_list = [
+	doctypes_to_be_ignored = [
 		"Account",
 		"Cost Center",
 		"Warehouse",
@@ -223,4 +223,7 @@
 		"Customer",
 		"Supplier",
 	]
-	return doctypes_to_be_ignored_list
+
+	doctypes_to_be_ignored.extend(frappe.get_hooks("company_data_to_be_ignored") or [])
+
+	return doctypes_to_be_ignored
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 80e4bcb..165a56b 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -57,12 +57,13 @@
   "total",
   "net_total",
   "taxes_section",
+  "tax_category",
   "taxes_and_charges",
   "column_break_43",
-  "tax_category",
-  "column_break_39",
   "shipping_rule",
+  "column_break_39",
   "incoterm",
+  "named_place",
   "section_break_41",
   "taxes",
   "section_break_44",
@@ -1388,13 +1389,19 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-truck",
  "idx": 146,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-17 17:22:42.860790",
+ "modified": "2022-12-12 18:38:53.067799",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note",
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index afad751..94f63a5 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -22,9 +22,6 @@
 
 
 class MaterialRequest(BuyingController):
-	def get_feed(self):
-		return
-
 	def check_if_already_pulled(self):
 		pass
 
diff --git a/erpnext/stock/doctype/pick_list/pick_list.py b/erpnext/stock/doctype/pick_list/pick_list.py
index 5de7fed..aff5e05 100644
--- a/erpnext/stock/doctype/pick_list/pick_list.py
+++ b/erpnext/stock/doctype/pick_list/pick_list.py
@@ -192,13 +192,13 @@
 
 			if item_map.get(key):
 				item_map[key].qty += item.qty
-				item_map[key].stock_qty += item.stock_qty
+				item_map[key].stock_qty += flt(item.stock_qty, item.precision("stock_qty"))
 			else:
 				item_map[key] = item
 
 			# maintain count of each item (useful to limit get query)
 			self.item_count_map.setdefault(item_code, 0)
-			self.item_count_map[item_code] += item.stock_qty
+			self.item_count_map[item_code] += flt(item.stock_qty, item.precision("stock_qty"))
 
 		return item_map.values()
 
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index ab91d7c..8f04358 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -58,12 +58,13 @@
   "total",
   "net_total",
   "taxes_charges_section",
+  "tax_category",
   "taxes_and_charges",
   "shipping_col",
-  "tax_category",
-  "column_break_53",
   "shipping_rule",
+  "column_break_53",
   "incoterm",
+  "named_place",
   "taxes_section",
   "taxes",
   "totals",
@@ -1225,13 +1226,19 @@
    "fieldtype": "Link",
    "label": "Incoterm",
    "options": "Incoterm"
+  },
+  {
+   "depends_on": "incoterm",
+   "fieldname": "named_place",
+   "fieldtype": "Data",
+   "label": "Named Place"
   }
  ],
  "icon": "fa fa-truck",
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2022-11-17 17:29:30.067536",
+ "modified": "2022-12-12 18:40:32.447752",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index a2748d0..541d4d1 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -766,13 +766,13 @@
 
 @frappe.whitelist()
 def auto_fetch_serial_number(
-	qty: float,
+	qty: int,
 	item_code: str,
 	warehouse: str,
 	posting_date: Optional[str] = None,
 	batch_nos: Optional[Union[str, List[str]]] = None,
 	for_doctype: Optional[str] = None,
-	exclude_sr_nos: Optional[List[str]] = None,
+	exclude_sr_nos=None,
 ) -> List[str]:
 
 	filters = frappe._dict({"item_code": item_code, "warehouse": warehouse})
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index f6c53f7..a047a9b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -4,12 +4,24 @@
 
 import json
 from collections import defaultdict
+from typing import Dict
 
 import frappe
 from frappe import _
 from frappe.model.mapper import get_mapped_doc
 from frappe.query_builder.functions import Sum
-from frappe.utils import cint, comma_or, cstr, flt, format_time, formatdate, getdate, nowdate
+from frappe.utils import (
+	add_days,
+	cint,
+	comma_or,
+	cstr,
+	flt,
+	format_time,
+	formatdate,
+	getdate,
+	nowdate,
+	today,
+)
 
 import erpnext
 from erpnext.accounts.general_ledger import process_gl_map
@@ -83,9 +95,6 @@
 				}
 			)
 
-	def get_feed(self):
-		return self.stock_entry_type
-
 	def onload(self):
 		for item in self.get("items"):
 			item.update(get_bin_details(item.item_code, item.s_warehouse))
@@ -2239,16 +2248,16 @@
 			d.qty -= process_loss_dict[d.item_code][1]
 
 	def set_serial_no_batch_for_finished_good(self):
-		serial_nos = ""
+		serial_nos = []
 		if self.pro_doc.serial_no:
-			serial_nos = self.get_serial_nos_for_fg()
+			serial_nos = self.get_serial_nos_for_fg() or []
 
 		for row in self.items:
 			if row.is_finished_item and row.item_code == self.pro_doc.production_item:
 				if serial_nos:
 					row.serial_no = "\n".join(serial_nos[0 : cint(row.qty)])
 
-	def get_serial_nos_for_fg(self, args):
+	def get_serial_nos_for_fg(self):
 		fields = [
 			"`tabStock Entry`.`name`",
 			"`tabStock Entry Detail`.`qty`",
@@ -2264,9 +2273,7 @@
 		]
 
 		stock_entries = frappe.get_all("Stock Entry", fields=fields, filters=filters)
-
-		if self.pro_doc.serial_no:
-			return self.get_available_serial_nos(stock_entries)
+		return self.get_available_serial_nos(stock_entries)
 
 	def get_available_serial_nos(self, stock_entries):
 		used_serial_nos = []
@@ -2705,3 +2712,62 @@
 		)
 		.orderby(stock_entry.creation, stock_entry_detail.item_code, stock_entry_detail.idx)
 	).run(as_dict=1)
+
+
+def audit_incorrect_valuation_entries():
+	# Audit of stock transfer entries having incorrect valuation
+	from erpnext.controllers.stock_controller import create_repost_item_valuation_entry
+
+	stock_entries = get_incorrect_stock_entries()
+
+	for stock_entry, values in stock_entries.items():
+		reposting_data = frappe._dict(
+			{
+				"posting_date": values.posting_date,
+				"posting_time": values.posting_time,
+				"voucher_type": "Stock Entry",
+				"voucher_no": stock_entry,
+				"company": values.company,
+			}
+		)
+
+		create_repost_item_valuation_entry(reposting_data)
+
+
+def get_incorrect_stock_entries() -> Dict:
+	stock_entry = frappe.qb.DocType("Stock Entry")
+	stock_ledger_entry = frappe.qb.DocType("Stock Ledger Entry")
+	transfer_purposes = [
+		"Material Transfer",
+		"Material Transfer for Manufacture",
+		"Send to Subcontractor",
+	]
+
+	query = (
+		frappe.qb.from_(stock_entry)
+		.inner_join(stock_ledger_entry)
+		.on(stock_entry.name == stock_ledger_entry.voucher_no)
+		.select(
+			stock_entry.name,
+			stock_entry.company,
+			stock_entry.posting_date,
+			stock_entry.posting_time,
+			Sum(stock_ledger_entry.stock_value_difference).as_("stock_value"),
+		)
+		.where(
+			(stock_entry.docstatus == 1)
+			& (stock_entry.purpose.isin(transfer_purposes))
+			& (stock_ledger_entry.modified > add_days(today(), -2))
+		)
+		.groupby(stock_ledger_entry.voucher_detail_no)
+		.having(Sum(stock_ledger_entry.stock_value_difference) != 0)
+	)
+
+	data = query.run(as_dict=True)
+	stock_entries = {}
+
+	for row in data:
+		if abs(row.stock_value) > 0.1 and row.name not in stock_entries:
+			stock_entries.setdefault(row.name, row)
+
+	return stock_entries
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index b574b71..680d209 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -5,7 +5,7 @@
 import frappe
 from frappe.permissions import add_user_permission, remove_user_permission
 from frappe.tests.utils import FrappeTestCase, change_settings
-from frappe.utils import add_days, flt, nowdate, nowtime, today
+from frappe.utils import add_days, flt, now, nowdate, nowtime, today
 
 from erpnext.accounts.doctype.account.test_account import get_inventory_account
 from erpnext.stock.doctype.item.test_item import (
@@ -17,6 +17,8 @@
 from erpnext.stock.doctype.serial_no.serial_no import *  # noqa
 from erpnext.stock.doctype.stock_entry.stock_entry import (
 	FinishedGoodError,
+	audit_incorrect_valuation_entries,
+	get_incorrect_stock_entries,
 	move_sample_to_retention_warehouse,
 )
 from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
@@ -1614,6 +1616,44 @@
 
 		self.assertRaises(BatchExpiredError, se.save)
 
+	def test_audit_incorrect_stock_entries(self):
+		item_code = "Test Incorrect Valuation Rate Item - 001"
+		create_item(item_code=item_code, is_stock_item=1)
+
+		make_stock_entry(
+			item_code=item_code,
+			purpose="Material Receipt",
+			posting_date=add_days(nowdate(), -10),
+			qty=2,
+			rate=500,
+			to_warehouse="_Test Warehouse - _TC",
+		)
+
+		transfer_entry = make_stock_entry(
+			item_code=item_code,
+			purpose="Material Transfer",
+			qty=2,
+			rate=500,
+			from_warehouse="_Test Warehouse - _TC",
+			to_warehouse="_Test Warehouse 1 - _TC",
+		)
+
+		sle_name = frappe.db.get_value(
+			"Stock Ledger Entry", {"voucher_no": transfer_entry.name, "actual_qty": (">", 0)}, "name"
+		)
+
+		frappe.db.set_value(
+			"Stock Ledger Entry", sle_name, {"modified": add_days(now(), -1), "stock_value_difference": 10}
+		)
+
+		stock_entries = get_incorrect_stock_entries()
+		self.assertTrue(transfer_entry.name in stock_entries)
+
+		audit_incorrect_valuation_entries()
+
+		stock_entries = get_incorrect_stock_entries()
+		self.assertFalse(transfer_entry.name in stock_entries)
+
 
 def make_serialized_item(**args):
 	args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 3a0b38a..398b3c9 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -715,8 +715,8 @@
 def get_stock_balance_for(
 	item_code: str,
 	warehouse: str,
-	posting_date: str,
-	posting_time: str,
+	posting_date,
+	posting_time,
 	batch_no: Optional[str] = None,
 	with_valuation_rate: bool = True,
 ):
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 108611c..1741d65 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -113,7 +113,7 @@
 		if args.get(key) is None:
 			args[key] = value
 
-	data = get_pricing_rule_for_item(args, out.price_list_rate, doc, for_validate=for_validate)
+	data = get_pricing_rule_for_item(args, doc=doc, for_validate=for_validate)
 
 	out.update(data)
 
@@ -828,9 +828,9 @@
 	):
 		if frappe.has_permission("Item Price", "write"):
 			price_list_rate = (
-				(args.rate + args.discount_amount) / args.get("conversion_factor")
+				(flt(args.rate) + flt(args.discount_amount)) / args.get("conversion_factor")
 				if args.get("conversion_factor")
-				else (args.rate + args.discount_amount)
+				else (flt(args.rate) + flt(args.discount_amount))
 			)
 
 			item_price = frappe.db.get_value(
@@ -1305,7 +1305,7 @@
 	item_doc = frappe.db.get_value("Item", args.item_code, ["name", "variant_of"], as_dict=1)
 	item_details = get_price_list_rate(args, item_doc)
 
-	item_details.update(get_pricing_rule_for_item(args, item_details.price_list_rate))
+	item_details.update(get_pricing_rule_for_item(args))
 
 	return item_details
 
diff --git a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
index a6fc049..c4358b8 100644
--- a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
+++ b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py
@@ -82,7 +82,7 @@
 			item.safety_stock,
 			item.lead_time_days,
 		)
-		.where(item.is_stock_item == 1)
+		.where((item.is_stock_item == 1) & (item.disabled == 0))
 	)
 
 	if brand := filters.get("brand"):
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 7f3e0cf..f23419e 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -18,9 +18,6 @@
 
 
 class Issue(Document):
-	def get_feed(self):
-		return "{0}: {1}".format(_(self.status), self.subject)
-
 	def validate(self):
 		if self.is_new() and self.via_customer_portal:
 			self.flags.create_communication = True
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.py b/erpnext/support/doctype/warranty_claim/warranty_claim.py
index c86356f..ff63b77 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.py
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.py
@@ -10,9 +10,6 @@
 
 
 class WarrantyClaim(TransactionBase):
-	def get_feed(self):
-		return _("{0}: From {1}").format(self.status, self.customer_name)
-
 	def validate(self):
 		if session["user"] != "Guest" and not self.customer:
 			frappe.throw(_("Customer is required"))
diff --git a/erpnext/translations/de.csv b/erpnext/translations/de.csv
index f1d8302..1014e27 100644
--- a/erpnext/translations/de.csv
+++ b/erpnext/translations/de.csv
@@ -1849,6 +1849,8 @@
 Outstanding Cheques and Deposits to clear,Ausstehende Schecks und Anzahlungen zum verbuchen,
 Outstanding for {0} cannot be less than zero ({1}),Ausstände für {0} können nicht kleiner als Null sein ({1}),
 Outward taxable supplies(zero rated),Steuerpflichtige Lieferungen aus dem Ausland (null bewertet),
+Over Receipt/Delivery of {0} {1} ignored for item {2} because you have {3} role.,"Überhöhte Annahme bzw. Lieferung von Artikel {2} mit {0} {1} wurde ignoriert, weil Sie die Rolle {3} haben."
+Overbilling of {0} {1} ignored for item {2} because you have {3} role.,"Überhöhte Abrechnung von Artikel {2} mit {0} {1} wurde ignoriert, weil Sie die Rolle {3} haben."
 Overdue,Überfällig,
 Overlap in scoring between {0} and {1},Überlappung beim Scoring zwischen {0} und {1},
 Overlapping conditions found between:,Überlagernde Bedingungen gefunden zwischen:,
@@ -9914,4 +9916,3 @@
 Delivered at Place,Geliefert benannter Ort,
 Delivered at Place Unloaded,Geliefert benannter Ort entladen,
 Delivered Duty Paid,Geliefert verzollt,
-{0} of {1} {2} ignored for item {3} because you have {4} role,"{0} von Artikel {3} mit {1} {2} wurde ignoriert, weil Sie die Rolle {4} haben."
diff --git a/erpnext/utilities/product.py b/erpnext/utilities/product.py
index 04ee0b3..afe9654 100644
--- a/erpnext/utilities/product.py
+++ b/erpnext/utilities/product.py
@@ -110,6 +110,7 @@
 					"conversion_rate": 1,
 					"for_shopping_cart": True,
 					"currency": frappe.db.get_value("Price List", price_list, "currency"),
+					"doctype": "Quotation",
 				}
 			)