143 lines
4.5 KiB
Python
143 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
|
|
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.
|
|
"""
|
|
session = db.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):
|
|
session = db.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):
|
|
session = db.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():
|
|
session = db.session
|
|
|
|
try:
|
|
account = Account(request.json['name'], request.json['authorized_overdraft'])
|
|
|
|
session.add(account)
|
|
session.commit()
|
|
|
|
return json.dumps("Account added.")
|
|
except:
|
|
session.rollback()
|
|
raise
|
|
|
|
|
|
@api.route("/accounts/<account_id>", methods=["PUT"])
|
|
def update_account(account_id):
|
|
session = db.session
|
|
|
|
try:
|
|
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)
|
|
session.commit()
|
|
|
|
return json.dumps("Account #%s updated." % account_id)
|
|
except:
|
|
session.rollback()
|
|
raise
|
|
|
|
@api.route("/accounts/<account_id>", methods=["DELETE"])
|
|
def delete_account(account_id):
|
|
session = db.session
|
|
|
|
try:
|
|
account = session.query(Account).filter(Account.id == account_id).first()
|
|
|
|
session.delete(account)
|
|
session.commit()
|
|
|
|
return json.dumps("Account #%s deleted." % account_id)
|
|
except:
|
|
session.rollback()
|
|
raise
|
|
|