Fix account status queries.

This commit is contained in:
Alexis Lahouze 2015-07-15 18:15:38 +02:00
parent 6a2d796cdb
commit 53cdeabc90

View File

@ -14,14 +14,11 @@
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with Accountant. If not, see <http://www.gnu.org/licenses/>. along with Accountant. If not, see <http://www.gnu.org/licenses/>.
""" """
from datetime import date from sqlalchemy import func, case, literal_column
from sqlalchemy import func, case, cast
from sqlalchemy.orm import validates from sqlalchemy.orm import validates
from accountant import db from accountant import db
from .entries import Entry
from .operations import Operation from .operations import Operation
@ -40,82 +37,108 @@ class Account(db.Model):
cls.id.label("id"), cls.id.label("id"),
cls.name.label("name"), cls.name.label("name"),
cls.authorized_overdraft.label("authorized_overdraft"), 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(Operation.value).label("future"),
func.sum( func.sum(
case( case(
[(Operation.pointed, Operation.value,)], [(Operation.pointed, Operation.value)],
else_=0 else_=0
) )
).label("pointed"), ).label("pointed"),
func.sum( func.sum(
case( 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 else_=0
) )
).label("current"), ).label("current"),
).group_by( ).group_by(
cls.id Operation.account_id
).subquery() ).subquery()
query = session.query( if begin and end:
cls.id, balance_query = session.query(
cls.name, Operation.account_id,
cls.authorized_overdraft, func.sum(
func.coalesce(status_query.c.current, 0).label('current'), case(
func.coalesce(status_query.c.pointed, 0).label('pointed'), [(func.sign(Operation.value) == -1, Operation.value)],
func.coalesce(status_query.c.future, 0).label('future'), else_=0
func.coalesce(balance_query.c.expenses, 0).label('expenses'), )
func.coalesce(balance_query.c.revenues, 0).label('revenues'), ).label("expenses"),
func.coalesce(balance_query.c.balance, 0).label('balance'), func.sum(
).outerjoin( case(
status_query, status_query.c.id == cls.id [(func.sign(Operation.value) == 1, Operation.value)],
).outerjoin( else_=0
balance_query, balance_query.c.account_id == cls.id )
).filter( ).label("revenues"),
cls.id == account_id 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() return query.one()