Merge pull request #29884 from resilient-tech/remove-india

refactor: remove India specific code
diff --git a/.github/helper/.flake8_strict b/.github/helper/.flake8_strict
index a79137d..198ec7b 100644
--- a/.github/helper/.flake8_strict
+++ b/.github/helper/.flake8_strict
@@ -66,6 +66,7 @@
     F841,
     E713,
     E712,
+    B023
 
 
 max-line-length = 200
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 5b2b526..5ed34d3 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -162,7 +162,7 @@
 							{
 								"reference_type": inv.voucher_type,
 								"reference_name": inv.voucher_no,
-								"amount": -(inv.outstanding),
+								"amount": -(inv.outstanding_in_account_currency),
 								"posting_date": inv.posting_date,
 								"currency": inv.currency,
 							}
diff --git a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
index 575ac74..625382a 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
@@ -19,6 +19,7 @@
 		self.create_company()
 		self.create_item()
 		self.create_customer()
+		self.create_account()
 		self.clear_old_entries()
 
 	def tearDown(self):
@@ -89,6 +90,38 @@
 			customer.save()
 			self.customer2 = customer.name
 
+		if frappe.db.exists("Customer", "_Test PR Customer 3"):
+			self.customer3 = "_Test PR Customer 3"
+		else:
+			customer = frappe.new_doc("Customer")
+			customer.customer_name = "_Test PR Customer 3"
+			customer.type = "Individual"
+			customer.default_currency = "EUR"
+			customer.save()
+			self.customer3 = customer.name
+
+	def create_account(self):
+		account_name = "Debtors EUR"
+		if not frappe.db.get_value(
+			"Account", filters={"account_name": account_name, "company": self.company}
+		):
+			acc = frappe.new_doc("Account")
+			acc.account_name = account_name
+			acc.parent_account = "Accounts Receivable - _PR"
+			acc.company = self.company
+			acc.account_currency = "EUR"
+			acc.account_type = "Receivable"
+			acc.insert()
+		else:
+			name = frappe.db.get_value(
+				"Account",
+				filters={"account_name": account_name, "company": self.company},
+				fieldname="name",
+				pluck=True,
+			)
+			acc = frappe.get_doc("Account", name)
+		self.debtors_eur = acc.name
+
 	def create_sales_invoice(
 		self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
 	):
@@ -118,7 +151,7 @@
 		)
 		return sinv
 
-	def create_payment_entry(self, amount=100, posting_date=nowdate()):
+	def create_payment_entry(self, amount=100, posting_date=nowdate(), customer=None):
 		"""
 		Helper function to populate default values in payment entry
 		"""
@@ -126,7 +159,7 @@
 			company=self.company,
 			payment_type="Receive",
 			party_type="Customer",
-			party=self.customer,
+			party=customer or self.customer,
 			paid_from=self.debit_to,
 			paid_to=self.bank,
 			paid_amount=amount,
@@ -454,3 +487,59 @@
 		self.assertEqual(len(pr.get("payments")), 1)
 		self.assertEqual(pr.get("invoices")[0].outstanding_amount, 20)
 		self.assertEqual(pr.get("payments")[0].amount, 20)
+
+	def test_pr_output_foreign_currency_and_amount(self):
+		# test for currency and amount invoices and payments
+		transaction_date = nowdate()
+		# In EUR
+		amount = 100
+		exchange_rate = 80
+
+		si = self.create_sales_invoice(
+			qty=1, rate=amount, posting_date=transaction_date, do_not_save=True, do_not_submit=True
+		)
+		si.customer = self.customer3
+		si.currency = "EUR"
+		si.conversion_rate = exchange_rate
+		si.debit_to = self.debtors_eur
+		si = si.save().submit()
+
+		cr_note = self.create_sales_invoice(
+			qty=-1, rate=amount, posting_date=transaction_date, do_not_save=True, do_not_submit=True
+		)
+		cr_note.customer = self.customer3
+		cr_note.is_return = 1
+		cr_note.currency = "EUR"
+		cr_note.conversion_rate = exchange_rate
+		cr_note.debit_to = self.debtors_eur
+		cr_note = cr_note.save().submit()
+
+		pr = self.create_payment_reconciliation()
+		pr.party = self.customer3
+		pr.receivable_payable_account = self.debtors_eur
+		pr.get_unreconciled_entries()
+
+		self.assertEqual(len(pr.invoices), 1)
+		self.assertEqual(len(pr.payments), 1)
+
+		self.assertEqual(pr.invoices[0].amount, amount)
+		self.assertEqual(pr.invoices[0].currency, "EUR")
+		self.assertEqual(pr.payments[0].amount, amount)
+		self.assertEqual(pr.payments[0].currency, "EUR")
+
+		cr_note.cancel()
+
+		pay = self.create_payment_entry(
+			amount=amount, posting_date=transaction_date, customer=self.customer3
+		)
+		pay.paid_from = self.debtors_eur
+		pay.paid_from_account_currency = "EUR"
+		pay.source_exchange_rate = exchange_rate
+		pay.received_amount = exchange_rate * amount
+		pay = pay.save().submit()
+
+		pr.get_unreconciled_entries()
+		self.assertEqual(len(pr.invoices), 1)
+		self.assertEqual(len(pr.payments), 1)
+		self.assertEqual(pr.payments[0].amount, amount)
+		self.assertEqual(pr.payments[0].currency, "EUR")
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 8daff9d..6be8fd7 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -855,8 +855,8 @@
 	)
 
 	for d in invoice_list:
