diff --git a/accountant/models/accounts.py b/accountant/models/accounts.py index d7640d8..27d7647 100644 --- a/accountant/models/accounts.py +++ b/accountant/models/accounts.py @@ -85,6 +85,45 @@ class Account(db.Model): return query.one() + def category_incomes(self, begin=None, end=None): + """Return a query for categories with expenses, revenues and income for + this account and an optional specific time period.""" + + query = db.session.query( + Operation.category.label('category'), + db.func.coalesce( + db.func.sum( + Operation.value + ).filter( + db.func.sign(Operation.value) == -1 + ), + 0 + ).label("expenses"), + db.func.coalesce( + db.func.sum( + Operation.value + ).filter( + db.func.sign(Operation.value) == 1 + ), + 0 + ).label("revenues"), + db.func.sum(Operation.value).label("income") + ).filter( + Operation.account_id == self.id + ).order_by( + Operation.category + ).group_by( + Operation.category + ) + + if begin: + query = query.filter(Operation.operation_date >= str(begin)) + + if end: + query = query.filter(Operation.operation_date <= str(end)) + + return query + @db.validates('authorized_overdraft') def validate_authorized_overdraft(self, key, authorized_overdraft): """Validator for authorized_overdraft : must be negative.""" diff --git a/accountant/models/operations.py b/accountant/models/operations.py index 4a2d7ec..ae8ff06 100644 --- a/accountant/models/operations.py +++ b/accountant/models/operations.py @@ -133,50 +133,6 @@ class Operation(db.Model): return query - @classmethod - def query_category_incomes(cls, account, begin=None, end=None): - """Return a query for categories with expenses, revenues and income for - a specific account and a specific time period.""" - if isinstance(account, (int, str)): - account_id = account - else: - account_id = account.id - - query = db.session.query( - cls.category.label('category'), - db.func.coalesce( - db.func.sum( - cls.value - ).filter( - db.func.sign(cls.value) == -1 - ), - 0 - ).label("expenses"), - db.func.coalesce( - db.func.sum( - cls.value - ).filter( - db.func.sign(cls.value) == 1 - ), - 0 - ).label("revenues"), - db.func.sum(cls.value).label("income") - ).filter( - cls.account_id == account_id - ).order_by( - cls.category - ).group_by( - cls.category - ) - - if begin: - query = query.filter(cls.operation_date >= str(begin)) - - if end: - query = query.filter(cls.operation_date <= str(end)) - - return query - @classmethod def query_daily_balances(cls, account, begin=None, end=None): """Get expenses, revenues, income and balance per day for a specific diff --git a/accountant/views/accounts.py b/accountant/views/accounts.py index 5714afb..f769c7d 100644 --- a/accountant/views/accounts.py +++ b/accountant/views/accounts.py @@ -328,8 +328,13 @@ class CategoryResource(Resource): data = range_parser.parse_args() # FIXME Alexis Lahouze 2017-05-23 check data. + account = Account.query().get(account_id) + + if not account: + ns.abort(404, 'Account with id %d not found.' % account_id) + return list(result_as_dicts( - Operation.query_category_incomes(account_id, **data) + account.category_incomes(**data) )), 200