Rewrote operations with cumulated balance.

This commit is contained in:
Alexis Lahouze 2017-05-25 22:07:56 +02:00
parent 69d5f57b90
commit d2c08c2fb3
2 changed files with 61 additions and 42 deletions

View File

@ -95,41 +95,59 @@ class Operation(db.Model):
self.canceled = canceled
@classmethod
def query(cls, begin=None, end=None):
def query(cls):
"""Return query for this class."""
# We have to use a join because the sold is not computed from the
# begining.
base_query = db.session.query(
cls.id,
cls.sold
).subquery()
query = db.session.query(
cls.id,
cls.operation_date,
cls.label,
cls.value,
base_query.c.sold,
cls.category,
cls.scheduled_operation_id,
cls.account_id,
cls.pointed,
cls.confirmed,
cls.canceled
).join(
base_query, base_query.c.id == cls.id
).order_by(
db.desc(cls.operation_date),
cls.value,
cls.label,
cls
)
return query
@classmethod
def get_with_balance(cls, account_id, begin=None, end=None):
"""Get operations with cumulated balance for a speciific account,
optionally for a specific time period."""
query = db.session.query(
*cls.__table__.columns.keys(),
db.func.sum(
cls.value
).filter(
db.not_(cls.canceled)
).over(
partition_by=[cls.account_id],
order_by=[
cls.operation_date,
db.desc(cls.value),
db.desc(cls.label),
cls.id
]
).label("balance")
).filter(
cls.account_id == account_id
)
if begin:
query = query.filter(cls.operation_date >= str(begin))
base_query = query.subquery()
query = db.session.query(
base_query
).filter(
cls.operation_date >= str(begin)
).join(
cls, base_query.c.id == cls.id
)
if end:
query = query.filter(cls.operation_date <= str(end))
query = query.order_by(
cls.operation_date,
db.desc(cls.value),
db.desc(cls.label),
cls.id
)
return query
@classmethod

View File

@ -7,7 +7,7 @@ import dateutil.parser
from flask_jwt_extended import jwt_required
from flask_restplus import Namespace, Resource, fields
from ..models import db
from ..models import db, result_as_dicts
from ..models.accounts import Account
from ..models.operations import Operation
@ -21,7 +21,7 @@ operation_model = ns.model('Operation', {
default=None,
readonly=True,
description='Id of the operation'),
'operation_date': fields.DateTime(
'operation_date': fields.Date(
dt_format='iso8601',
required=True,
description='Date of the operation'),
@ -52,11 +52,11 @@ operation_model = ns.model('Operation', {
description='Canceled status of the operation (for a scheduled one)')
})
operation_with_sold_model = ns.clone(
'OperationWithSold', operation_model, {
'sold': fields.Float(
operation_with_balance_model = ns.clone(
'OperationWithBalance', operation_model, {
'balance': fields.Float(
readonly=True,
description='Cumulated sold'
description='Cumulated balance'
),
}
)
@ -99,21 +99,22 @@ account_range_parser.add_argument(
class OperationListResource(Resource):
"""Resource to handle operation lists."""
@ns.response(200, 'OK', [operation_with_sold_model])
@ns.expect(parser=account_range_parser)
@ns.marshal_list_with(operation_with_sold_model)
@jwt_required
@ns.response(200, 'OK', [operation_with_balance_model])
@ns.expect(account_range_parser)
@ns.marshal_list_with(operation_with_balance_model)
#@jwt_required
def get(self):
"""Get operations with solds for a specific account."""
"""Get operations with cumulated balance for a specific account."""
data = account_range_parser.parse_args()
return Operation.query(
begin=data['begin'],
end=data['end']
).filter(
Operation.account_id == data['account_id']
).all(), 200
account_id = data['account_id']
begin = data['begin']
end = data['end']
return list(result_as_dicts(
Operation.get_with_balance(account_id, begin=begin, end=end)
)), 200
@ns.response(201, 'Operation created', operation_model)
@ns.response(404, 'Account not found')