Merge branch 'develop' of https://github.com/frappe/erpnext into ledger_preview
diff --git a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
index c4a23a6..0eef3e9 100644
--- a/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
+++ b/erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.py
@@ -10,6 +10,7 @@
 from frappe.query_builder.custom import ConstantColumn
 from frappe.utils import cint, flt
 
+from erpnext import get_default_cost_center
 from erpnext.accounts.doctype.bank_transaction.bank_transaction import get_total_allocated_amount
 from erpnext.accounts.report.bank_reconciliation_statement.bank_reconciliation_statement import (
 	get_amounts_not_reflected_in_system,
@@ -140,6 +141,9 @@
 					second_account
 				)
 			)
+
+	company = frappe.get_value("Account", company_account, "company")
+
 	accounts = []
 	# Multi Currency?
 	accounts.append(
@@ -149,6 +153,7 @@
 			"debit_in_account_currency": bank_transaction.withdrawal,
 			"party_type": party_type,
 			"party": party,
+			"cost_center": get_default_cost_center(company),
 		}
 	)
 
@@ -158,11 +163,10 @@
 			"bank_account": bank_transaction.bank_account,
 			"credit_in_account_currency": bank_transaction.withdrawal,
 			"debit_in_account_currency": bank_transaction.deposit,
+			"cost_center": get_default_cost_center(company),
 		}
 	)
 
-	company = frappe.get_value("Account", company_account, "company")
-
 	journal_entry_dict = {
 		"voucher_type": entry_type,
 		"company": company,
diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json
index 0a7d057..fd2d931 100644
--- a/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json
+++ b/erpnext/accounts/doctype/exchange_rate_revaluation_account/exchange_rate_revaluation_account.json
@@ -73,6 +73,7 @@
    "fieldname": "current_exchange_rate",
    "fieldtype": "Float",
    "label": "Current Exchange Rate",
+   "precision": "9",
    "read_only": 1
   },
   {
@@ -148,7 +149,7 @@
  ],
  "istable": 1,
  "links": [],
