75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
from enum import StrEnum
|
|
from typing import Annotated, Literal
|
|
|
|
from annotated_types import MinLen
|
|
from pydantic import BaseModel, Field
|
|
from pydantic_extra_types.currency_code import Currency
|
|
from ulid import ULID
|
|
|
|
from .ref import AccountRef
|
|
|
|
|
|
class AccountType(StrEnum):
|
|
"""资金性质"""
|
|
|
|
ASSET = "ASSET"
|
|
LIABILITY = "LIABILITY"
|
|
EQUITY = "EQUITY"
|
|
|
|
|
|
class BaseAccount(BaseModel):
|
|
"""基础账户模型"""
|
|
|
|
id: ULID = Field(default_factory=ULID)
|
|
name: Annotated[str, "用户自定义名称", MinLen(1)]
|
|
account_type: AccountType
|
|
primary_currency: Annotated[Currency | None, "主币种(可选)", Field(default=None)]
|
|
supported_currencies: Annotated[
|
|
list[Currency] | None, "支持的币种列表(None=全币种)", Field(default=None)
|
|
]
|
|
is_active: Annotated[bool, "是否启用", Field(default=True)]
|
|
remark: Annotated[str | None, "备注", Field(default=None)]
|
|
created_at: Annotated[datetime, "创建时间", Field(default_factory=lambda: datetime.now(UTC))]
|
|
updated_at: Annotated[datetime, "更新时间", Field(default_factory=lambda: datetime.now(UTC))]
|
|
deleted_at: Annotated[datetime | None, "软删除时间(None=未删除)", Field(default=None)]
|
|
|
|
|
|
class BankAccount(BaseAccount):
|
|
"""银行账户"""
|
|
|
|
account_type: Literal[AccountType.ASSET, AccountType.LIABILITY] = AccountType.ASSET
|
|
issuer_name: Annotated[str, "银行名称", MinLen(1)]
|
|
account_number: Annotated[str | None, "完整账户号(敏感信息)", Field(default=None)]
|
|
account_suffix: Annotated[
|
|
str | None, "账户号末尾部分,用于识别", MinLen(1), Field(default=None)
|
|
]
|
|
sub_accounts: Annotated[list[AccountRef], "子账户引用", Field(default_factory=list)]
|
|
|
|
|
|
class EWalletAccount(BaseAccount):
|
|
"""电子钱包账户"""
|
|
|
|
account_type: Literal[AccountType.ASSET] = AccountType.ASSET
|
|
platform: Annotated[
|
|
str,
|
|
"平台名称: Alipay/WeChat/PayMe/AlipayHK/MPay/Octopus/Tap&Go/AlipayMO",
|
|
MinLen(1),
|
|
]
|
|
account_id: Annotated[str | None, "平台账户ID", Field(default=None)]
|
|
|
|
|
|
class CashAccount(BaseAccount):
|
|
"""现金账户"""
|
|
|
|
account_type: Literal[AccountType.ASSET] = AccountType.ASSET
|
|
location: Annotated[str | None, "存放位置描述", Field(default=None)]
|
|
|
|
|
|
type Account = Annotated[
|
|
BankAccount | EWalletAccount | CashAccount,
|
|
Field(discriminator="account_type"),
|
|
]
|