From 53cdeabc900c4aa775764924fe8d1fdb6cd2b586 Mon Sep 17 00:00:00 2001 From: Alexis Lahouze Date: Wed, 15 Jul 2015 18:15:38 +0200 Subject: [PATCH] Fix account status queries. --- accountant/api/models/accounts.py | 155 +++++++++++++++++------------- 1 file changed, 89 insertions(+), 66 deletions(-) diff --git a/accountant/api/models/accounts.py b/accountant/api/models/accounts.py index 19c51d8..ae5806c 100644 --- a/accountant/api/models/accounts.py +++ b/accountant/api/models/accounts.py @@ -14,14 +14,11 @@ You should have received a copy of the GNU Affero General Public License along with Accountant. If not, see . """ -from datetime import date - -from sqlalchemy import func, case, cast +from sqlalchemy import func, case, literal_column from sqlalchemy.orm import validates from accountant import db -from .entries import Entry from .operations import Operation @@ -40,82 +37,108 @@ class Account(db.Model): cls.id.label("id"), cls.name.label("name"), cls.authorized_overdraft.label("authorized_overdraft"), - func.sum(Entry.value).label("future"), - func.sum(case([(Entry.pointed, Entry.value,)], - else_=cast(0, db.Numeric(15, 2)))).label("pointed"), - func.sum(case([(Entry.operation_date < func.now(), Entry.value,)], - else_=cast(0, db.Numeric(15, 2)))).label("current") - ).outerjoin(Entry).group_by(cls.id).order_by(cls.id) - - return query - - @classmethod - def get(cls, session, account, begin=date.today(), end=None): - if isinstance(account, int) or isinstance(account, str): - account_id = account - else: - account_id = account.id - - end = end if end else begin - - balance_query = session.query( - Operation.account_id, - func.sum( - case( - [(func.sign(Operation.value) == -1, Operation.value)], - else_=0 - ) - ).label("expenses"), - func.sum( - case( - [(func.sign(Operation.value) == 1, Operation.value)], - else_=0 - ) - ).label("revenues"), - func.sum(Operation.value).label("balance") - ).filter( - Operation.operation_date >= str(begin), - Operation.operation_date <= str(end) - ).group_by( - Operation.account_id - ).subquery() - - status_query = session.query( - cls.id, func.sum(Operation.value).label("future"), func.sum( case( - [(Operation.pointed, Operation.value,)], + [(Operation.pointed, Operation.value)], else_=0 ) ).label("pointed"), func.sum( case( - [(Operation.operation_date <= str(end), Operation.value,)], + [(Operation.operation_date <= func.current_date(), + Operation.value)], + else_=0 + ) + ).label("current") + ).outerjoin(Operation).group_by(cls.id).order_by(cls.id) + + return query + + @classmethod + def get(cls, session, account, begin=None, end=None): + if isinstance(account, int) or isinstance(account, str): + account_id = account + else: + account_id = account.id + + status_query = session.query( + Operation.account_id, + func.sum(Operation.value).label("future"), + func.sum( + case( + [(Operation.pointed, + Operation.value)], + else_=0 + ) + ).label("pointed"), + func.sum( + case( + [(Operation.operation_date <= func.current_date(), + Operation.value)], else_=0 ) ).label("current"), ).group_by( - cls.id + Operation.account_id ).subquery() - query = session.query( - cls.id, - cls.name, - cls.authorized_overdraft, - func.coalesce(status_query.c.current, 0).label('current'), - func.coalesce(status_query.c.pointed, 0).label('pointed'), - func.coalesce(status_query.c.future, 0).label('future'), - func.coalesce(balance_query.c.expenses, 0).label('expenses'), - func.coalesce(balance_query.c.revenues, 0).label('revenues'), - func.coalesce(balance_query.c.balance, 0).label('balance'), - ).outerjoin( - status_query, status_query.c.id == cls.id - ).outerjoin( - balance_query, balance_query.c.account_id == cls.id - ).filter( - cls.id == account_id - ) + if begin and end: + balance_query = session.query( + Operation.account_id, + func.sum( + case( + [(func.sign(Operation.value) == -1, Operation.value)], + else_=0 + ) + ).label("expenses"), + func.sum( + case( + [(func.sign(Operation.value) == 1, Operation.value)], + else_=0 + ) + ).label("revenues"), + func.sum(Operation.value).label("balance") + ).filter( + Operation.operation_date >= str(begin), + Operation.operation_date <= str(end) + ).group_by( + Operation.account_id + ).subquery() + + query = session.query( + cls.id, + cls.name, + cls.authorized_overdraft, + func.coalesce(status_query.c.current, 0).label('current'), + func.coalesce(status_query.c.pointed, 0).label('pointed'), + func.coalesce(status_query.c.future, 0).label('future'), + func.coalesce(balance_query.c.expenses, 0).label('expenses'), + func.coalesce(balance_query.c.revenues, 0).label('revenues'), + func.coalesce(balance_query.c.balance, 0).label('balance'), + ).outerjoin( + status_query, status_query.c.account_id == cls.id + ).outerjoin( + balance_query, balance_query.c.account_id == cls.id + ).filter( + cls.id == account_id + ) + else: + query = session.query( + cls.id, + cls.name, + cls.authorized_overdraft, + func.coalesce(status_query.c.current, 0).label('current'), + func.coalesce(status_query.c.pointed, 0).label('pointed'), + func.coalesce(status_query.c.future, 0).label('future'), + literal_column("0").label('expenses'), + literal_column("0").label('revenues'), + literal_column("0").label('balance'), + ).outerjoin( + status_query, status_query.c.account_id == cls.id + ).filter( + cls.id == account_id + ) return query.one()