fix: Update paid amount for pos return (#20543)

* fix: Paid amount updation for pos return

* fix: Remove console

* fix: Styling

* fix: get  default mode of payment from POS profile

* fix: Add test cases

* fix: Codacy
diff --git a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
index 58f1216..64d347d 100644
--- a/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
+++ b/erpnext/accounts/doctype/pos_profile/test_pos_profile.py
@@ -29,27 +29,29 @@
 
 		frappe.db.sql("delete from `tabPOS Profile`")
 
-def make_pos_profile():
+def make_pos_profile(**args):
 	frappe.db.sql("delete from `tabPOS Profile`")
 
+	args = frappe._dict(args)
+
 	pos_profile = frappe.get_doc({
-		"company": "_Test Company",
-		"cost_center": "_Test Cost Center - _TC",
-		"currency": "INR",
+		"company": args.company or "_Test Company",
+		"cost_center": args.cost_center or "_Test Cost Center - _TC",
+		"currency": args.currency or "INR",
 		"doctype": "POS Profile",
-		"expense_account": "_Test Account Cost for Goods Sold - _TC",
-		"income_account": "Sales - _TC",
-		"name": "_Test POS Profile",
+		"expense_account": args.expense_account or "_Test Account Cost for Goods Sold - _TC",
+		"income_account":  args.income_account or "Sales - _TC",
+		"name":  args.name or "_Test POS Profile",
 		"naming_series": "_T-POS Profile-",
-		"selling_price_list": "_Test Price List",
-		"territory": "_Test Territory",
+		"selling_price_list":  args.selling_price_list or "_Test Price List",
+		"territory": args.territory or  "_Test Territory",
 		"customer_group": frappe.db.get_value('Customer Group', {'is_group': 0}, 'name'),
-		"warehouse": "_Test Warehouse - _TC",
-		"write_off_account": "_Test Write Off - _TC",
-		"write_off_cost_center": "_Test Write Off Cost Center - _TC"
+		"warehouse":  args.warehouse or "_Test Warehouse - _TC",
+		"write_off_account":  args.write_off_account or "_Test Write Off - _TC",
+		"write_off_cost_center":  args.write_off_cost_center or "_Test Write Off Cost Center - _TC"
 	})
 
-	if not frappe.db.exists("POS Profile", "_Test POS Profile"):
+	if not frappe.db.exists("POS Profile", args.name or "_Test POS Profile"):
 		pos_profile.insert()
 
 	return pos_profile
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index ad3640c..f5dd6e7 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -420,7 +420,7 @@
 
 		if pos:
 			self.allow_print_before_pay = pos.allow_print_before_pay
-			
+
 			if not for_validate:
 				self.tax_category = pos.get("tax_category")
 
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index a2a47b3..e48e6c9 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -705,6 +705,64 @@
 
 		self.pos_gl_entry(si, pos, 50)
 
+	def test_pos_returns_without_repayment(self):
+		pos_profile = make_pos_profile()
+
+		pos = create_sales_invoice(qty = 10, do_not_save=True)
+		pos.is_pos = 1
+		pos.pos_profile = pos_profile.name
+
+		pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 500})
+		pos.append("payments", {'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 500})
+		pos.insert()
+		pos.submit()
+
+		pos_return = create_sales_invoice(is_return=1,
+			return_against=pos.name, qty=-5, do_not_save=True)
+
+		pos_return.is_pos = 1
+		pos_return.pos_profile = pos_profile.name
+
+		pos_return.insert()
+		pos_return.submit()
+
+		self.assertFalse(pos_return.is_pos)
+		self.assertFalse(pos_return.get('payments'))
+
+	def test_pos_returns_with_repayment(self):
+		pos_profile = make_pos_profile()
+
+		pos_profile.append('payments', {
+			'default': 1,
+			'mode_of_payment': 'Cash',
+			'amount': 0.0
+		})
+
+		pos_profile.save()
+
+		pos = create_sales_invoice(qty = 10, do_not_save=True)
+
+		pos.is_pos = 1
+		pos.pos_profile = pos_profile.name
+
+		pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 500})
+		pos.append("payments", {'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 500})
+		pos.insert()
+		pos.submit()
+
+		pos_return = create_sales_invoice(is_return=1,
+			return_against=pos.name, qty=-5, do_not_save=True)
+
+		pos_return.is_pos = 1
+		pos_return.pos_profile = pos_profile.name
+		pos_return.insert()
+		pos_return.submit()
+
+		self.assertEqual(pos_return.get('payments')[0].amount, -500)
+		pos_profile.payments = []
+		pos_profile.save()
+
+
 	def test_pos_change_amount(self):
 		make_pos_profile()
 
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index b52a07d..95e661a 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -514,7 +514,7 @@
 		if self.doc.doctype == "Sales Invoice":
 			self.calculate_paid_amount()
 
-		if self.doc.is_return and self.doc.return_against: return
+		if self.doc.is_return and self.doc.return_against and not self.doc.get('is_pos'): return
 
 		self.doc.round_floats_in(self.doc, ["grand_total", "total_advance", "write_off_amount"])
 		self._set_in_company_currency(self.doc, ['write_off_amount'])
@@ -532,7 +532,7 @@
 			self.doc.round_floats_in(self.doc, ["paid_amount"])
 			change_amount = 0
 
-			if self.doc.doctype == "Sales Invoice":
+			if self.doc.doctype == "Sales Invoice" and not self.doc.get('is_return'):
 				self.calculate_write_off_amount()
 				self.calculate_change_amount()
 				change_amount = self.doc.change_amount \
@@ -544,6 +544,9 @@
 			self.doc.outstanding_amount = flt(total_amount_to_pay - flt(paid_amount) + flt(change_amount),
 				self.doc.precision("outstanding_amount"))
 
+			if self.doc.doctype == 'Sales Invoice' and self.doc.get('is_pos') and self.doc.get('is_return'):
+			 	self.update_paid_amount_for_return(total_amount_to_pay)
+
 	def calculate_paid_amount(self):
 
 		paid_amount = base_paid_amount = 0.0
@@ -614,6 +617,27 @@
 	def set_item_wise_tax_breakup(self):
 		self.doc.other_charges_calculation = get_itemised_tax_breakup_html(self.doc)
 
+	def update_paid_amount_for_return(self, total_amount_to_pay):
+		default_mode_of_payment = frappe.db.get_value('Sales Invoice Payment',
+			{'parent': self.doc.pos_profile, 'default': 1},
+			['mode_of_payment', 'type', 'account'], as_dict=1)
+
+		self.doc.payments = []
+
+		if default_mode_of_payment:
+			self.doc.append('payments', {
+				'mode_of_payment': default_mode_of_payment.mode_of_payment,
+				'type': default_mode_of_payment.type,
+				'account': default_mode_of_payment.account,
+				'amount': total_amount_to_pay
+			})
+		else:
+			self.doc.is_pos = 0
+			self.doc.pos_profile = ''
+
+		self.calculate_paid_amount()
+
+
 def get_itemised_tax_breakup_html(doc):
 	if not doc.taxes:
 		return
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index a51c2f0..9a5b750 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -39,6 +39,11 @@
 			this.calculate_total_advance(update_paid_amount);
 		}
 
+		if (this.frm.doc.doctype == "Sales Invoice" && this.frm.doc.is_pos &&
+			this.frm.doc.is_return) {
+			this.update_paid_amount_for_return();
+		}
+
 		// Sales person's commission
 		if(in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"], this.frm.doc.doctype)) {
 			this.calculate_commission();
@@ -635,23 +640,58 @@
 		}
 	},
 
