From cab172dc65a71070f06af6866bc6ec8ca2887b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Gr=C3=B6ger?= Date: Wed, 17 May 2023 14:47:40 +0200 Subject: [PATCH] fix floor transaction with value which has more ziffers than scale #33 --- .../plugins/balance/balance_controller.py | 50 ++++++++++++++++--- flaschengeist/plugins/balance/models.py | 16 +++++- flaschengeist/plugins/balance/routes.py | 9 +++- 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/flaschengeist/plugins/balance/balance_controller.py b/flaschengeist/plugins/balance/balance_controller.py index 797b039..5201d76 100644 --- a/flaschengeist/plugins/balance/balance_controller.py +++ b/flaschengeist/plugins/balance/balance_controller.py @@ -48,7 +48,13 @@ def get_balance(user, start: datetime = None, end: datetime = None): def get_balances( - start: datetime = None, end: datetime = None, limit=None, offset=None, descending=None, sortBy=None, _filter=None + start: datetime = None, + end: datetime = None, + limit=None, + offset=None, + descending=None, + sortBy=None, + _filter=None, ): logger.debug( f"get_balances(start={start}, end={end}, limit={limit}, offset={offset}, descending={descending}, sortBy={sortBy}, _filter={_filter})" @@ -56,7 +62,11 @@ def get_balances( class _User(User): _debit = db.relationship(Transaction, back_populates="sender_", foreign_keys=[Transaction._sender_id]) - _credit = db.relationship(Transaction, back_populates="receiver_", foreign_keys=[Transaction._receiver_id]) + _credit = db.relationship( + Transaction, + back_populates="receiver_", + foreign_keys=[Transaction._receiver_id], + ) @hybrid_property def debit(self): @@ -92,7 +102,12 @@ def get_balances( def limit(cls): return ( db.select(_UserAttribute.value) - .where(and_(cls.id_ == _UserAttribute.user, _UserAttribute.name == "balance_limit")) + .where( + and_( + cls.id_ == _UserAttribute.user, + _UserAttribute.name == "balance_limit", + ) + ) .scalar_subquery() ) @@ -127,14 +142,25 @@ def get_balances( if _filter: query = query.filter( - or_(_User.firstname.ilike(f"%{_filter.lower()}%"), _User.lastname.ilike(f"%{_filter.lower()}%")) + or_( + _User.firstname.ilike(f"%{_filter.lower()}%"), + _User.lastname.ilike(f"%{_filter.lower()}%"), + ) ) if sortBy == "balance": if descending: - query = query.order_by((_User.credit - _User.debit).desc(), _User.lastname.asc(), _User.firstname.asc()) + 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()) + 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()) @@ -209,7 +235,11 @@ def send(sender: User, receiver, amount: float, author: User): BalancePlugin.getPlugin().notify( sender, "Neue Transaktion", - {"type": NotifyType.SUB_FROM, "author_id": author.userid, "amount": amount}, + { + "type": NotifyType.SUB_FROM, + "author_id": author.userid, + "amount": amount, + }, ) if receiver is not None and receiver.id_ != author.id_: if sender is not None: @@ -226,7 +256,11 @@ def send(sender: User, receiver, amount: float, author: User): BalancePlugin.getPlugin().notify( receiver, "Neue Transaktion", - {"type": NotifyType.ADD_FROM, "author_id": author.userid, "amount": amount}, + { + "type": NotifyType.ADD_FROM, + "author_id": author.userid, + "amount": amount, + }, ) return transaction diff --git a/flaschengeist/plugins/balance/models.py b/flaschengeist/plugins/balance/models.py index 2d9525b..fa51f7d 100644 --- a/flaschengeist/plugins/balance/models.py +++ b/flaschengeist/plugins/balance/models.py @@ -1,7 +1,9 @@ from datetime import datetime from typing import Optional from sqlalchemy.ext.hybrid import hybrid_property +from math import floor +from flaschengeist import logger from flaschengeist.database import db from flaschengeist.models.user import User from flaschengeist.models import ModelSerializeMixin, UtcDateTime, Serial @@ -18,8 +20,9 @@ class Transaction(db.Model, ModelSerializeMixin): # Public and exported member id: int = db.Column("id", Serial, primary_key=True) time: datetime = db.Column(UtcDateTime, nullable=False, default=UtcDateTime.current_utc) - amount: float = db.Column(db.Numeric(precision=5, scale=2, asdecimal=False), nullable=False) + _amount: float = db.Column("amount", db.Numeric(precision=5, scale=2, asdecimal=False), nullable=False) reversal_id: Optional[int] = db.Column(Serial, db.ForeignKey("balance_transaction.id")) + amount: float # Dummy properties used for JSON serialization (userid instead of full user) author_id: Optional[str] = None @@ -56,3 +59,14 @@ class Transaction(db.Model, ModelSerializeMixin): @property def original_id(self): return self.original_.id if self.original_ else None + + @property + def amount(self): + return self._amount + + @amount.setter + def amount(self, value): + self._amount = floor(value * 100) / 100 + + def __repr__(self): + return f"" diff --git a/flaschengeist/plugins/balance/routes.py b/flaschengeist/plugins/balance/routes.py index 8ba1efb..0e14a81 100644 --- a/flaschengeist/plugins/balance/routes.py +++ b/flaschengeist/plugins/balance/routes.py @@ -1,4 +1,5 @@ from datetime import datetime, timezone +from logging import log from werkzeug.exceptions import Forbidden, BadRequest from flask import Blueprint, request, jsonify @@ -163,6 +164,7 @@ def get_balance(userid, current_session: Session): end = datetime.now(tz=timezone.utc) balance = balance_controller.get_balance(user, start, end) + logger.debug(f"Balance of {user.userid} from {start} to {end}: {balance}") return {"credit": balance[0], "debit": balance[1], "balance": balance[2]} @@ -224,6 +226,7 @@ def get_transactions(userid, current_session: Session): show_cancelled=show_cancelled, descending=descending, ) + logger.debug(f"transactions: {transactions}") return {"transactions": transactions, "count": count} @@ -321,7 +324,11 @@ def get_balances(current_session: Session): _filter = request.args.get("filter", None, type=str) logger.debug(f"request.args: {request.args}") balances, count = balance_controller.get_balances( - limit=limit, offset=offset, descending=descending, sortBy=sortBy, _filter=_filter + limit=limit, + offset=offset, + descending=descending, + sortBy=sortBy, + _filter=_filter, ) return jsonify( {