Rewrote operations with cumulated balance.
This commit is contained in:
parent
69d5f57b90
commit
d2c08c2fb3
@ -95,41 +95,59 @@ class Operation(db.Model):
|
|||||||
self.canceled = canceled
|
self.canceled = canceled
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def query(cls, begin=None, end=None):
|
def query(cls):
|
||||||
"""Return query for this class."""
|
"""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(
|
query = db.session.query(
|
||||||
cls.id,
|
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,
|
cls.operation_date,
|
||||||
cls.label,
|
db.desc(cls.value),
|
||||||
cls.value,
|
db.desc(cls.label),
|
||||||
base_query.c.sold,
|
cls.id
|
||||||
cls.category,
|
]
|
||||||
cls.scheduled_operation_id,
|
).label("balance")
|
||||||
cls.account_id,
|
).filter(
|
||||||
cls.pointed,
|
cls.account_id == account_id
|
||||||
cls.confirmed,
|
|
||||||
cls.canceled
|
|
||||||
).join(
|
|
||||||
base_query, base_query.c.id == cls.id
|
|
||||||
).order_by(
|
|
||||||
db.desc(cls.operation_date),
|
|
||||||
cls.value,
|
|
||||||
cls.label,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if begin:
|
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:
|
if end:
|
||||||
query = query.filter(cls.operation_date <= str(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
|
return query
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -7,7 +7,7 @@ import dateutil.parser
|
|||||||
from flask_jwt_extended import jwt_required
|
from flask_jwt_extended import jwt_required
|
||||||
from flask_restplus import Namespace, Resource, fields
|
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.accounts import Account
|
||||||
from ..models.operations import Operation
|
from ..models.operations import Operation
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ operation_model = ns.model('Operation', {
|
|||||||
default=None,
|
default=None,
|
||||||
readonly=True,
|
readonly=True,
|
||||||
description='Id of the operation'),
|
description='Id of the operation'),
|
||||||
'operation_date': fields.DateTime(
|
'operation_date': fields.Date(
|
||||||
dt_format='iso8601',
|
dt_format='iso8601',
|
||||||
required=True,
|
required=True,
|
||||||
description='Date of the operation'),
|
description='Date of the operation'),
|
||||||
@ -52,11 +52,11 @@ operation_model = ns.model('Operation', {
|
|||||||
description='Canceled status of the operation (for a scheduled one)')
|
description='Canceled status of the operation (for a scheduled one)')
|
||||||
})
|
})
|
||||||
|
|
||||||
operation_with_sold_model = ns.clone(
|
operation_with_balance_model = ns.clone(
|
||||||
'OperationWithSold', operation_model, {
|
'OperationWithBalance', operation_model, {
|
||||||
'sold': fields.Float(
|
'balance': fields.Float(
|
||||||
readonly=True,
|
readonly=True,
|
||||||
description='Cumulated sold'
|
description='Cumulated balance'
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -99,21 +99,22 @@ account_range_parser.add_argument(
|
|||||||
class OperationListResource(Resource):
|
class OperationListResource(Resource):
|
||||||
"""Resource to handle operation lists."""
|
"""Resource to handle operation lists."""
|
||||||
|
|
||||||
@ns.response(200, 'OK', [operation_with_sold_model])
|
@ns.response(200, 'OK', [operation_with_balance_model])
|
||||||
@ns.expect(parser=account_range_parser)
|
@ns.expect(account_range_parser)
|
||||||
@ns.marshal_list_with(operation_with_sold_model)
|
@ns.marshal_list_with(operation_with_balance_model)
|
||||||
@jwt_required
|
#@jwt_required
|
||||||
def get(self):
|
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()
|
data = account_range_parser.parse_args()
|
||||||
|
|
||||||
return Operation.query(
|
account_id = data['account_id']
|
||||||
begin=data['begin'],
|
begin = data['begin']
|
||||||
end = data['end']
|
end = data['end']
|
||||||
).filter(
|
|
||||||
Operation.account_id == data['account_id']
|
return list(result_as_dicts(
|
||||||
).all(), 200
|
Operation.get_with_balance(account_id, begin=begin, end=end)
|
||||||
|
)), 200
|
||||||
|
|
||||||
@ns.response(201, 'Operation created', operation_model)
|
@ns.response(201, 'Operation created', operation_model)
|
||||||
@ns.response(404, 'Account not found')
|
@ns.response(404, 'Account not found')
|
||||||
|
Loading…
Reference in New Issue
Block a user