- "modified": "2023-06-20 07:21:40.743460",
+ "modified": "2023-06-22 12:39:56.446722",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Exchange Rate Revaluation Account",
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
index 2283677..89fa151 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
@@ -85,25 +85,29 @@
 
 		// check for any running reconciliation jobs
 		if (this.frm.doc.receivable_payable_account) {
-			frappe.db.get_single_value("Accounts Settings", "auto_reconcile_payments").then((enabled) => {
- 				if(enabled) {
-					this.frm.call({
-						'method': "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.is_any_doc_running",
-						"args": {
-							for_filter: {
-								company: this.frm.doc.company,
-								party_type: this.frm.doc.party_type,
-								party: this.frm.doc.party,
-								receivable_payable_account: this.frm.doc.receivable_payable_account
+			this.frm.call({
+				doc: this.frm.doc,
+				method: 'is_auto_process_enabled',
+				callback: (r) => {
+					if (r.message) {
+						this.frm.call({
+							'method': "erpnext.accounts.doctype.process_payment_reconciliation.process_payment_reconciliation.is_any_doc_running",
+							"args": {
+								for_filter: {
+									company: this.frm.doc.company,
+									party_type: this.frm.doc.party_type,
+									party: this.frm.doc.party,
+									receivable_payable_account: this.frm.doc.receivable_payable_account
+								}
 							}
-						}
-					}).then(r => {
-						if (r.message) {
-							let doc_link = frappe.utils.get_form_link("Process Payment Reconciliation", r.message, true);
-							let msg = __("Payment Reconciliation Job: {0} is running for this party. Can't reconcile now.", [doc_link]);
-							this.frm.dashboard.add_comment(msg, "yellow");
-						}
-					});
+						}).then(r => {
+							if (r.message) {
+								let doc_link = frappe.utils.get_form_link("Process Payment Reconciliation", r.message, true);
+								let msg = __("Payment Reconciliation Job: {0} is running for this party. Can't reconcile now.", [doc_link]);
+								this.frm.dashboard.add_comment(msg, "yellow");
+							}
+						});
+					}
 				}
 			});
 		}
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 2c8faec..2e4e3b0 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -253,6 +253,10 @@
 		return difference_amount
 
 	@frappe.whitelist()
+	def is_auto_process_enabled(self):
+		return frappe.db.get_single_value("Accounts Settings", "auto_reconcile_payments")
+
+	@frappe.whitelist()
 	def calculate_difference_on_allocation_change(self, payment_entry, invoice, allocated_amount):
 		invoice_exchange_map = self.get_invoice_exchange_map(invoice, payment_entry)
 		invoice[0]["exchange_rate"] = invoice_exchange_map.get(invoice[0].get("invoice_number"))
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 818c789..9546680 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -320,7 +320,9 @@
 	return data[0]
 
 
-def make_return_doc(doctype: str, source_name: str, target_doc=None):
+def make_return_doc(
+	doctype: str, source_name: str, target_doc=None, return_against_rejected_qty=False
+):
 	from frappe.model.mapper import get_mapped_doc
 
 	company = frappe.db.get_value("Delivery Note", source_name, "company")
@@ -471,7 +473,7 @@
 
 			target_doc.qty = -1 * flt(source_doc.qty - (returned_qty_map.get("qty") or 0))
 
-			if hasattr(target_doc, "stock_qty"):
+			if hasattr(target_doc, "stock_qty") and not return_against_rejected_qty:
 				target_doc.stock_qty = -1 * flt(
 					source_doc.stock_qty - (returned_qty_map.get("stock_qty") or 0)
 				)
@@ -490,6 +492,13 @@
 				target_doc.rejected_warehouse = source_doc.rejected_warehouse
 				target_doc.purchase_receipt_item = source_doc.name
 
+			if doctype == "Purchase Receipt" and return_against_rejected_qty:
+				target_doc.qty = -1 * flt(source_doc.rejected_qty - (returned_qty_map.get("qty") or 0))
+				target_doc.rejected_qty = 0.0
+				target_doc.rejected_warehouse = ""
+				target_doc.warehouse = source_doc.rejected_warehouse
+				target_doc.received_qty = target_doc.qty
+
 		elif doctype == "Purchase Invoice":
 			returned_qty_map = get_returned_qty_map_for_row(
 				source_parent.name, source_parent.supplier, source_doc.name, doctype
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 685209c..35aad78 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -213,10 +213,43 @@
 	}
 
 	make_purchase_return() {
-		frappe.model.open_mapped_doc({
-			method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return",
-			frm: cur_frm
+		let me = this;
+
+		let has_rejected_items = cur_frm.doc.items.filter((item) => {
+			if (item.rejected_qty > 0) {
+				return true;
+			}
 		})
+
+		if (has_rejected_items && has_rejected_items.length > 0) {
+			frappe.prompt([
+				{
+					label: __("Return Qty from Rejected Warehouse"),
+					fieldtype: "Check",
+					fieldname: "return_for_rejected_warehouse",
+					default: 1
+				},
+			], function(values){
+				if (values.return_for_rejected_warehouse) {
+					frappe.call({
+						method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return_against_rejected_warehouse",
+						args: {
+							source_name: cur_frm.doc.name
+						},
+						callback: function(r) {
+							if(r.message) {
+								frappe.model.sync(r.message);
+								frappe.set_route("Form", r.message.doctype, r.message.name);
+							}
+						}
+					})
+				} else {
+					cur_frm.cscript._make_purchase_return();
+				}
+			}, __("Return Qty"), __("Make Return Entry"));
+		} else {
+			cur_frm.cscript._make_purchase_return();
+		}
 	}
 
 	close_purchase_receipt() {
@@ -326,6 +359,13 @@
 	},
 });
 
+cur_frm.cscript._make_purchase_return = function() {
+	frappe.model.open_mapped_doc({
+		method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_purchase_return",
+		frm: cur_frm
+	});
+}
+
 cur_frm.cscript['Make Stock Entry'] = function() {
 	frappe.model.open_mapped_doc({
 		method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_stock_entry",
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index 387f031..0b5dc05 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -1137,6 +1137,13 @@
 
 
 @frappe.whitelist()
+def make_purchase_return_against_rejected_warehouse(source_name):
+	from erpnext.controllers.sales_and_purchase_return import make_return_doc
+
+	return make_return_doc("Purchase Receipt", source_name, return_against_rejected_qty=True)
+
+
+@frappe.whitelist()
 def make_purchase_return(source_name, target_doc=None):
 	from erpnext.controllers.sales_and_purchase_return import make_return_doc
 
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index ddc0556..1986722 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -1827,6 +1827,33 @@
 
 		self.assertEqual(abs(data["stock_value_difference"]), 400.00)
 
+	def test_return_from_rejected_warehouse(self):
+		from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
+			make_purchase_return_against_rejected_warehouse,
+		)
+
+		item_code = "_Test Item Return from Rejected Warehouse"
+		create_item(item_code)
+
+		warehouse = create_warehouse("_Test Warehouse Return Qty Warehouse")
+		rejected_warehouse = create_warehouse("_Test Rejected Warehouse Return Qty Warehouse")
+
+		# Step 1: Create Purchase Receipt with valuation rate 100
+		pr = make_purchase_receipt(
+			item_code=item_code,
+			warehouse=warehouse,
+			qty=10,
+			rate=100,
+			rejected_qty=2,
+			rejected_warehouse=rejected_warehouse,
+		)
+
+		pr_return = make_purchase_return_against_rejected_warehouse(pr.name)
+		self.assertEqual(pr_return.items[0].warehouse, rejected_warehouse)
+		self.assertEqual(pr_return.items[0].qty, 2.0 * -1)
+		self.assertEqual(pr_return.items[0].rejected_qty, 0.0)
+		self.assertEqual(pr_return.items[0].rejected_warehouse, "")
+
 
 def prepare_data_for_internal_transfer():
 	from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier