mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-24 21:52:21 +01:00
Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
This commit is contained in:
@@ -132,7 +132,8 @@
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "IBAN",
|
"label": "IBAN",
|
||||||
"length": 30
|
"length": 34,
|
||||||
|
"options": "IBAN"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_12",
|
"fieldname": "column_break_12",
|
||||||
@@ -208,6 +209,7 @@
|
|||||||
"label": "Disabled"
|
"label": "Disabled"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"grid_page_length": 50,
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"group": "Transactions",
|
"group": "Transactions",
|
||||||
@@ -250,7 +252,7 @@
|
|||||||
"link_fieldname": "default_bank_account"
|
"link_fieldname": "default_bank_account"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2024-10-30 09:41:14.113414",
|
"modified": "2025-08-29 12:32:01.081687",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Account",
|
"name": "Bank Account",
|
||||||
@@ -282,6 +284,7 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"row_format": "Dynamic",
|
||||||
"search_fields": "bank,account",
|
"search_fields": "bank,account",
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ from frappe.contacts.address_and_contact import (
|
|||||||
load_address_and_contact,
|
load_address_and_contact,
|
||||||
)
|
)
|
||||||
from frappe.model.document import Document
|
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):
|
class BankAccount(Document):
|
||||||
@@ -52,7 +53,6 @@ class BankAccount(Document):
|
|||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_company()
|
self.validate_company()
|
||||||
self.validate_iban()
|
|
||||||
self.validate_account()
|
self.validate_account()
|
||||||
self.update_default_bank_account()
|
self.update_default_bank_account()
|
||||||
|
|
||||||
@@ -72,34 +72,10 @@ class BankAccount(Document):
|
|||||||
if self.is_company_account and not self.company:
|
if self.is_company_account and not self.company:
|
||||||
frappe.throw(_("Company is manadatory for company account"))
|
frappe.throw(_("Company is manadatory for company account"))
|
||||||
|
|
||||||
|
@deprecated
|
||||||
def validate_iban(self):
|
def validate_iban(self):
|
||||||
"""
|
"""Kept for backward compatibility, will be removed in v16."""
|
||||||
Algorithm: https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN
|
validate_iban(self.iban, throw=True)
|
||||||
"""
|
|
||||||
# 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"))
|
|
||||||
|
|
||||||
def update_default_bank_account(self):
|
def update_default_bank_account(self):
|
||||||
if self.is_default and not self.disabled:
|
if self.is_default and not self.disabled:
|
||||||
|
|||||||
@@ -3,45 +3,8 @@
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import frappe
|
|
||||||
from frappe import ValidationError
|
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Bank Account')
|
# test_records = frappe.get_test_records('Bank Account')
|
||||||
|
|
||||||
|
|
||||||
class TestBankAccount(unittest.TestCase):
|
class TestBankAccount(unittest.TestCase):
|
||||||
def test_validate_iban(self):
|
pass
|
||||||
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()
|
|
||||||
|
|||||||
@@ -146,6 +146,7 @@
|
|||||||
"fieldname": "iban",
|
"fieldname": "iban",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "IBAN",
|
"label": "IBAN",
|
||||||
|
"options": "IBAN",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -216,7 +217,7 @@
|
|||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-09-25 23:44:12.473583",
|
"modified": "2025-09-26 00:38:17.584694",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Guarantee",
|
"name": "Bank Guarantee",
|
||||||
|
|||||||
@@ -223,7 +223,8 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "bank_party_iban",
|
"fieldname": "bank_party_iban",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Party IBAN (Bank Statement)"
|
"label": "Party IBAN (Bank Statement)",
|
||||||
|
"options": "IBAN"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "bank_party_account_number",
|
"fieldname": "bank_party_account_number",
|
||||||
@@ -238,7 +239,7 @@
|
|||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-09-26 17:06:29.207673",
|
"modified": "2025-10-14 11:53:45.908169",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Transaction",
|
"name": "Bank Transaction",
|
||||||
|
|||||||
@@ -226,7 +226,8 @@
|
|||||||
"fetch_from": "bank_account.iban",
|
"fetch_from": "bank_account.iban",
|
||||||
"fieldname": "iban",
|
"fieldname": "iban",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"label": "IBAN"
|
"label": "IBAN",
|
||||||
|
"options": "IBAN"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "bank_account.branch_code",
|
"fetch_from": "bank_account.branch_code",
|
||||||
@@ -443,11 +444,12 @@
|
|||||||
"label": "Phone Number"
|
"label": "Phone Number"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"grid_page_length": 50,
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-12-27 21:29:10.361894",
|
"modified": "2025-08-29 11:52:48.555415",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Request",
|
"name": "Payment Request",
|
||||||
@@ -482,8 +484,9 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"row_format": "Dynamic",
|
||||||
"show_preview_popup": 1,
|
"show_preview_popup": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"states": []
|
"states": []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -814,7 +814,8 @@
|
|||||||
"depends_on": "eval:doc.salary_mode == 'Bank'",
|
"depends_on": "eval:doc.salary_mode == 'Bank'",
|
||||||
"fieldname": "iban",
|
"fieldname": "iban",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "IBAN"
|
"label": "IBAN",
|
||||||
|
"options": "IBAN"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-user",
|
"icon": "fa fa-user",
|
||||||
@@ -822,7 +823,7 @@
|
|||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"is_tree": 1,
|
"is_tree": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-07-04 08:29:34.347269",
|
"modified": "2025-08-29 11:52:12.819878",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Setup",
|
"module": "Setup",
|
||||||
"name": "Employee",
|
"name": "Employee",
|
||||||
@@ -864,6 +865,7 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"row_format": "Dynamic",
|
||||||
"search_fields": "employee_name",
|
"search_fields": "employee_name",
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
@@ -871,4 +873,4 @@
|
|||||||
"states": [],
|
"states": [],
|
||||||
"title_field": "employee_name",
|
"title_field": "employee_name",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user