refactor: split make_exchage_gain_loss_journal into smaller function
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 40432f7..6bf9d29 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -968,6 +968,78 @@
 
 				d.exchange_gain_loss = difference
 
+	def create_gain_loss_journal(
+		self,
+		party_type,
+		party,
+		party_account,
+		gain_loss_account,
+		exc_gain_loss,
+		dr_or_cr,
+		reverse_dr_or_cr,
+		ref1_dt,
+		ref1_dn,
+		ref1_detail_no,
+		ref2_dt,
+		ref2_dn,
+		ref2_detail_no,
+	) -> str:
+		journal_entry = frappe.new_doc("Journal Entry")
+		journal_entry.voucher_type = "Exchange Gain Or Loss"
+		journal_entry.company = self.company
+		journal_entry.posting_date = nowdate()
+		journal_entry.multi_currency = 1
+
+		party_account_currency = frappe.get_cached_value("Account", party_account, "account_currency")
+
+		if not gain_loss_account:
+			frappe.throw(
+				_("Please set default Exchange Gain/Loss Account in Company {}").format(self.get("company"))
+			)
+		gain_loss_account_currency = get_account_currency(gain_loss_account)
+		company_currency = frappe.get_cached_value("Company", self.company, "default_currency")
+
+		if gain_loss_account_currency != self.company_currency:
+			frappe.throw(_("Currency for {0} must be {1}").format(gain_loss_account, company_currency))
+
+		journal_account = frappe._dict(
+			{
+				"account": party_account,
+				"party_type": party_type,
+				"party": party,
+				"account_currency": party_account_currency,
+				"exchange_rate": 0,
+				"cost_center": erpnext.get_default_cost_center(self.company),
+				"reference_type": ref1_dt,
+				"reference_name": ref1_dn,
+				"reference_detail_no": ref1_detail_no,
+				dr_or_cr: abs(exc_gain_loss),
+				dr_or_cr + "_in_account_currency": 0,
+			}
+		)
+
+		journal_entry.append("accounts", journal_account)
+
+		journal_account = frappe._dict(
+			{
+				"account": gain_loss_account,
+				"account_currency": gain_loss_account_currency,
+				"exchange_rate": 1,
+				"cost_center": erpnext.get_default_cost_center(self.company),
+				"reference_type": ref2_dt,
+				"reference_name": ref2_dn,
+				"reference_detail_no": ref2_detail_no,
+				reverse_dr_or_cr + "_in_account_currency": 0,
+				reverse_dr_or_cr: abs(exc_gain_loss),
+			}
+		)
+
+		journal_entry.append("accounts", journal_account)
+
+		journal_entry.save()
+		journal_entry.submit()
+		return journal_entry.name
+
 	def make_exchange_gain_loss_journal(self, args: dict = None) -> None:
 		"""
 		Make Exchange Gain/Loss journal for Invoices and Payments
@@ -978,23 +1050,16 @@
 			if self.get("doctype") == "Journal Entry":
 				# 'args' is populated with exchange gain/loss account and the amount to be booked.
 				# These are generated by Sales/Purchase Invoice during reconciliation and advance allocation.
+				# and below logic is only for such scenarios
 				if args:
 					for arg in args:
 						# Advance section uses `exchange_gain_loss` and reconciliation uses `difference_amount`
 						if (
 							arg.get("difference_amount", 0) != 0 or arg.get("exchange_gain_loss", 0) != 0
 						) and arg.get("difference_account"):
-							journal_entry = frappe.new_doc("Journal Entry")
-							journal_entry.voucher_type = "Exchange Gain Or Loss"
-							journal_entry.company = self.company
-							journal_entry.posting_date = nowdate()
-							journal_entry.multi_currency = 1
 
 							party_account = arg.get("account")
-							party_account_currency = frappe.get_cached_value(
-								"Account", party_account, "account_currency"
-							)
-
+							gain_loss_account = arg.get("difference_account")
 							difference_amount = arg.get("difference_amount") or arg.get("exchange_gain_loss")
 							if difference_amount > 0:
 								dr_or_cr = "debit" if arg.get("party_type") == "Customer" else "credit"
@@ -1003,60 +1068,22 @@
 
 							reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
 
-							gain_loss_account = arg.get("difference_account")
-							if not gain_loss_account:
-								frappe.throw(
-									_("Please set default Exchange Gain/Loss Account in Company {}").format(
-										self.get("company")
-									)
-								)
-
-							gain_loss_account_currency = get_account_currency(gain_loss_account)
-							if gain_loss_account_currency != self.company_currency:
-								frappe.throw(
-									_("Currency for {0} must be {1}").format(gain_loss_account, self.company_currency)
-								)
-
-							journal_account = frappe._dict(
-								{
-									"account": party_account,
-									"party_type": arg.get("party_type"),
-									"party": arg.get("party"),
-									"account_currency": party_account_currency,
-									"exchange_rate": 0,
-									"cost_center": erpnext.get_default_cost_center(self.company),
-									"reference_type": arg.get("against_voucher_type"),
-									"reference_name": arg.get("against_voucher"),
-									"reference_detail_no": arg.get("idx"),
-									dr_or_cr: abs(difference_amount),
-									dr_or_cr + "_in_account_currency": 0,
-								}
+							self.create_gain_loss_journal(
+								arg.get("party_type"),
+								arg.get("party"),
+								party_account,
+								gain_loss_account,
+								difference_amount,
+								dr_or_cr,
+								reverse_dr_or_cr,
+								arg.get("against_voucher_type"),
+								arg.get("against_voucher"),
+								arg.get("idx"),
+								self.doctype,
+								self.name,
+								arg.get("idx"),
 							)
 
-							journal_entry.append("accounts", journal_account)
-
-							journal_account = frappe._dict(
-								{
-									"account": gain_loss_account,
-									"account_currency": gain_loss_account_currency,
-									"exchange_rate": 1,
-									"cost_center": erpnext.get_default_cost_center(self.company),
-									# TODO: figure out a way to pass reference
-									# TODO: add reference_detail_no field in payment ledger
-									# throws 'Journal Entry doesn't have {account} or doesn't have matched account'
-									"reference_type": self.doctype,
-									"reference_name": self.name,
-									"reference_detail_no": arg.idx,
-									reverse_dr_or_cr: abs(difference_amount),
-									reverse_dr_or_cr + "_in_account_currency": 0,
-								}
-							)
-
-							journal_entry.append("accounts", journal_account)
-
-							journal_entry.save()
-							journal_entry.submit()
-
 			if self.get("doctype") == "Payment Entry":
 				# For Payment Entry, exchange_gain_loss field in the `references` table is the trigger for journal creation
 				gain_loss_to_book = [x for x in self.references if x.exchange_gain_loss != 0]
@@ -1093,23 +1120,15 @@
 						)
 
 				for d in gain_loss_to_book:
+					# Filter out References for which Gain/Loss is already booked
 					if d.exchange_gain_loss and (
 						(d.reference_doctype, d.reference_name, str(d.idx)) not in booked
 					):
-						journal_entry = frappe.new_doc("Journal Entry")
-						journal_entry.voucher_type = "Exchange Gain Or Loss"
-						journal_entry.company = self.company
-						journal_entry.posting_date = nowdate()
-						journal_entry.multi_currency = 1
-
 						if self.payment_type == "Receive":
 							party_account = self.paid_from
 						elif self.payment_type == "Pay":
 							party_account = self.paid_to
 
-						party_account_currency = frappe.get_cached_value(
-							"Account", party_account, "account_currency"
-						)
 						dr_or_cr = "debit" if d.exchange_gain_loss > 0 else "credit"
 
 						if d.reference_doctype == "Purchase Invoice":
@@ -1120,54 +1139,22 @@
 						gain_loss_account = frappe.get_cached_value(
 							"Company", self.company, "exchange_gain_loss_account"
 						)
-						if not gain_loss_account:
-							frappe.throw(
-								_("Please set default Exchange Gain/Loss Account in Company {}").format(
-									self.get("company")
-								)
-							)
-						gain_loss_account_currency = get_account_currency(gain_loss_account)
-						if gain_loss_account_currency != self.company_currency:
-							frappe.throw(
-								_("Currency for {0} must be {1}").format(gain_loss_account, self.company_currency)
-							)
 
-						journal_account = frappe._dict(
-							{
-								"account": party_account,
-								"party_type": self.party_type,
-								"party": self.party,
-								"account_currency": party_account_currency,
-								"exchange_rate": 0,
-								"cost_center": erpnext.get_default_cost_center(self.company),
-								"reference_type": d.reference_doctype,
-								"reference_name": d.reference_name,
-								"reference_detail_no": d.idx,
-								dr_or_cr: abs(d.exchange_gain_loss),
-								dr_or_cr + "_in_account_currency": 0,
-							}
+						self.create_gain_loss_journal(
+							self.party_type,
+							self.party,
+							party_account,
+							gain_loss_account,
+							d.exchange_gain_loss,
+							dr_or_cr,
+							reverse_dr_or_cr,
+							d.reference_doctype,
+							d.reference_name,
+							d.idx,
+							self.doctype,
+							self.name,
+							d.idx,
 						)
-
-						journal_entry.append("accounts", journal_account)
-
-						journal_account = frappe._dict(
-							{
-								"account": gain_loss_account,
-								"account_currency": gain_loss_account_currency,
-								"exchange_rate": 1,
-								"cost_center": erpnext.get_default_cost_center(self.company),
-								"reference_type": self.doctype,
-								"reference_name": self.name,
-								"reference_detail_no": d.idx,
-								reverse_dr_or_cr + "_in_account_currency": 0,
-								reverse_dr_or_cr: abs(d.exchange_gain_loss),
-							}
-						)
-
-						journal_entry.append("accounts", journal_account)
-
-						journal_entry.save()
-						journal_entry.submit()
 			# frappe.throw("stopping...")
 
 	def update_against_document_in_jv(self):