From 3268f065d336eed8380ede27fcc3bcb12d21c3da Mon Sep 17 00:00:00 2001 From: ewandor Date: Tue, 18 Feb 2025 23:00:37 +0100 Subject: [PATCH] Adding filters et pagination to ledger --- api/app/ledger/resource.py | 27 +++++++++++++-------------- api/app/ledger/routes.py | 22 +++++++++++++++++++--- gui/app/src/pages/accounts/ledger.tsx | 5 ++--- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/api/app/ledger/resource.py b/api/app/ledger/resource.py index 724c002..cae1ae5 100644 --- a/api/app/ledger/resource.py +++ b/api/app/ledger/resource.py @@ -1,27 +1,26 @@ from sqlalchemy import and_, select, func from sqlalchemy.orm import aliased -from ledger.schema import TransactionLedgerRead from transaction.models import Split, Transaction - - class LedgerResource: @classmethod - def get_ledger(cls, session, account_id): + def get_ledger(cls, account_id, filters): split_account = aliased(Split) split_balance = aliased(Split) transaction_balance = aliased(Transaction) - balance_stmt = select(func.sum(split_balance.amount)).join(transaction_balance).where(and_(split_balance.account_id == split_account.account_id, transaction_balance.sequence <= Transaction.sequence)).scalar_subquery() + balance_stmt = select(func.sum(split_balance.amount)) \ + .join(transaction_balance) \ + .where(and_( + split_balance.account_id == split_account.account_id, + transaction_balance.sequence <= Transaction.sequence) + ).scalar_subquery() - stmt = (select( - Transaction, - split_account, - balance_stmt.label('balance') - ).join( - split_account, - and_(Transaction.id == split_account.transaction_id, split_account.account_id == account_id) - )) + stmt = select(Transaction,split_account,balance_stmt.label('balance')) \ + .join( + split_account, + and_(Transaction.id == split_account.transaction_id, split_account.account_id == account_id) + ) - return [TransactionLedgerRead(transaction=transaction, account_split=split, balance=balance) for transaction, split, balance in session.exec(stmt).all()] + return filters.filter(stmt) diff --git a/api/app/ledger/routes.py b/api/app/ledger/routes.py index 040ddb9..f4f6b65 100644 --- a/api/app/ledger/routes.py +++ b/api/app/ledger/routes.py @@ -1,15 +1,31 @@ from uuid import UUID from fastapi import APIRouter, Depends +from fastapi_filter import FilterDepends +from fastapi_filter.contrib.sqlalchemy import Filter +from fastapi_pagination import Page +from fastapi_pagination.ext.sqlalchemy import paginate +from fastapi_pagination.utils import disable_installed_extensions_check from db import SessionDep from ledger.resource import LedgerResource from ledger.schema import TransactionLedgerRead - +from transaction.models import Transaction from user.manager import get_current_user router = APIRouter() +class LedgerFilters(Filter): + + class Constants(Filter.Constants): + model = Transaction + search_model_fields = ["id", "sequence"] +disable_installed_extensions_check() + @router.get("/{account_id}") -def read_ledger(account_id: UUID, session: SessionDep, current_user=Depends(get_current_user)) -> list[TransactionLedgerRead]: - return LedgerResource.get_ledger(session, account_id) +def read_ledger(account_id: UUID, session: SessionDep, filters: LedgerFilters = FilterDepends(LedgerFilters), current_user=Depends(get_current_user)) -> Page[TransactionLedgerRead]: + return paginate( + session, + LedgerResource.get_ledger(account_id, filters), + transformer=lambda items: [TransactionLedgerRead(transaction=transaction, account_split=split, balance=balance) for transaction, split, balance in items], + ) diff --git a/gui/app/src/pages/accounts/ledger.tsx b/gui/app/src/pages/accounts/ledger.tsx index b17d17e..a39907b 100644 --- a/gui/app/src/pages/accounts/ledger.tsx +++ b/gui/app/src/pages/accounts/ledger.tsx @@ -17,9 +17,8 @@ import {useList, useOne} from "@refinedev/core"; export const AccountLedger: React.FC = () => { const { id } = useParams() - const { data, isLoading, isError } = useOne({ - resource: `ledgers`, - id: id + const { data, isLoading, isError } = useList({ + resource: `ledgers/${id}`, }); if (isLoading) { return
Loading