Merge pull request #24891 from marination/pos-opening-entry-pre-release

fix: POS Opening Entry with empty balance detail rows
diff --git a/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py b/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
index cb5b3a5..0023a84 100644
--- a/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
+++ b/erpnext/accounts/doctype/pos_opening_entry/pos_opening_entry.py
@@ -20,15 +20,16 @@
 
 		if not cint(frappe.db.get_value("User", self.user, "enabled")):
 			frappe.throw(_("User {} is disabled. Please select valid user/cashier").format(self.user))
-	
+
 	def validate_payment_method_account(self):
 		invalid_modes = []
 		for d in self.balance_details:
-			account = frappe.db.get_value("Mode of Payment Account", 
-				{"parent": d.mode_of_payment, "company": self.company}, "default_account")
-			if not account:
-				invalid_modes.append(get_link_to_form("Mode of Payment", d.mode_of_payment))
-		
+			if d.mode_of_payment:
+				account = frappe.db.get_value("Mode of Payment Account",
+					{"parent": d.mode_of_payment, "company": self.company}, "default_account")
+				if not account:
+					invalid_modes.append(get_link_to_form("Mode of Payment", d.mode_of_payment))
+
 		if invalid_modes:
 			if invalid_modes == 1:
 				msg = _("Please set default Cash or Bank account in Mode of Payment {}")
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index 45b4e30..89fd9c7 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -106,6 +106,10 @@
 					})
 					return frappe.utils.play_sound("error");
 				}
+
+				// filter balance details for empty rows
+				balance_details = balance_details.filter(d => d.mode_of_payment);
+
 				const method = "erpnext.selling.page.point_of_sale.point_of_sale.create_opening_voucher";
 				const res = await frappe.call({ method, args: { pos_profile, company, balance_details }, freeze:true });
 				!res.exc && this.prepare_app_defaults(res.message);