Merge pull request #6976 from saurabh6790/advance_payment_entry_cancellation_fix

[fix] on advance payment entry cancellation delink invoice and pyamen…
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 7b9bf16..d4f8edb 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -60,7 +60,14 @@
 		self.setup_party_account_field()
 		self.make_gl_entries(cancel=1)
 		self.update_advance_paid()
-							
+		self.delink_advance_entry_references()
+	
+	def delink_advance_entry_references(self):
+		for reference in self.references:
+			if reference.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
+				doc = frappe.get_doc(reference.reference_doctype, reference.reference_name)
+				doc.delink_advance_entries(self.name)
+
 	def set_missing_values(self):
 		if self.payment_type == "Internal Transfer":
 			for field in ("party", "party_balance", "total_allocated_amount", 
diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
index e82d55e..d8c9b04 100644
--- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
@@ -460,7 +460,7 @@
 		pi.load_from_db()
 		
 		#check outstanding after advance allocation
-		self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total - pi.total_advance, pi.precision("outstanding_amount")))
+		self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total - pi.total_advance))
 		
 		#added to avoid Document has been modified exception
 		jv = frappe.get_doc("Journal Entry", jv.name)
@@ -468,7 +468,54 @@
 		
 		pi.load_from_db()
 		#check outstanding after advance cancellation
-		self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total + pi.total_advance, pi.precision("outstanding_amount")))
+		self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total + pi.total_advance))
+
+	def test_outstanding_amount_after_advance_payment_entry_cancelation(self):
+		pe = frappe.get_doc({
+			"doctype": "Payment Entry",
+			"payment_type": "Pay",
+			"party_type": "Supplier",
+			"party": "_Test Supplier",
+			"company": "_Test Company",
+			"paid_from_account_currency": "INR",
+			"paid_to_account_currency": "INR",
+			"source_exchange_rate": 1,
+			"target_exchange_rate": 1,
+			"reference_no": "1",
+			"reference_date": nowdate(),
+			"received_amount": 300,
+			"paid_amount": 300,
+			"paid_from": "_Test Cash - _TC",
+			"paid_to": "_Test Payable - _TC"
+		})
+		pe.insert()
+		pe.submit()
+		
+		pi = frappe.copy_doc(test_records[0])
+		pi.is_pos = 0
+		pi.append("advances", {
+			"doctype": "Purchase Invoice Advance",
+			"reference_type": "Payment Entry",
+			"reference_name": pe.name,
+			"advance_amount": 300,
+			"allocated_amount": 300,
+			"remarks": pe.remarks
+		})
+		pi.insert()
+		pi.submit()
+		
+		pi.load_from_db()
+
+		#check outstanding after advance allocation
+		self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total - pi.total_advance))
+		
+		#added to avoid Document has been modified exception
+		pe = frappe.get_doc("Payment Entry", pe.name)
+		pe.cancel()
+		
+		pi.load_from_db()
+		#check outstanding after advance cancellation
+		self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total + pi.total_advance))
 
 def unlink_payment_on_cancel_of_invoice(enable=1):
 	accounts_settings = frappe.get_doc("Accounts Settings")
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 12b90ed..511eeaa 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1013,6 +1013,53 @@
 		si.load_from_db()
 		#check outstanding after advance cancellation
 		self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total + si.total_advance, si.precision("outstanding_amount")))
+	
+	def test_outstanding_amount_after_advance_payment_entry_cancelation(self):
+		pe = frappe.get_doc({
+			"doctype": "Payment Entry",
+			"payment_type": "Receive",
+			"party_type": "Customer",
+			"party": "_Test Customer",
+			"company": "_Test Company",
+			"paid_from_account_currency": "INR",
+			"paid_to_account_currency": "INR",
+			"source_exchange_rate": 1,
+			"target_exchange_rate": 1,
+			"reference_no": "1",
+			"reference_date": nowdate(),
+			"received_amount": 300,
+			"paid_amount": 300,
+			"paid_from": "_Test Receivable - _TC",
+			"paid_to": "_Test Cash - _TC"
+		})
+		pe.insert()
+		pe.submit()
+		
+		si = frappe.copy_doc(test_records[0])
+		si.is_pos = 0
+		si.append("advances", {
+			"doctype": "Sales Invoice Advance",
+			"reference_type": "Payment Entry",
+			"reference_name": pe.name,
+			"advance_amount": 300,
+			"allocated_amount": 300,
+			"remarks": pe.remarks
+		})
+		si.insert()
+		si.submit()
+		
+		si.load_from_db()
+
+		#check outstanding after advance allocation
+		self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total - si.total_advance, si.precision("outstanding_amount")))
+		
+		#added to avoid Document has been modified exception
+		pe = frappe.get_doc("Payment Entry", pe.name)
+		pe.cancel()
+		
+		si.load_from_db()
+		#check outstanding after advance cancellation
+		self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total + si.total_advance, si.precision("outstanding_amount")))
 
 def create_sales_invoice(**args):
 	si = frappe.new_doc("Sales Invoice")
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index f85edfd..051334c 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -126,11 +126,11 @@
 		
 		return ret
 	
-	def delink_advance_entries(self, jv):
+	def delink_advance_entries(self, linked_doc_name):
 		total_allocated_amount = 0
 		for adv in self.advances:
 			consider_for_total_advance = True
-			if adv.reference_name == jv:
+			if adv.reference_name == linked_doc_name:
 				frappe.db.sql("""delete from `tab{0} Advance`
 					where name = %s""".format(self.doctype), adv.name)
 				consider_for_total_advance = False