130 lines
3.7 KiB
Python
130 lines
3.7 KiB
Python
from decimal import Decimal
|
|
from typing import Optional
|
|
from uuid import UUID, uuid4
|
|
|
|
from sqlmodel import Field, SQLModel, select, Relationship
|
|
from pydantic import Field as PydField
|
|
|
|
from account.models import Account
|
|
from account.schemas import AccountRead
|
|
from payee.models import Payee, PayeeRead
|
|
|
|
|
|
class TransactionBase(SQLModel):
|
|
pass
|
|
|
|
class TransactionBaseId(TransactionBase):
|
|
id: UUID | None = Field(default_factory=uuid4, primary_key=True)
|
|
|
|
class Transaction(TransactionBaseId, table=True):
|
|
splits: list["Split"] = Relationship(back_populates="transaction")
|
|
|
|
@classmethod
|
|
def create(cls, transaction, session):
|
|
transaction_db = cls.model_validate(transaction)
|
|
session.add(transaction_db)
|
|
session.commit()
|
|
session.refresh(transaction_db)
|
|
|
|
return transaction_db
|
|
|
|
@classmethod
|
|
def list(cls):
|
|
return select(Transaction).join(Split).join(Account)
|
|
|
|
@classmethod
|
|
def get(cls, session, transaction_id):
|
|
return session.get(Transaction, transaction_id)
|
|
|
|
@classmethod
|
|
def update(cls, session, transaction_db, transaction_data):
|
|
transaction_db.sqlmodel_update(cls.model_validate(transaction_data))
|
|
session.add(transaction_db)
|
|
session.commit()
|
|
session.refresh(transaction_db)
|
|
return transaction_db
|
|
|
|
@classmethod
|
|
def delete(cls, session, transaction):
|
|
session.delete(transaction)
|
|
session.commit()
|
|
|
|
class SplitBase(SQLModel):
|
|
account_id: UUID = Field(foreign_key="account.id")
|
|
payee_id: Optional[UUID] = Field(foreign_key="payee.id")
|
|
amount: Decimal = Field(decimal_places=2)
|
|
|
|
class SplitBaseId(SplitBase):
|
|
transaction_id: UUID = Field(primary_key=True, foreign_key="transaction.id")
|
|
id: int = Field(primary_key=True)
|
|
|
|
class SplitRead(SplitBaseId):
|
|
account: AccountRead
|
|
payee: PayeeRead | None
|
|
|
|
class TransactionRead(TransactionBaseId):
|
|
splits: list[SplitRead]
|
|
|
|
class SplitWrite(SplitBase):
|
|
account_id: UUID = PydField(json_schema_extra={
|
|
"foreign_key": {
|
|
"reference": {
|
|
"resource": "accounts",
|
|
"schema": "AccountRead",
|
|
"label": "name"
|
|
}
|
|
}
|
|
})
|
|
payee_id: UUID | None = PydField(json_schema_extra={
|
|
"foreign_key": {
|
|
"reference": {
|
|
"resource": "payees",
|
|
"schema": "PayeeRead",
|
|
"label": "name"
|
|
}
|
|
}
|
|
})
|
|
amount: str = PydField(json_schema_extra={"format": "price-bgdc"})
|
|
|
|
class TransactionWrite(TransactionBase):
|
|
splits: list[SplitWrite] = PydField(json_schema_extra={"minItems": 1})
|
|
|
|
class TransactionCreate(TransactionWrite):
|
|
pass
|
|
|
|
class TransactionUpdate(TransactionWrite):
|
|
pass
|
|
|
|
class Split(SplitBaseId, table=True):
|
|
transaction: Transaction = Relationship(back_populates="splits")
|
|
account: Account | None = Relationship(back_populates="transaction_splits")
|
|
payee: Payee | None = Relationship()
|
|
|
|
@classmethod
|
|
def create(cls, transaction_split, session):
|
|
transaction_split_db = cls.model_validate(transaction_split)
|
|
session.add(transaction_split_db)
|
|
session.commit()
|
|
session.refresh(transaction_split_db)
|
|
|
|
return transaction_split_db
|
|
|
|
@classmethod
|
|
def update(cls, session, transaction_db, transaction_data):
|
|
transaction_db.sqlmodel_update(transaction_data)
|
|
session.add(transaction_db)
|
|
session.commit()
|
|
session.refresh(transaction_db)
|
|
return transaction_db
|
|
|
|
@classmethod
|
|
def delete(cls, session, transaction):
|
|
session.delete(transaction)
|
|
session.commit()
|
|
|
|
|
|
class SplitCreate(SplitWrite):
|
|
pass
|
|
|
|
class SplitUpdate(SplitWrite):
|
|
pass |