feature/pricelist add server pagination for balance #17
|
@ -175,8 +175,8 @@ def register(data):
|
||||||
allowed_keys = User().serialize().keys()
|
allowed_keys = User().serialize().keys()
|
||||||
values = {key: value for key, value in data.items() if key in allowed_keys}
|
values = {key: value for key, value in data.items() if key in allowed_keys}
|
||||||
roles = values.pop("roles", [])
|
roles = values.pop("roles", [])
|
||||||
if "birthday" in values:
|
if "birthday" in data:
|
||||||
values["birthday"] = from_iso_format(values["birthday"]).date()
|
values["birthday"] = from_iso_format(data["birthday"]).date()
|
||||||
user = User(**values)
|
user = User(**values)
|
||||||
set_roles(user, roles)
|
set_roles(user, roles)
|
||||||
|
|
||||||
|
@ -195,6 +195,8 @@ def register(data):
|
||||||
)
|
)
|
||||||
messageController.send_message(messageController.Message(user, text, subject))
|
messageController.send_message(messageController.Message(user, text, subject))
|
||||||
|
|
||||||
|
find_user(user.userid)
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
|
|
|
@ -3,12 +3,13 @@
|
||||||
# English: Debit -> from account
|
# English: Debit -> from account
|
||||||
# Credit -> to account
|
# Credit -> to account
|
||||||
|
|
||||||
from sqlalchemy import func
|
from sqlalchemy import func, case, and_
|
||||||
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from werkzeug.exceptions import BadRequest, NotFound, Conflict
|
from werkzeug.exceptions import BadRequest, NotFound, Conflict
|
||||||
|
|
||||||
from flaschengeist.database import db
|
from flaschengeist.database import db
|
||||||
from flaschengeist.models.user import User
|
from flaschengeist.models.user import User, _UserAttribute
|
||||||
|
|
||||||
from .models import Transaction
|
from .models import Transaction
|
||||||
from . import permissions, BalancePlugin
|
from . import permissions, BalancePlugin
|
||||||
|
@ -38,27 +39,114 @@ def get_balance(user, start: datetime = None, end: datetime = None):
|
||||||
return credit, debit, credit - debit
|
return credit, debit, credit - debit
|
||||||
|
|
||||||
|
|
||||||
def get_balances(start: datetime = None, end: datetime = None):
|
def get_balances(start: datetime = None, end: datetime = None, limit=None, offset=None, descending=None, sortBy=None):
|
||||||
ferfissimo
commented
Der Ansatz ist cool! NICE 👍 Der Ansatz ist cool! NICE 👍
crimsen
commented
Noch irgendwas hier zu machen? Noch irgendwas hier zu machen?
|
|||||||
debit = db.session.query(Transaction.sender_id, func.sum(Transaction.amount)).filter(Transaction.sender_ != None)
|
class _User(User):
|
||||||
credit = db.session.query(Transaction.receiver_id, func.sum(Transaction.amount)).filter(
|
_debit = db.relationship(Transaction, back_populates="sender_", foreign_keys=[Transaction._sender_id])
|
||||||
Transaction.receiver_ != None
|
_credit = db.relationship(Transaction, back_populates="receiver_", foreign_keys=[Transaction._receiver_id])
|
||||||
)
|
|
||||||
if start:
|
|
||||||
debit = debit.filter(start <= Transaction.time)
|
|
||||||
credit = credit.filter(start <= Transaction.time)
|
|
||||||
if end:
|
|
||||||
debit = debit.filter(Transaction.time <= end)
|
|
||||||
credit = credit.filter(Transaction.time <= end)
|
|
||||||
|
|
||||||
debit = debit.group_by(Transaction._sender_id).all()
|
@hybrid_property
|
||||||
credit = credit.group_by(Transaction._receiver_id).all()
|
def debit(self):
|
||||||
|
return sum([cred.amount for cred in self._debit])
|
||||||
|
|
||||||
|
@debit.expression
|
||||||
|
def debit(cls):
|
||||||
|
a = (
|
||||||
|
db.select(func.sum(Transaction.amount))
|
||||||
|
.where(cls.id_ == Transaction._sender_id, Transaction.amount)
|
||||||
|
.scalar_subquery()
|
||||||
|
)
|
||||||
|
return case([(a, a)], else_=0)
|
||||||
|
|
||||||
|
@hybrid_property
|
||||||
|
def credit(self):
|
||||||
|
return sum([cred.amount for cred in self._credit])
|
||||||
|
|
||||||
|
@credit.expression
|
||||||
|
def credit(cls):
|
||||||
|
b = (
|
||||||
|
db.select(func.sum(Transaction.amount))
|
||||||
|
.where(cls.id_ == Transaction._receiver_id, Transaction.amount)
|
||||||
|
.scalar_subquery()
|
||||||
|
)
|
||||||
|
return case([(b, b)], else_=0)
|
||||||
|
|
||||||
|
@hybrid_property
|
||||||
|
def limit(self):
|
||||||
|
return self.get_attribute("balance_limit", None)
|
||||||
|
|
||||||
|
@limit.expression
|
||||||
|
def limit(cls):
|
||||||
|
return (
|
||||||
|
db.select(_UserAttribute.value)
|
||||||
|
.where(and_(cls.id_ == _UserAttribute.user, _UserAttribute.name == "balance_limit"))
|
||||||
|
.scalar_subquery()
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_debit(self, start: datetime = None, end: datetime = None):
|
||||||
|
if start and end:
|
||||||
|
return sum([deb.amount for deb in self._debit if start <= deb.time and deb.time <= end])
|
||||||
|
if start:
|
||||||
|
return sum([deb.amount for deb in self._dedit if start <= deb.time])
|
||||||
|
if end:
|
||||||
|
return sum([deb.amount for deb in self._dedit if deb.time <= end])
|
||||||
|
return self.debit
|
||||||
|
|
||||||
|
def get_credit(self, start: datetime = None, end: datetime = None):
|
||||||
|
if start and end:
|
||||||
|
return sum([cred.amount for cred in self._credit if start <= cred.time and cred.time <= end])
|
||||||
|
if start:
|
||||||
|
return sum([cred.amount for cred in self._credit if start <= cred.time])
|
||||||
|
if end:
|
||||||
|
return sum([cred.amount for cred in self._credit if cred.time <= end])
|
||||||
|
return self.credit
|
||||||
|
|
||||||
|
query = _User.query
|
||||||
|
|
||||||
|
if start:
|
||||||
|
q1 = query.join(_User._credit).filter(start <= Transaction.time)
|
||||||
|
q2 = query.join(_User._debit).filter(start <= Transaction.time)
|
||||||
|
query = q1.union(q2)
|
||||||
|
if end:
|
||||||
|
q1 = query.join(_User._credit).filter(Transaction.time <= end)
|
||||||
|
q2 = query.join(_User._debit).filter(Transaction.time <= end)
|
||||||
|
query = q1.union(q2)
|
||||||
|
|
||||||
|
if sortBy == "balance":
|
||||||
|
if descending:
|
||||||
|
query = query.order_by((_User.credit - _User.debit).desc(), _User.lastname.asc(), _User.firstname.asc())
|
||||||
|
else:
|
||||||
|
query = query.order_by((_User.credit - _User.debit).asc(), _User.lastname.asc(), _User.firstname.asc())
|
||||||
|
elif sortBy == "limit":
|
||||||
|
if descending:
|
||||||
|
query = query.order_by(_User.limit.desc(), User.lastname.asc(), User.firstname.asc())
|
||||||
|
else:
|
||||||
|
query = query.order_by(_User.limit.asc(), User.lastname.asc(), User.firstname.asc())
|
||||||
|
elif sortBy == "firstname":
|
||||||
|
if descending:
|
||||||
|
query = query.order_by(User.firstname.desc(), User.lastname.desc())
|
||||||
|
else:
|
||||||
|
query = query.order_by(User.firstname.asc(), User.lastname.asc())
|
||||||
|
elif sortBy == "lastname":
|
||||||
|
if descending:
|
||||||
|
query = query.order_by(User.lastname.desc(), User.firstname.desc())
|
||||||
|
else:
|
||||||
|
query = query.order_by(User.lastname.asc(), User.firstname.asc())
|
||||||
|
|
||||||
|
count = None
|
||||||
|
if limit:
|
||||||
|
count = query.count()
|
||||||
|
query = query.limit(limit)
|
||||||
|
if offset:
|
||||||
|
query = query.offset(offset)
|
||||||
|
users = query
|
||||||
all = {}
|
all = {}
|
||||||
for uid, cred in credit:
|
|
||||||
all[uid] = [cred, 0]
|
for user in users:
|
||||||
for uid, deb in debit:
|
|
||||||
all.setdefault(uid, [0, 0])
|
all[user.userid] = [user.get_credit(start, end), 0]
|
||||||
all[uid][1] = deb
|
all[user.userid][1] = user.get_debit(start, end)
|
||||||
return all
|
|
||||||
|
return all, count
|
||||||
|
|
||||||
|
|
||||||
def send(sender: User, receiver, amount: float, author: User):
|
def send(sender: User, receiver, amount: float, author: User):
|
||||||
|
|
|
@ -110,7 +110,6 @@ def limits(current_session: Session):
|
||||||
Returns:
|
Returns:
|
||||||
JSON encoded array of userid with limit or HTTP-error
|
JSON encoded array of userid with limit or HTTP-error
|
||||||
"""
|
"""
|
||||||
|
|
||||||
users = userController.get_users()
|
users = userController.get_users()
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
ferfissimo
commented
Siehe unten: https://flaschengeist.dev/Flaschengeist/flaschengeist/pulls/17/files#issuecomment-164
|
|||||||
return jsonify([{"userid": user.userid, "limit": user.get_attribute("balance_limit")} for user in users])
|
return jsonify([{"userid": user.userid, "limit": user.get_attribute("balance_limit")} for user in users])
|
||||||
|
@ -311,5 +310,14 @@ def get_balances(current_session: Session):
|
||||||
Returns:
|
Returns:
|
||||||
JSON Array containing credit, debit and userid for each user or HTTP error
|
JSON Array containing credit, debit and userid for each user or HTTP error
|
||||||
"""
|
"""
|
||||||
balances = balance_controller.get_balances()
|
limit = request.args.get("limit", type=int)
|
||||||
return jsonify([{"userid": u, "credit": v[0], "debit": v[1]} for u, v in balances.items()])
|
offset = request.args.get("offset", type=int)
|
||||||
|
descending = request.args.get("descending", False, type=bool)
|
||||||
|
sortBy = request.args.get("sortBy", type=str)
|
||||||
|
balances, count = balance_controller.get_balances(limit=limit, offset=offset, descending=descending, sortBy=sortBy)
|
||||||
|
return jsonify(
|
||||||
|
{
|
||||||
|
"balances": [{"userid": u, "credit": v[0], "debit": v[1]} for u, v in balances.items()],
|
||||||
|
"count": count,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Sieht für mich ziemlich unnötig aus, gibt es einen Grund das hier aufzurufen?
Damit werden gleich Userattributes geupdatet. Ohne diese Funktion, gibt es keine "DN" und es erschien mir einfacher, das einfach damit aufzurufen. (Benutze ich auch in run_flaschengeist ldap_sync)
Allgemein, sollte das eigentlich in einem anderen commit rein.