refactor: cancel gain/loss JE on Journal as payment cancellation
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index 0115fd7..e6b8b5d 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -87,9 +87,8 @@
 		self.update_invoice_discounting()
 
 	def on_cancel(self):
-		from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
-
-		unlink_ref_doc_from_payment_entries(self)
+		# References for this Journal are removed on the `on_cancel` event in accounts_controller
+		super(JournalEntry, self).on_cancel()
 		self.ignore_linked_doctypes = (
 			"GL Entry",
 			"Stock Ledger Entry",
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 49a6367..53d9e21 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -655,7 +655,7 @@
 	"""
 	Cancel Exchange Gain/Loss for Sales/Purchase Invoice, if they have any.
 	"""
-	if parent_doc.doctype in ["Sales Invoice", "Purchase Invoice", "Payment Entry"]:
+	if parent_doc.doctype in ["Sales Invoice", "Purchase Invoice", "Payment Entry", "Journal Entry"]:
 		journals = frappe.db.get_all(
 			"Journal Entry Account",
 			filters={
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 0b3b41d..a126dfe 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -991,10 +991,11 @@
 							party_account_currency = frappe.get_cached_value(
 								"Account", party_account, "account_currency"
 							)
-							dr_or_cr = "debit" if arg.get("difference_amount") > 0 else "credit"
 
-							if arg.reference_doctype == "Purchase Invoice":
-								dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
+							dr_or_cr = "debit" if arg.get("party_type") == "Customer" else "credit"
+
+							# if arg.reference_doctype == "Purchase Invoice":
+							# 	dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
 
 							reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
 
@@ -1038,6 +1039,7 @@
 									"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,
@@ -1163,6 +1165,7 @@
 
 						journal_entry.save()
 						journal_entry.submit()
+			# frappe.throw("stopping...")
 
 	def update_against_document_in_jv(self):
 		"""
@@ -1229,7 +1232,7 @@
 			unlink_ref_doc_from_payment_entries,
 		)
 
-		if self.doctype in ["Sales Invoice", "Purchase Invoice", "Payment Entry"]:
+		if self.doctype in ["Sales Invoice", "Purchase Invoice", "Payment Entry", "Journal Entry"]:
 			# Cancel Exchange Gain/Loss Journal before unlinking
 			cancel_exchange_gain_loss_journal(self)
 
diff --git a/erpnext/controllers/tests/test_accounts_controller.py b/erpnext/controllers/tests/test_accounts_controller.py
index 31aa857..28a569b 100644
--- a/erpnext/controllers/tests/test_accounts_controller.py
+++ b/erpnext/controllers/tests/test_accounts_controller.py
@@ -11,6 +11,7 @@
 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.purchase_invoice.test_purchase_invoice import make_purchase_invoice
 from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
 from erpnext.accounts.party import get_party_account
 from erpnext.stock.doctype.item.test_item import create_item
@@ -20,7 +21,7 @@
 	if not frappe.db.exists("Customer", customer_name):
 		customer = frappe.new_doc("Customer")
 		customer.customer_name = customer_name
-		customer.type = "Individual"
+		customer.customer_type = "Individual"
 
 		if currency:
 			customer.default_currency = currency
@@ -30,7 +31,22 @@
 		return customer_name
 
 
-class TestAccountsController(FrappeTestCase):
+def make_supplier(supplier_name, currency=None):
+	if not frappe.db.exists("Supplier", supplier_name):
+		supplier = frappe.new_doc("Supplier")
+		supplier.supplier_name = supplier_name
+		supplier.supplier_type = "Individual"
+
+		if currency:
+			supplier.default_currency = currency
+		supplier.save()
+		return supplier.name
+	else:
+		return supplier_name
+
+
+# class TestAccountsController(FrappeTestCase):
+class TestAccountsController(unittest.TestCase):
 	"""
 	Test Exchange Gain/Loss booking on various scenarios
 	"""
@@ -39,11 +55,12 @@
 		self.create_company()
 		self.create_account()
 		self.create_item()
-		self.create_customer()
+		self.create_parties()
 		self.clear_old_entries()
 
 	def tearDown(self):
-		frappe.db.rollback()
+		# frappe.db.rollback()
+		pass
 
 	def create_company(self):
 		company_name = "_Test Company MC"
@@ -80,9 +97,16 @@
 		)
 		self.item = item if isinstance(item, str) else item.item_code
 
+	def create_parties(self):
+		self.create_customer()
+		self.create_supplier()
+
 	def create_customer(self):
 		self.customer = make_customer("_Test MC Customer USD", "USD")
 
+	def create_supplier(self):
+		self.supplier = make_supplier("_Test MC Supplier USD", "USD")
+
 	def create_account(self):
 		account_name = "Debtors USD"
 		if not frappe.db.get_value(
@@ -215,7 +239,7 @@
 		return journals
 
 	def test_01_payment_against_invoice(self):
-		# Invoice in Foreign Currency
+		# Sales Invoice in Foreign Currency
 		si = self.create_sales_invoice(qty=1, rate=1)
 		# Payment
 		pe = self.create_payment_entry(amount=1, source_exc_rate=75).save()