-		payment_amount = d.invoice_amount - d.outstanding
-		outstanding_amount = d.outstanding
+		payment_amount = d.invoice_amount_in_account_currency - d.outstanding_in_account_currency
+		outstanding_amount = d.outstanding_in_account_currency
 		if outstanding_amount > 0.5 / (10**precision):
 			if (
 				min_outstanding
@@ -872,7 +872,7 @@
 							"voucher_no": d.voucher_no,
 							"voucher_type": d.voucher_type,
 							"posting_date": d.posting_date,
-							"invoice_amount": flt(d.invoice_amount),
+							"invoice_amount": flt(d.invoice_amount_in_account_currency),
 							"payment_amount": payment_amount,
 							"outstanding_amount": outstanding_amount,
 							"due_date": d.due_date,
@@ -1412,7 +1412,7 @@
 						if gle.against_voucher_type
 						else gle.voucher_type,
 						"against_voucher_no": gle.against_voucher if gle.against_voucher else gle.voucher_no,
-						"currency": gle.currency,
+						"account_currency": gle.account_currency,
 						"amount": dr_or_cr,
 						"amount_in_account_currency": dr_or_cr_account_currency,
 						"delinked": True if cancel else False,
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 6bb4cfc..b556d99 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -1243,7 +1243,7 @@
 		ste_doc.insert()
 		ste_doc.submit()
 
-		batch_list = [row.batch_no for row in ste_doc.items]
+		batch_list = sorted([row.batch_no for row in ste_doc.items])
 
 		wo_doc = make_wo_order_test_record(production_item=fg_item, qty=4)
 		transferred_ste_doc = frappe.get_doc(
diff --git a/erpnext/startup/boot.py b/erpnext/startup/boot.py
index c3445ab..bb120ea 100644
--- a/erpnext/startup/boot.py
+++ b/erpnext/startup/boot.py
@@ -14,7 +14,6 @@
 	if frappe.session["user"] != "Guest":
 		update_page_info(bootinfo)
 
-		load_country_and_currency(bootinfo)
 		bootinfo.sysdefaults.territory = frappe.db.get_single_value("Selling Settings", "territory")
 		bootinfo.sysdefaults.customer_group = frappe.db.get_single_value(
 			"Selling Settings", "customer_group"
@@ -53,20 +52,6 @@
 		bootinfo.party_account_types = frappe._dict(party_account_types)
 
 
-def load_country_and_currency(bootinfo):
-	country = frappe.db.get_default("country")
-	if country and frappe.db.exists("Country", country):
-		bootinfo.docs += [frappe.get_doc("Country", country)]
-
-	bootinfo.docs += frappe.db.sql(
-		"""select name, fraction, fraction_units,
-		number_format, smallest_currency_fraction_value, symbol from tabCurrency
-		where enabled=1""",
-		as_dict=1,
-		update={"doctype": ":Currency"},
-	)
-
-
 def update_page_info(bootinfo):
 	bootinfo.page_info.update(
 		{
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index fcf0cd1..704e1fc 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -511,6 +511,7 @@
 				and not d.is_fixed_asset
 				and flt(d.qty)
 				and provisional_accounting_for_non_stock_items
+				and d.get("provisional_expense_account")
 			):
 				self.add_provisional_gl_entry(
 					d, gl_entries, self.posting_date, d.get("provisional_expense_account")
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 4b2850e..46a1e70 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -1661,7 +1661,8 @@
 				qty = frappe.utils.ceil(qty)
 
 			if row.batch_details:
-				for batch_no, batch_qty in row.batch_details.items():
+				batches = sorted(row.batch_details.items(), key=lambda x: x[0])
+				for batch_no, batch_qty in batches:
 					if qty <= 0 or batch_qty <= 0:
 						continue