accountant-ui/api/controller/accounts.py
2013-12-03 23:01:17 +01:00

122 lines
4.5 KiB
Python

"""
This file is part of Accountant.
Accountant is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Accountant. If not, see <http://www.gnu.org/licenses/>.
"""
from .. import api
from ..model import db, session_scope
from ..model.accounts import Account
from ..model.entries import Entry
from ..model.operations import Operation
from flask import json, request
from sqlalchemy import func, case, cast, extract, distinct
@api.route("/accounts", methods=["GET"])
def get_accounts():
"""
Returns accounts with their solds.
"""
with session_scope() as session:
query = session.query(
Account.id.label("id"),
Account.name.label("name"),
Account.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(Account.id).order_by(Account.id)
return json.dumps([{
"id": i.id,
"name": i.name,
"authorized_overdraft": i.authorized_overdraft,
"current": str(i.current),
"pointed": str(i.pointed),
"future": str(i.future)
} for i in query.all()])
@api.route("/accounts/<account_id>/<year>/<month>/")
def get_account_status(account_id, year, month):
with session_scope() as session:
query = session.query(
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.account_id == account_id
).filter(
func.date_trunc('month', Operation.operation_date) == "%s-%s-01" % (year, month)
).group_by(Operation.account_id)
if query.count() == 1:
result = query.one()
revenues = result.revenues
expenses = result.expenses
balance = result.balance
else:
revenues = 0.0
expenses = 0.0
balance = 0.0
return json.dumps({
"expenses": str(expenses),
"revenues": str(revenues),
"balance": str(balance)
})
@api.route("/accounts/<account_id>/months")
def get_months(account_id):
with session_scope() as session:
query = session.query(
distinct(func.lpad(cast(extract("year", Entry.operation_date), db.String), 4, '0')).label("year"),
func.lpad(cast(extract("month", Entry.operation_date), db.String), 2, '0').label("month")
).filter(Entry.account_id == account_id).order_by("year", "month")
return json.dumps([{
"year": i.year,
"month": i.month.rjust(2, '0')
} for i in query.all()])
@api.route("/accounts", methods=["PUT"])
def add_account():
with session_scope() as session:
account = Account(request.json['name'], request.json['authorized_overdraft'])
session.add(account)
return json.dumps("Account added.")
@api.route("/accounts/<account_id>", methods=["PUT"])
def update_account(account_id):
with session_scope() as session:
account = session.query(Account).filter(Account.id == account_id).first()
account.name = request.json['name']
account.authorized_overdraft = request.json['authorized_overdraft']
session.merge(account)
return json.dumps("Account #%s updated." % account_id)
@api.route("/accounts/<account_id>", methods=["DELETE"])
def delete_account(account_id):
with session_scope() as session:
account = session.query(Account).filter(Account.id == account_id).first()
session.delete(account)
return json.dumps("Account #%s deleted." % account_id)