Move queries in models.
This commit is contained in:
parent
e1b5d8be43
commit
c411ce5328
@ -14,8 +14,12 @@
|
||||
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 sqlalchemy import func, case, cast
|
||||
|
||||
from accountant import db
|
||||
|
||||
from .entries import Entry
|
||||
|
||||
|
||||
class Account(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
@ -25,3 +29,18 @@ class Account(db.Model):
|
||||
def __init__(self, name, authorized_overdraft):
|
||||
self.name = name
|
||||
self.authorized_overdraft = authorized_overdraft
|
||||
|
||||
@classmethod
|
||||
def get_accounts(cls, session):
|
||||
query = session.query(
|
||||
cls.id.label("id"),
|
||||
cls.name.label("name"),
|
||||
cls.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(cls.id).order_by(cls.id)
|
||||
|
||||
return query
|
||||
|
@ -14,10 +14,9 @@
|
||||
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 accountant import db
|
||||
|
||||
from .accounts import Account
|
||||
from .scheduled_operations import ScheduledOperation
|
||||
from sqlalchemy import distinct, func, cast, extract
|
||||
from accountant import db
|
||||
|
||||
|
||||
class Entry(db.Model):
|
||||
@ -30,9 +29,9 @@ class Entry(db.Model):
|
||||
scheduled_operation_id = db.Column(db.Integer,
|
||||
db.ForeignKey('scheduled_operation.id'))
|
||||
|
||||
account = db.relationship(Account, backref=db.backref('entry',
|
||||
account = db.relationship("Account", backref=db.backref('entry',
|
||||
lazy="dynamic"))
|
||||
scheduled_operation = db.relationship(ScheduledOperation,
|
||||
scheduled_operation = db.relationship("ScheduledOperation",
|
||||
backref=db.backref('entry',
|
||||
lazy="dynamic"))
|
||||
|
||||
@ -47,3 +46,19 @@ class Entry(db.Model):
|
||||
self.account_id = account_id
|
||||
self.category = category
|
||||
self.scheduled_operation_id = scheduled_operation_id
|
||||
|
||||
@classmethod
|
||||
def get_months_for_account(cls, session, account):
|
||||
if isinstance(account, int) or isinstance(account, str):
|
||||
account_id = account
|
||||
else:
|
||||
account_id = account.id
|
||||
|
||||
query = session.query(
|
||||
distinct(func.lpad(cast(extract("year", cls.operation_date),
|
||||
db.String), 4, '0')).label("year"),
|
||||
func.lpad(cast(extract("month", cls.operation_date),
|
||||
db.String), 2, '0').label("month")
|
||||
).filter(cls.account_id == account_id).order_by("year", "month")
|
||||
|
||||
return query
|
||||
|
@ -14,6 +14,8 @@
|
||||
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 sqlalchemy import func, case, desc
|
||||
|
||||
from accountant import db
|
||||
|
||||
from .accounts import Account
|
||||
@ -44,3 +46,52 @@ class Operation(db.Model):
|
||||
self.value = value
|
||||
self.account_id = account_id
|
||||
self.category = category
|
||||
|
||||
@classmethod
|
||||
def get_for_account_and_month(cls, session, account, year, month):
|
||||
if isinstance(account, int) or isinstance(account, str):
|
||||
account_id = account
|
||||
else:
|
||||
account_id = account.id
|
||||
|
||||
base_query = session.query(
|
||||
cls,
|
||||
case(
|
||||
whens={cls.canceled: None},
|
||||
else_=func.sum(cls.value).over(
|
||||
partition_by="canceled",
|
||||
order_by=["operation_date", desc("value"), desc("label")])
|
||||
).label("sold")
|
||||
).filter(cls.account_id == account_id).order_by(
|
||||
desc(cls.operation_date),
|
||||
cls.value,
|
||||
cls.label,
|
||||
).subquery()
|
||||
|
||||
query = session.query(base_query).select_from(base_query)
|
||||
query = query.filter(func.date_trunc(
|
||||
'month', base_query.c.operation_date) == "%s-%s-01" % (year, month))
|
||||
|
||||
return query
|
||||
|
||||
@classmethod
|
||||
def get_account_status(cls, session, account, year, month):
|
||||
if isinstance(account, int) or isinstance(account, str):
|
||||
account_id = account
|
||||
else:
|
||||
account_id = account.id
|
||||
|
||||
query = session.query(
|
||||
func.sum(case([(func.sign(cls.value) == -1, cls.value)],
|
||||
else_=0)).label("expenses"),
|
||||
func.sum(case([(func.sign(cls.value) == 1, cls.value)],
|
||||
else_=0)).label("revenues"),
|
||||
func.sum(cls.value).label("balance")
|
||||
).filter(
|
||||
cls.account_id == account_id
|
||||
).filter(
|
||||
func.date_trunc('month',
|
||||
cls.operation_date) == "%s-%s-01" % (year, month)
|
||||
).group_by(cls.account_id)
|
||||
|
||||
return query
|
||||
|
@ -14,6 +14,8 @@
|
||||
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 sqlalchemy import desc
|
||||
|
||||
from accountant import db
|
||||
|
||||
from .accounts import Account
|
||||
@ -44,3 +46,24 @@ class ScheduledOperation(db.Model):
|
||||
self.value = value
|
||||
self.account_id = account_id
|
||||
self.category = category
|
||||
|
||||
@classmethod
|
||||
def get_scheduled_operations_for_account(cls, session, account):
|
||||
if isinstance(account, int) or isinstance(account, str):
|
||||
account_id = account
|
||||
else:
|
||||
account_id = account.id
|
||||
|
||||
query = session.query(
|
||||
cls
|
||||
).select_from(
|
||||
session.query(cls)
|
||||
.filter(cls.account_id == account_id)
|
||||
.order_by(
|
||||
desc(cls.day),
|
||||
cls.value,
|
||||
cls.label,
|
||||
).subquery()
|
||||
)
|
||||
|
||||
return query
|
||||
|
@ -16,11 +16,9 @@
|
||||
"""
|
||||
from flask import json, request
|
||||
|
||||
from sqlalchemy import func, case, cast, extract, distinct
|
||||
|
||||
from forms.accounts import AccountForm
|
||||
|
||||
from accountant import db, session_scope
|
||||
from accountant import session_scope
|
||||
|
||||
from . import auth
|
||||
from .. import api
|
||||
@ -37,16 +35,7 @@ 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)
|
||||
query = Account.get_accounts(session)
|
||||
|
||||
return json.dumps([{
|
||||
"id": i.id,
|
||||
@ -62,19 +51,7 @@ def get_accounts():
|
||||
@auth.login_required
|
||||
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)
|
||||
query = Operation.get_account_status(session, account_id, year, month)
|
||||
|
||||
if query.count() == 1:
|
||||
result = query.one()
|
||||
@ -97,12 +74,7 @@ def get_account_status(account_id, year, month):
|
||||
@auth.login_required
|
||||
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")
|
||||
query = Entry.get_months_for_account(session, account_id)
|
||||
|
||||
return json.dumps([{
|
||||
"year": i.year,
|
||||
@ -129,10 +101,7 @@ def update_account(account_id):
|
||||
|
||||
if account_form.validate():
|
||||
with session_scope() as session:
|
||||
query = session.query(Account)
|
||||
query = query.filter(Account.id == account_id)
|
||||
|
||||
account = query.first()
|
||||
account = session.query(Account).get(account_id)
|
||||
|
||||
account.name = request.json['name']
|
||||
account.authorized_overdraft = request.json['authorized_overdraft']
|
||||
|
@ -16,8 +16,6 @@
|
||||
"""
|
||||
from flask import json, request
|
||||
|
||||
from sqlalchemy import func, case, desc
|
||||
|
||||
from accountant import session_scope
|
||||
|
||||
from .. import api
|
||||
@ -32,23 +30,8 @@ def get_entries(account_id, year, month):
|
||||
Return entries for an account, year, and month.
|
||||
"""
|
||||
with session_scope() as session:
|
||||
base_query = session.query(
|
||||
Operation,
|
||||
case(
|
||||
whens={Operation.canceled: None},
|
||||
else_=func.sum(Operation.value).over(
|
||||
partition_by="canceled",
|
||||
order_by=["operation_date", desc("value"), desc("label")])
|
||||
).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)
|
||||
query = query.filter(func.date_trunc(
|
||||
'month', base_query.c.operation_date) == "%s-%s-01" % (year, month))
|
||||
query = Operation.get_for_account_and_month(session, account_id, year,
|
||||
month)
|
||||
|
||||
return json.dumps([{
|
||||
"id": i.id,
|
||||
@ -85,7 +68,7 @@ def add_entry():
|
||||
@api.route("/entries/<entry_id>", methods=["PUT"])
|
||||
def update_entry(entry_id):
|
||||
with session_scope() as session:
|
||||
entry = session.query(Entry).filter(Entry.id == entry_id).first()
|
||||
entry = session.query(Entry).get(entry_id)
|
||||
|
||||
entry.id = entry_id
|
||||
entry.operation_date = request.json['operation_date']
|
||||
|
@ -16,8 +16,6 @@
|
||||
"""
|
||||
from flask import json, request
|
||||
|
||||
from sqlalchemy import desc
|
||||
|
||||
from accountant import session_scope
|
||||
|
||||
from .. import api
|
||||
@ -30,17 +28,8 @@ def get_scheduled_operations(account_id):
|
||||
Return entries for an account, year, and month.
|
||||
"""
|
||||
with session_scope() as session:
|
||||
query = session.query(
|
||||
ScheduledOperation
|
||||
).select_from(
|
||||
session.query(ScheduledOperation)
|
||||
.filter(ScheduledOperation.account_id == account_id)
|
||||
.order_by(
|
||||
desc(ScheduledOperation.day),
|
||||
ScheduledOperation.value,
|
||||
ScheduledOperation.label,
|
||||
).subquery()
|
||||
)
|
||||
query = ScheduledOperation.get_scheduled_operations_for_account(
|
||||
session, account_id)
|
||||
|
||||
return json.dumps([{
|
||||
"id": i.id,
|
||||
|
Loading…
Reference in New Issue
Block a user