From bd3a1328687e6cd18580caf898dffac5baa5a4f4 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 14:42:08 +0000 Subject: [PATCH] feat: set options for IBAN fields (backport #49377) (#49413) Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com> --- .../doctype/bank_account/bank_account.json | 7 +++- .../doctype/bank_account/bank_account.py | 34 +++------------- .../doctype/bank_account/test_bank_account.py | 39 +------------------ .../bank_guarantee/bank_guarantee.json | 3 +- .../bank_transaction/bank_transaction.json | 5 ++- .../payment_request/payment_request.json | 9 +++-- erpnext/setup/doctype/employee/employee.json | 8 ++-- 7 files changed, 27 insertions(+), 78 deletions(-) diff --git a/erpnext/accounts/doctype/bank_account/bank_account.json b/erpnext/accounts/doctype/bank_account/bank_account.json index 962551b2417..4946dc168ba 100644 --- a/erpnext/accounts/doctype/bank_account/bank_account.json +++ b/erpnext/accounts/doctype/bank_account/bank_account.json @@ -132,7 +132,8 @@ "fieldtype": "Data", "in_list_view": 1, "label": "IBAN", - "length": 30 + "length": 34, + "options": "IBAN" }, { "fieldname": "column_break_12", @@ -208,6 +209,7 @@ "label": "Disabled" } ], + "grid_page_length": 50, "links": [ { "group": "Transactions", @@ -250,7 +252,7 @@ "link_fieldname": "default_bank_account" } ], - "modified": "2024-10-30 09:41:14.113414", + "modified": "2025-08-29 12:32:01.081687", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Account", @@ -282,6 +284,7 @@ "write": 1 } ], + "row_format": "Dynamic", "search_fields": "bank,account", "sort_field": "modified", "sort_order": "DESC", diff --git a/erpnext/accounts/doctype/bank_account/bank_account.py b/erpnext/accounts/doctype/bank_account/bank_account.py index 5a728eb415b..5a874701a39 100644 --- a/erpnext/accounts/doctype/bank_account/bank_account.py +++ b/erpnext/accounts/doctype/bank_account/bank_account.py @@ -9,7 +9,8 @@ from frappe.contacts.address_and_contact import ( load_address_and_contact, ) from frappe.model.document import Document -from frappe.utils import comma_and, get_link_to_form +from frappe.utils import comma_and, get_link_to_form, validate_iban +from frappe.utils.deprecations import deprecated class BankAccount(Document): @@ -52,7 +53,6 @@ class BankAccount(Document): def validate(self): self.validate_company() - self.validate_iban() self.validate_account() self.update_default_bank_account() @@ -72,34 +72,10 @@ class BankAccount(Document): if self.is_company_account and not self.company: frappe.throw(_("Company is manadatory for company account")) + @deprecated def validate_iban(self): - """ - Algorithm: https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN - """ - # IBAN field is optional - if not self.iban: - return - - def encode_char(c): - # Position in the alphabet (A=1, B=2, ...) plus nine - return str(9 + ord(c) - 64) - - # remove whitespaces, upper case to get the right number from ord() - iban = "".join(self.iban.split(" ")).upper() - - # Move country code and checksum from the start to the end - flipped = iban[4:] + iban[:4] - - # Encode characters as numbers - encoded = [encode_char(c) if ord(c) >= 65 and ord(c) <= 90 else c for c in flipped] - - try: - to_check = int("".join(encoded)) - except ValueError: - frappe.throw(_("IBAN is not valid")) - - if to_check % 97 != 1: - frappe.throw(_("IBAN is not valid")) + """Kept for backward compatibility, will be removed in v16.""" + validate_iban(self.iban, throw=True) def update_default_bank_account(self): if self.is_default and not self.disabled: diff --git a/erpnext/accounts/doctype/bank_account/test_bank_account.py b/erpnext/accounts/doctype/bank_account/test_bank_account.py index 0ec388d9e5c..d285b89d10c 100644 --- a/erpnext/accounts/doctype/bank_account/test_bank_account.py +++ b/erpnext/accounts/doctype/bank_account/test_bank_account.py @@ -3,45 +3,8 @@ import unittest -import frappe -from frappe import ValidationError - # test_records = frappe.get_test_records('Bank Account') class TestBankAccount(unittest.TestCase): - def test_validate_iban(self): - valid_ibans = [ - "GB82 WEST 1234 5698 7654 32", - "DE91 1000 0000 0123 4567 89", - "FR76 3000 6000 0112 3456 7890 189", - ] - - invalid_ibans = [ - # wrong checksum (3rd place) - "GB72 WEST 1234 5698 7654 32", - "DE81 1000 0000 0123 4567 89", - "FR66 3000 6000 0112 3456 7890 189", - ] - - bank_account = frappe.get_doc({"doctype": "Bank Account"}) - - try: - bank_account.validate_iban() - except AttributeError: - msg = "BankAccount.validate_iban() failed for empty IBAN" - self.fail(msg=msg) - - for iban in valid_ibans: - bank_account.iban = iban - try: - bank_account.validate_iban() - except ValidationError: - msg = f"BankAccount.validate_iban() failed for valid IBAN {iban}" - self.fail(msg=msg) - - for not_iban in invalid_ibans: - bank_account.iban = not_iban - msg = f"BankAccount.validate_iban() accepted invalid IBAN {not_iban}" - with self.assertRaises(ValidationError, msg=msg): - bank_account.validate_iban() + pass diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.json b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.json index dc5413e973c..c255ce7ba8f 100644 --- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.json +++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.json @@ -146,6 +146,7 @@ "fieldname": "iban", "fieldtype": "Data", "label": "IBAN", + "options": "IBAN", "read_only": 1 }, { @@ -216,7 +217,7 @@ ], "is_submittable": 1, "links": [], - "modified": "2025-09-25 23:44:12.473583", + "modified": "2025-09-26 00:38:17.584694", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Guarantee", diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json index 37fbd261898..02ff1dbf3e9 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.json +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.json @@ -223,7 +223,8 @@ { "fieldname": "bank_party_iban", "fieldtype": "Data", - "label": "Party IBAN (Bank Statement)" + "label": "Party IBAN (Bank Statement)", + "options": "IBAN" }, { "fieldname": "bank_party_account_number", @@ -238,7 +239,7 @@ "grid_page_length": 50, "is_submittable": 1, "links": [], - "modified": "2025-09-26 17:06:29.207673", + "modified": "2025-10-14 11:53:45.908169", "modified_by": "Administrator", "module": "Accounts", "name": "Bank Transaction", diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json index 5a19a080484..6853e9ca1fb 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.json +++ b/erpnext/accounts/doctype/payment_request/payment_request.json @@ -226,7 +226,8 @@ "fetch_from": "bank_account.iban", "fieldname": "iban", "fieldtype": "Read Only", - "label": "IBAN" + "label": "IBAN", + "options": "IBAN" }, { "fetch_from": "bank_account.branch_code", @@ -443,11 +444,12 @@ "label": "Phone Number" } ], + "grid_page_length": 50, "in_create": 1, "index_web_pages_for_search": 1, "is_submittable": 1, "links": [], - "modified": "2024-12-27 21:29:10.361894", + "modified": "2025-08-29 11:52:48.555415", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Request", @@ -482,8 +484,9 @@ "write": 1 } ], + "row_format": "Dynamic", "show_preview_popup": 1, "sort_field": "modified", "sort_order": "DESC", "states": [] -} \ No newline at end of file +} diff --git a/erpnext/setup/doctype/employee/employee.json b/erpnext/setup/doctype/employee/employee.json index 1c80fd84965..cc23b44bff0 100644 --- a/erpnext/setup/doctype/employee/employee.json +++ b/erpnext/setup/doctype/employee/employee.json @@ -814,7 +814,8 @@ "depends_on": "eval:doc.salary_mode == 'Bank'", "fieldname": "iban", "fieldtype": "Data", - "label": "IBAN" + "label": "IBAN", + "options": "IBAN" } ], "icon": "fa fa-user", @@ -822,7 +823,7 @@ "image_field": "image", "is_tree": 1, "links": [], - "modified": "2025-07-04 08:29:34.347269", + "modified": "2025-08-29 11:52:12.819878", "modified_by": "Administrator", "module": "Setup", "name": "Employee", @@ -864,6 +865,7 @@ "write": 1 } ], + "row_format": "Dynamic", "search_fields": "employee_name", "show_name_in_global_search": 1, "sort_field": "modified", @@ -871,4 +873,4 @@ "states": [], "title_field": "employee_name", "track_changes": 1 -} \ No newline at end of file +}