121 lines
4.0 KiB
Python
121 lines
4.0 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.entries import Entry
|
|
from ..model.operations import Operation
|
|
from ..model.scheduled_operations import ScheduledOperation
|
|
from flask import json, request
|
|
from sqlalchemy import func, desc
|
|
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
|
|
from sqlalchemy.orm import sessionmaker, column_property, aliased
|
|
from sqlalchemy.sql import func, select, case
|
|
|
|
@api.route("/entries/<account_id>/<year>/<month>")
|
|
def get_entries(account_id, year, month):
|
|
"""
|
|
Return entries for an account, year, and month.
|
|
"""
|
|
session = db.session
|
|
|
|
base_query = session.query(
|
|
Operation,
|
|
case(whens={Operation.canceled: None}, else_=func.sum(Operation.value).over(partition_by="canceled", order_by="operation_date, value desc, label desc")).label("sold")
|
|
).filter(Operation.account_id == account_id).order_by(
|
|
desc(Operation.operation_date),
|
|
Operation.value,
|
|
Operation.label,
|
|
).subquery()
|
|
|
|
query = session.query(base_query).select_from(base_query).filter(func.date_trunc('month', base_query.c.operation_date) == "%s-%s-01" % (year, month))
|
|
|
|
return json.dumps([{
|
|
"id": i.id,
|
|
"pointed": i.pointed,
|
|
"operation_date": i.operation_date.strftime("%Y-%m-%d"),
|
|
"label": i.label,
|
|
"value": str(i.value),
|
|
"category": i.category,
|
|
"sold": str(i.sold) if not i.canceled else None,
|
|
"account_id": i.account_id,
|
|
"canceled": i.canceled,
|
|
"scheduled_operation_id": i.scheduled_operation_id
|
|
} for i in query.all()])
|
|
|
|
@api.route("/entries", methods=["PUT"])
|
|
def add_entry():
|
|
session = db.session
|
|
|
|
try:
|
|
entry = Entry(
|
|
operation_date = request.json['operation_date'],
|
|
pointed = request.json['pointed'],
|
|
label = request.json['label'],
|
|
value = request.json['value'],
|
|
category = request.json['category'],
|
|
account_id = request.json['account_id'],
|
|
scheduled_operation_id = request.json['scheduled_operation_id']
|
|
)
|
|
|
|
session.add(entry)
|
|
session.commit()
|
|
|
|
return json.dumps("Entry added.")
|
|
except:
|
|
session.rollback()
|
|
raise
|
|
|
|
@api.route("/entries/<entry_id>", methods=["PUT"])
|
|
def update_entry(entry_id):
|
|
session = db.session
|
|
|
|
try:
|
|
entry = session.query(Entry).filter(Entry.id == entry_id).first()
|
|
|
|
entry.id = entry_id
|
|
entry.operation_date = request.json['operation_date']
|
|
entry.pointed = request.json['pointed']
|
|
entry.label = request.json['label']
|
|
entry.value = request.json['value']
|
|
entry.category = request.json['category']
|
|
entry.account_id = request.json['account_id']
|
|
entry.scheduled_operation_id = request.json['scheduled_operation_id']
|
|
|
|
session.merge(entry)
|
|
session.commit()
|
|
|
|
return json.dumps("Entry #%s updated." % entry_id)
|
|
except:
|
|
session.rollback()
|
|
raise
|
|
|
|
@api.route("/entries/<entry_id>", methods=["DELETE"])
|
|
def delete_entry(entry_id):
|
|
session = db.session
|
|
|
|
try:
|
|
entry = session.query(Entry).filter(Entry.id == entry_id).first()
|
|
|
|
session.delete(entry)
|
|
session.commit()
|
|
|
|
return json.dumps("Entry #%s deleted." % entry_id)
|
|
except:
|
|
session.rollback()
|
|
raise
|
|
|