-	set_default_payment: function(total_amount_to_pay, update_paid_amount){
+	update_paid_amount_for_return: function() {
+		var grand_total = this.frm.doc.rounded_total || this.frm.doc.grand_total;
+
+		if(this.frm.doc.party_account_currency == this.frm.doc.currency) {
+			var total_amount_to_pay = flt((grand_total - this.frm.doc.total_advance
+				- this.frm.doc.write_off_amount), precision("grand_total"));
+		} else {
+			var total_amount_to_pay = flt(
+				(flt(grand_total*this.frm.doc.conversion_rate, precision("grand_total"))
+					- this.frm.doc.total_advance - this.frm.doc.base_write_off_amount),
+				precision("base_grand_total")
+			);
+		}
+
+		frappe.db.get_value('Sales Invoice Payment', {'parent': this.frm.doc.pos_profile, 'default': 1},
+			['mode_of_payment', 'account', 'type'], (value) => {
+				if (this.frm.is_dirty()) {
+					frappe.model.clear_table(this.frm.doc, 'payments');
+					if (value) {
+						let row = frappe.model.add_child(this.frm.doc, 'Sales Invoice Payment', 'payments');
+						row.mode_of_payment = value.mode_of_payment;
+						row.type = value.type;
+						row.account = value.account;
+						row.default = 1;
+						row.amount = total_amount_to_pay;
+					} else {
+						this.frm.set_value('is_pos', 1);
+					}
+					this.frm.refresh_fields();
+				}
+			}, 'Sales Invoice');
+
+		this.calculate_paid_amount();
+	},
+
+	set_default_payment: function(total_amount_to_pay, update_paid_amount) {
 		var me = this;
 		var payment_status = true;
-		if(this.frm.doc.is_pos && (update_paid_amount===undefined || update_paid_amount)){
-			$.each(this.frm.doc['payments'] || [], function(index, data){
+		if(this.frm.doc.is_pos && (update_paid_amount===undefined || update_paid_amount)) {
+			$.each(this.frm.doc['payments'] || [], function(index, data) {
 				if(data.default && payment_status && total_amount_to_pay > 0) {
 					data.base_amount = flt(total_amount_to_pay, precision("base_amount"));
 					data.amount = flt(total_amount_to_pay / me.frm.doc.conversion_rate, precision("amount"));
 					payment_status = false;
-				}else if(me.frm.doc.paid_amount){
+				} else if(me.frm.doc.paid_amount) {
 					data.amount = 0.0;
 				}
 			});
 		}
 	},
 
-	calculate_paid_amount: function(){
+	calculate_paid_amount: function() {
 		var me = this;
 		var paid_amount = 0.0;
 		var base_paid_amount = 0.0;