Adding filters et pagination to ledger
This commit is contained in:
@@ -1,27 +1,26 @@
|
|||||||
from sqlalchemy import and_, select, func
|
from sqlalchemy import and_, select, func
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
from ledger.schema import TransactionLedgerRead
|
|
||||||
from transaction.models import Split, Transaction
|
from transaction.models import Split, Transaction
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LedgerResource:
|
class LedgerResource:
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_ledger(cls, session, account_id):
|
def get_ledger(cls, account_id, filters):
|
||||||
split_account = aliased(Split)
|
split_account = aliased(Split)
|
||||||
split_balance = aliased(Split)
|
split_balance = aliased(Split)
|
||||||
transaction_balance = aliased(Transaction)
|
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(
|
stmt = select(Transaction,split_account,balance_stmt.label('balance')) \
|
||||||
Transaction,
|
.join(
|
||||||
split_account,
|
split_account,
|
||||||
balance_stmt.label('balance')
|
and_(Transaction.id == split_account.transaction_id, split_account.account_id == account_id)
|
||||||
).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)
|
||||||
|
|||||||
@@ -1,15 +1,31 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
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 db import SessionDep
|
||||||
from ledger.resource import LedgerResource
|
from ledger.resource import LedgerResource
|
||||||
from ledger.schema import TransactionLedgerRead
|
from ledger.schema import TransactionLedgerRead
|
||||||
|
from transaction.models import Transaction
|
||||||
from user.manager import get_current_user
|
from user.manager import get_current_user
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
class LedgerFilters(Filter):
|
||||||
|
|
||||||
|
class Constants(Filter.Constants):
|
||||||
|
model = Transaction
|
||||||
|
search_model_fields = ["id", "sequence"]
|
||||||
|
disable_installed_extensions_check()
|
||||||
|
|
||||||
@router.get("/{account_id}")
|
@router.get("/{account_id}")
|
||||||
def read_ledger(account_id: UUID, session: SessionDep, current_user=Depends(get_current_user)) -> list[TransactionLedgerRead]:
|
def read_ledger(account_id: UUID, session: SessionDep, filters: LedgerFilters = FilterDepends(LedgerFilters), current_user=Depends(get_current_user)) -> Page[TransactionLedgerRead]:
|
||||||
return LedgerResource.get_ledger(session, account_id)
|
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],
|
||||||
|
)
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ import {useList, useOne} from "@refinedev/core";
|
|||||||
export const AccountLedger: React.FC = () => {
|
export const AccountLedger: React.FC = () => {
|
||||||
const { id } = useParams()
|
const { id } = useParams()
|
||||||
|
|
||||||
const { data, isLoading, isError } = useOne({
|
const { data, isLoading, isError } = useList({
|
||||||
resource: `ledgers`,
|
resource: `ledgers/${id}`,
|
||||||
id: id
|
|
||||||
});
|
});
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <div>Loading</div>
|
return <div>Loading</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user