人财事物信息化 - bank.py
这两个链接分别指向ERPNext系统中与银行及银行账户相关的代码文件,它们共同为系统提供了银行信息管理、账户操作以及数据验证等功能,确保了银行相关业务在系统中的准确和高效处理。
bank.py
文件总结- 功能概述:该文件定义了
Bank
类,用于管理银行信息,在加载和删除银行信息时,分别实现加载地址和联系人信息以及删除相关地址和联系人的功能。 - 代码结构:继承自
Document
类,包含类型提示部分,定义了bank_name
、bank_transaction_mapping
等属性。 - 核心方法
onload
方法:调用load_address_and_contact
函数,将银行的地址和联系人信息加载到__onload
属性中,方便在页面加载时展示相关信息。on_trash
方法:调用delete_contact_and_address
函数,在删除银行记录时,同时删除与之关联的地址和联系人信息,保证数据的一致性和完整性。
- 功能概述:该文件定义了
bank_account.py
文件总结- 功能概述:此文件定义的
BankAccount
类用于管理银行账户信息,涵盖自动命名、验证、设置默认账户等功能,并提供了获取和创建银行账户的方法。 - 代码结构:同样继承自
Document
类,在类型提示部分定义了account
、account_name
等多种属性,用于描述银行账户的详细信息。 - 核心方法
onload
方法:与Bank
类的onload
方法类似,加载银行账户的地址和联系人信息。autoname
方法:按照“账户名称 - 银行名称”的格式自动生成银行账户的名称,确保账户名称的规范性和唯一性。on_trash
方法:删除银行账户记录时,删除相关地址和联系人信息。validate
方法:调用多个验证方法,包括validate_company
、validate_iban
和validate_account
,分别验证公司信息、IBAN格式以及账户的唯一性;还会调用update_default_bank_account
方法,确保系统中默认银行账户的准确性。validate_account
方法:检查当前输入的账户是否已被其他银行账户使用,若已使用则抛出异常提示用户更换账户。validate_iban
方法:根据国际银行账户号码(IBAN)的验证算法,对输入的IBAN进行有效性验证,确保IBAN格式正确。update_default_bank_account
方法:当当前银行账户被设置为默认账户时,将同类型的其他银行账户的“默认”属性设置为0,保证同一类型下只有一个默认银行账户。make_bank_account
方法:创建一个新的银行账户文档对象,并设置其party_type
和party
属性,返回该新建的银行账户对象,方便在其他业务逻辑中创建银行账户。get_party_bank_account
方法:根据传入的party_type
(如客户、供应商等)和party
(具体的客户或供应商名称),从数据库中获取默认的银行账户名称,用于获取特定对象的默认银行账户。get_default_company_bank_account
方法:优先获取指定公司、party_type
和party
的默认银行账户;若未找到,则根据公司和“公司账户”、“默认账户”条件获取默认银行账户,用于获取公司的默认银行账户。get_bank_account_details
方法:根据传入的银行账户名称,从缓存中获取该银行账户的account
、bank
和bank_account_no
等详细信息,并以字典形式返回,方便获取银行账户的关键信息。 ### 1.bank.py
文件总结
- 功能概述:此文件定义的
1.1 整体功能概述
该文件定义了 Bank
类,用于管理 ERPNext 系统中的银行信息。它继承自 Document
类,包含了银行相关的属性以及验证和保存等操作的逻辑。
1.2 类属性
属性名 | 类型 | 描述 |
---|---|---|
bank_name |
DF.Data |
银行名称 |
swift_number |
DF.Data |
银行的 SWIFT 代码 |
iban |
DF.Data |
国际银行账户号码(IBAN) |
country |
DF.Link |
银行所在国家 |
aba_number |
DF.Data |
美国银行协会(ABA)号码 |
micr |
DF.Data |
磁性墨水字符识别(MICR)代码 |
1.3 关键方法
方法名 | 功能 | 业务逻辑 |
---|---|---|
validate |
在保存银行信息前进行验证 | 调用 validate_swift_number 方法验证 SWIFT 代码格式,若不符合要求则抛出错误;同时调用 validate_iban 方法验证 IBAN 号码格式。 |
validate_swift_number |
验证 SWIFT 代码格式 | 若设置了 SWIFT 代码,检查其长度是否为 8 或 11 位,若不符合则抛出错误提示。 |
validate_iban |
验证 IBAN 号码格式 | 若设置了 IBAN 号码,使用 frappe.utils.validate_iban 函数进行验证,若不合法则抛出错误提示。 |
on_update |
在更新银行信息后执行 | 调用 update_nsm_model 方法更新嵌套集模型。 |
on_trash |
在删除银行信息后执行 | 调用 update_nsm_model 方法更新嵌套集模型。 |
1.4 关键问题解答
- 问题 1:为什么要验证 SWIFT 代码和 IBAN 号码的格式?
- 答案:SWIFT 代码和 IBAN 号码是国际银行交易中重要的标识,确保其格式正确可以避免因格式错误导致的交易失败或数据错误。通过验证格式,可以提高数据的准确性和交易的成功率。
- 问题 2:
validate
方法在保存银行信息时的作用是什么?- 答案:
validate
方法在保存银行信息前对 SWIFT 代码和 IBAN 号码进行格式验证,若验证不通过则阻止保存并抛出错误提示,从而保证保存到系统中的银行信息是符合规范的。
- 答案:
- 问题 3:
on_update
和on_trash
方法中调用update_nsm_model
的目的是什么?- 答案:
update_nsm_model
用于更新嵌套集模型,当银行信息发生更新或删除操作时,调用该方法可以确保嵌套集模型的数据与实际的银行信息保持一致,以便后续的查询和操作能够正常进行。
- 答案:
2. bank_account.py
文件总结
2.1 整体功能概述
该文件定义了 BankAccount
类,用于管理 ERPNext 系统中的银行账户信息。它继承自 Document
类,包含了银行账户相关的属性以及验证、保存和关联等操作的逻辑。
2.2 类属性
属性名 | 类型 | 描述 |
---|---|---|
bank |
DF.Link |
关联的银行 |
bank_account_no |
DF.Data |
银行账户号码 |
account |
DF.Link |
关联的会计账户 |
is_default |
DF.Check |
是否为默认银行账户 |
company |
DF.Link |
关联的公司 |
iban |
DF.Data |
国际银行账户号码(IBAN) |
swift_number |
DF.Data |
银行的 SWIFT 代码 |
2.3 关键方法
方法名 | 功能 | 业务逻辑 |
---|---|---|
validate |
在保存银行账户信息前进行验证 | 调用 validate_duplicate_account 方法检查是否存在重复的银行账户;若设置了 IBAN 号码,调用 validate_iban 方法验证其格式;若设置了 SWIFT 代码,调用 validate_swift_number 方法验证其格式;同时调用 validate_company 方法确保公司关联正确。 |
validate_duplicate_account |
检查是否存在重复的银行账户 | 查询数据库,检查是否存在相同银行、相同账户号码且相同公司的银行账户记录,若存在则抛出错误提示。 |
validate_iban |
验证 IBAN 号码格式 | 若设置了 IBAN 号码,使用 frappe.utils.validate_iban 函数进行验证,若不合法则抛出错误提示。 |
validate_swift_number |
验证 SWIFT 代码格式 | 若设置了 SWIFT 代码,检查其长度是否为 8 或 11 位,若不符合则抛出错误提示。 |
validate_company |
验证公司关联 | 确保关联的公司与会计账户所属的公司一致,若不一致则抛出错误提示。 |
on_update |
在更新银行账户信息后执行 | 若设置为默认银行账户,更新其他同公司的银行账户为非默认。 |
on_trash |
在删除银行账户信息后执行 | 若删除的是默认银行账户,更新同公司的其他银行账户为默认(若有)。 |
2.4 关键问题解答
- 问题 1:为什么要检查是否存在重复的银行账户?
- 答案:避免系统中出现重复的银行账户记录,保证数据的唯一性和准确性。重复的记录可能会导致财务数据混乱,影响财务核算和业务操作的正常进行。
- 问题 2:
validate
方法中对 IBAN 和 SWIFT 代码的验证与bank.py
中的验证有什么关系?- 答案:两者的验证逻辑基本相同,都是为了确保 IBAN 和 SWIFT 代码的格式正确。在
bank.py
中是对银行信息的验证,而在bank_account.py
中是对银行账户信息的验证,目的都是为了保证数据在不同层面的准确性和合规性。
- 答案:两者的验证逻辑基本相同,都是为了确保 IBAN 和 SWIFT 代码的格式正确。在
- 问题 3:
on_update
和on_trash
方法中对默认银行账户的处理逻辑有什么作用?- 答案:在更新和删除银行账户信息时,对默认银行账户进行处理可以确保每个公司始终有且只有一个默认银行账户(如果存在银行账户的话)。这样可以方便在进行财务操作时,系统能够自动选择默认的银行账户,提高操作的便利性和准确性。
要在 bank_account.py
文件中实现新属性,你可以按照以下步骤进行操作。这里以添加一个名为 account_type
的新属性,用于表示银行账户类型(如储蓄账户、支票账户等)为例,详细介绍具体实现过程。
1. 定义新属性
在 BankAccount
类的类型提示部分添加新属性的定义,这样在代码编写时可以获得类型检查支持。
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
# 新增属性:账户类型
account_type: DF.Select[
"Savings Account",
"Checking Account",
"Credit Card Account",
"Loan Account"
]
2. 在文档元数据中添加新属性
在 bank_account.py
文件对应的文档元数据(通常是 bank_account.json
或类似文件)中添加新属性的定义,确保 ERPNext 系统能够识别和处理该属性。
{
"doctype": "DocType",
"name": "Bank Account",
"fields": [
{
"label": "Account Type",
"fieldname": "account_type",
"fieldtype": "Select",
"options": "Savings Account\nChecking Account\nCredit Card Account\nLoan Account",
"description": "The type of the bank account."
}
]
}
3. 在验证方法中处理新属性(可选)
如果新属性有特定的验证规则,你可以在 validate
方法或新增的验证方法中添加相应的验证逻辑。
def validate(self):
self.validate_duplicate_account()
if self.iban:
self.validate_iban()
if self.swift_number:
self.validate_swift_number()
self.validate_company()
# 新增对账户类型的验证
self.validate_account_type()
def validate_account_type(self):
if self.account_type not in ["Savings Account", "Checking Account", "Credit Card Account", "Loan Account"]:
frappe.throw(_("Invalid account type selected."))
4. 在其他方法中处理新属性(可选)
如果新属性会影响其他业务逻辑,你需要在相应的方法中进行处理。例如,在 on_update
或 on_trash
方法中。
def on_update(self):
if self.is_default:
# 更新其他同公司的银行账户为非默认
frappe.db.sql("""UPDATE `tabBank Account`
SET is_default = 0
WHERE company = %s AND name != %s""", (self.company, self.name))
# 可以在这里添加与账户类型相关的更新逻辑
if self.account_type == "Credit Card Account":
# 执行信用卡账户相关的更新操作
pass
def on_trash(self):
if self.is_default:
# 若删除的是默认银行账户,更新同公司的其他银行账户为默认(若有)
other_account = frappe.get_all("Bank Account", filters={"company": self.company, "name": ("!=", self.name)}, limit=1)
if other_account:
frappe.db.set_value("Bank Account", other_account[0].name, "is_default", 1)
# 可以在这里添加与账户类型相关的删除逻辑
if self.account_type == "Loan Account":
# 执行贷款账户相关的删除操作
pass
5. 在用户界面中显示新属性
确保在 Bank Account
文档的用户界面中显示新属性,这样用户可以输入和查看该属性的值。这通常需要在相应的表单模板文件(如 bank_account.html
或使用的前端框架模板)中添加新属性的输入字段。
<!-- 在银行账户表单中添加账户类型字段 -->
<div class="form-group">
<label for="account_type">Account Type</label>
<select id="account_type" name="account_type">
<option value="Savings Account">Savings Account</option>
<option value="Checking Account">Checking Account</option>
<option value="Credit Card Account">Credit Card Account</option>
<option value="Loan Account">Loan Account</option>
</select>
</div>
总结
通过以上步骤,你可以在 bank_account.py
文件中成功实现新属性。主要包括定义属性、在文档元数据中添加属性、在验证和业务逻辑方法中处理属性,以及在用户界面中显示属性。根据新属性的具体需求,你可以进一步调整和扩展这些步骤。
以下以在 ERPNext 的 bank_account.py
文件中增加支持中国本地化功能为例,为你添加一些函数方法,以满足中国本地化的业务需求,比如处理中国的银行账户编码规则、添加中国特色的银行信息等。以下是详细的代码示例及说明:
import frappe
from frappe.model.document import Document
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
class BankAccount(Document):
bank: DF.Link
bank_account_no: DF.Data
account: DF.Link
is_default: DF.Check
company: DF.Link
iban: DF.Data
swift_number: DF.Data
# 新增属性:中国地区银行联行号
china_bank_branch_number: DF.Data
# 新增属性:中国地区银行账户类型(如对公账户、个人账户)
china_account_type: DF.Select[
"对公账户",
"个人账户",
"其他"
]
class BankAccount(Document):
def validate(self):
self.validate_duplicate_account()
if self.iban:
self.validate_iban()
if self.swift_number:
self.validate_swift_number()
self.validate_company()
# 新增对中国本地化属性的验证
self.validate_china_bank_branch_number()
self.validate_china_account_type()
def validate_duplicate_account(self):
duplicate = frappe.db.exists(
"Bank Account",
{
"bank": self.bank,
"bank_account_no": self.bank_account_no,
"company": self.company,
"name": ("!=", self.name),
},
)
if duplicate:
frappe.throw(_("A bank account with the same details already exists."))
def validate_iban(self):
if not frappe.utils.validate_iban(self.iban):
frappe.throw(_("Invalid IBAN number."))
def validate_swift_number(self):
if len(self.swift_number) not in [8, 11]:
frappe.throw(_("Invalid SWIFT number. It should be 8 or 11 characters long."))
def validate_company(self):
account_company = frappe.db.get_value("Account", self.account, "company")
if account_company != self.company:
frappe.throw(_("The company of the account does not match the selected company."))
# 新增中国地区银行联行号验证方法
def validate_china_bank_branch_number(self):
if self.china_bank_branch_number:
# 简单示例:假设中国地区银行联行号为 12 位数字
if not self.china_bank_branch_number.isdigit() or len(self.china_bank_branch_number) != 12:
frappe.throw(_("Invalid China Bank Branch Number. It should be 12 digits."))
# 新增中国地区账户类型验证方法
def validate_china_account_type(self):
if self.china_account_type not in ["对公账户", "个人账户", "其他"]:
frappe.throw(_("Invalid China Account Type selected."))
# 新增获取中国地区银行开户行名称方法
def get_china_bank_deposit_branch_name(self):
# 这里简单模拟根据银行联行号查询开户行名称,实际应用中需要连接数据库或调用接口获取准确信息
branch_name = frappe.db.get_value("China Bank Branch Mapping", {"branch_number": self.china_bank_branch_number}, "branch_name")
if branch_name:
return branch_name
else:
return ""
def on_update(self):
if self.is_default:
# 更新其他同公司的银行账户为非默认
frappe.db.sql("""UPDATE `tabBank Account`
SET is_default = 0
WHERE company = %s AND name != %s""", (self.company, self.name))
# 可以在这里添加与中国本地化属性相关的更新逻辑
if self.china_account_type == "对公账户":
# 执行对公账户相关的更新操作
pass
def on_trash(self):
if self.is_default:
# 若删除的是默认银行账户,更新同公司的其他银行账户为默认(若有)
other_account = frappe.get_all("Bank Account", filters={"company": self.company, "name": ("!=", self.name)}, limit=1)
if other_account:
frappe.db.set_value("Bank Account", other_account[0].name, "is_default", 1)
# 可以在这里添加与中国本地化属性相关的删除逻辑
if self.china_account_type == "个人账户":
# 执行个人账户相关的删除操作
pass
上述代码在 bank_account.py
文件中做了以下几个方面的修改以支持中国本地化功能:
- 新增属性:添加了
china_bank_branch_number
(中国地区银行联行号)和china_account_type
(中国地区银行账户类型)两个属性,用于存储中国本地化的银行账户相关信息。 - 新增验证方法:增加了
validate_china_bank_branch_number
和validate_china_account_type
方法,分别用于验证中国地区银行联行号和账户类型的有效性。 - 新增业务方法:添加了
get_china_bank_deposit_branch_name
方法,用于根据银行联行号获取中国地区银行开户行名称(这里只是简单模拟,实际应用中需要更复杂的逻辑来获取准确信息)。 - 修改其他方法:在
validate
方法中调用了新增的验证方法,确保在保存银行账户信息时对中国本地化属性进行验证;在on_update
和on_trash
方法中预留了处理中国本地化属性相关逻辑的位置,可根据实际需求进一步扩展。
通过这些修改,可以在 ERPNext 的银行账户管理功能中增加对中国本地化业务的支持。你可以根据具体需求进一步完善和扩展这些功能。