from datetime import date from decimal import Decimal from typing import Optional from uuid import UUID, uuid4 from sqlmodel import Field, SQLModel from pydantic import Field as PydField, BaseModel from pydantic.json_schema import SkipJsonSchema from account.enums import Asset, Liability, CategoryFamily from core.types import MonetaryAmount class AccountBase(SQLModel): name: str = Field(index=True) parent_account_id: Optional[UUID] = Field(default=None, foreign_key="account.id") class AccountBaseId(AccountBase): id: UUID | None = Field(default_factory=uuid4, primary_key=True) family: str = Field(index=True) type: str = Field(index=True) path: str = Field(index=True) class AccountRead(AccountBaseId): pass class BaseAccountWrite(AccountBase): path: SkipJsonSchema[str] = Field(default="") family: SkipJsonSchema[str] = Field(default="") class AccountWrite(BaseAccountWrite): type: Asset | Liability = Field() parent_account_id: UUID | None = PydField(default=None, json_schema_extra={ "foreign_key": { "reference": { "resource": "accounts", "schema": "AccountRead", "label": "name" } } }) class AccountCreate(AccountWrite): opening_date: date = Field() opening_balance: MonetaryAmount = Field() class AccountUpdate(AccountWrite): pass class CategoryRead(AccountBaseId): pass class CategoryWrite(BaseAccountWrite): type: CategoryFamily = Field() parent_account_id: UUID | None = PydField(default=None, json_schema_extra={ "foreign_key": { "reference": { "resource": "categories", "schema": "CategoryRead", "label": "name" } } }) class CategoryCreate(CategoryWrite): opening_date: SkipJsonSchema[date] = Field(default=date(1970, 1, 1)) opening_balance: SkipJsonSchema[Decimal] = Field(default=0) class CategoryUpdate(CategoryWrite): pass class OpeningTransaction(BaseModel): opening_date: date = Field() opening_balance: MonetaryAmount = Field(default=0) class OpeningTransactionUpdate(OpeningTransaction): pass