diff --git a/api/app/account/account_routes.py b/api/app/account/account_routes.py index 0334784..3dba587 100644 --- a/api/app/account/account_routes.py +++ b/api/app/account/account_routes.py @@ -12,6 +12,8 @@ from account.models import Account from account.resource import AccountResource from db import SessionDep +from transaction.models import TransactionRead +from transaction.resource import TransactionResource from user.manager import get_current_user @@ -55,6 +57,13 @@ def read_account(account_id: UUID, session: SessionDep, current_user=Depends(get raise HTTPException(status_code=404, detail="Account not found") return account +@router.get("/{account_id}/opening_state") +def read_account_opening_state(account_id: UUID, session: SessionDep, current_user=Depends(get_current_user)) -> TransactionRead: + transaction = TransactionResource.get_opening_transaction(session, account_id) + if not transaction: + raise HTTPException(status_code=404, detail="Account not found") + return transaction + @router.put("/{account_id}") def update_account(account_id: UUID, account: AccountUpdate, session: SessionDep, current_user=Depends(get_current_user)) -> AccountRead: db_account = AccountResource.get(session, account_id) diff --git a/api/app/transaction/models.py b/api/app/transaction/models.py index b7b9cc2..84981ed 100644 --- a/api/app/transaction/models.py +++ b/api/app/transaction/models.py @@ -60,7 +60,7 @@ class SplitBaseId(SplitBase): class SplitRead(SplitBaseId): account: AccountRead - payee: PayeeRead + payee: PayeeRead | None class TransactionRead(TransactionBaseId): splits: list[SplitRead] diff --git a/api/app/transaction/resource.py b/api/app/transaction/resource.py new file mode 100644 index 0000000..ea15e5f --- /dev/null +++ b/api/app/transaction/resource.py @@ -0,0 +1,53 @@ +from decimal import Decimal +from typing import Optional +from uuid import UUID, uuid4 + +from sqlalchemy.orm import aliased +from sqlmodel import Field, SQLModel, select, Relationship +from pydantic import Field as PydField + +from account.models import Account +from account.schemas import AccountRead +from transaction.models import Transaction, Split +from payee.models import Payee, PayeeRead + +class TransactionResource: + @classmethod + def create(cls, transaction, session): + transaction_db = Transaction.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 get_opening_transaction(cls, session, account_id): + split_account = aliased(Split) + split_equity = aliased(Split) + account_filter = aliased(Account) + return session.exec(select(Transaction) + .join(split_account, split_account.account_id == account_id) + .join(split_equity) + .join(account_filter, account_filter.id == split_equity.account_id and Account.path == "/Equity/")).first() + + @classmethod + def update(cls, session, transaction_db, transaction_data): + transaction_db.sqlmodel_update(Transaction.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()