fix floor transaction with value which has more ziffers than scale #33
This commit is contained in:
		
							parent
							
								
									b40d40644d
								
							
						
					
					
						commit
						cab172dc65
					
				|  | @ -48,7 +48,13 @@ def get_balance(user, start: datetime = None, end: datetime = None): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def get_balances( | 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( |     logger.debug( | ||||||
|         f"get_balances(start={start}, end={end}, limit={limit}, offset={offset}, descending={descending}, sortBy={sortBy}, _filter={_filter})" |         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): |     class _User(User): | ||||||
|         _debit = db.relationship(Transaction, back_populates="sender_", foreign_keys=[Transaction._sender_id]) |         _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 |         @hybrid_property | ||||||
|         def debit(self): |         def debit(self): | ||||||
|  | @ -92,7 +102,12 @@ def get_balances( | ||||||
|         def limit(cls): |         def limit(cls): | ||||||
|             return ( |             return ( | ||||||
|                 db.select(_UserAttribute.value) |                 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() |                 .scalar_subquery() | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|  | @ -127,14 +142,25 @@ def get_balances( | ||||||
| 
 | 
 | ||||||
|     if _filter: |     if _filter: | ||||||
|         query = query.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 sortBy == "balance": | ||||||
|         if descending: |         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: |         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": |     elif sortBy == "limit": | ||||||
|         if descending: |         if descending: | ||||||
|             query = query.order_by(_User.limit.desc(), User.lastname.asc(), User.firstname.asc()) |             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( |             BalancePlugin.getPlugin().notify( | ||||||
|                 sender, |                 sender, | ||||||
|                 "Neue Transaktion", |                 "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 receiver is not None and receiver.id_ != author.id_: | ||||||
|         if sender is not None: |         if sender is not None: | ||||||
|  | @ -226,7 +256,11 @@ def send(sender: User, receiver, amount: float, author: User): | ||||||
|             BalancePlugin.getPlugin().notify( |             BalancePlugin.getPlugin().notify( | ||||||
|                 receiver, |                 receiver, | ||||||
|                 "Neue Transaktion", |                 "Neue Transaktion", | ||||||
|                 {"type": NotifyType.ADD_FROM, "author_id": author.userid, "amount": amount}, |                 { | ||||||
|  |                     "type": NotifyType.ADD_FROM, | ||||||
|  |                     "author_id": author.userid, | ||||||
|  |                     "amount": amount, | ||||||
|  |                 }, | ||||||
|             ) |             ) | ||||||
|     return transaction |     return transaction | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,9 @@ | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| from typing import Optional | from typing import Optional | ||||||
| from sqlalchemy.ext.hybrid import hybrid_property | from sqlalchemy.ext.hybrid import hybrid_property | ||||||
|  | from math import floor | ||||||
| 
 | 
 | ||||||
|  | from flaschengeist import logger | ||||||
| from flaschengeist.database import db | from flaschengeist.database import db | ||||||
| from flaschengeist.models.user import User | from flaschengeist.models.user import User | ||||||
| from flaschengeist.models import ModelSerializeMixin, UtcDateTime, Serial | from flaschengeist.models import ModelSerializeMixin, UtcDateTime, Serial | ||||||
|  | @ -18,8 +20,9 @@ class Transaction(db.Model, ModelSerializeMixin): | ||||||
|     # Public and exported member |     # Public and exported member | ||||||
|     id: int = db.Column("id", Serial, primary_key=True) |     id: int = db.Column("id", Serial, primary_key=True) | ||||||
|     time: datetime = db.Column(UtcDateTime, nullable=False, default=UtcDateTime.current_utc) |     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")) |     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) |     # Dummy properties used for JSON serialization (userid instead of full user) | ||||||
|     author_id: Optional[str] = None |     author_id: Optional[str] = None | ||||||
|  | @ -56,3 +59,14 @@ class Transaction(db.Model, ModelSerializeMixin): | ||||||
|     @property |     @property | ||||||
|     def original_id(self): |     def original_id(self): | ||||||
|         return self.original_.id if self.original_ else None |         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"<Transaction {self.id} {self.amount} {self.time} {self.sender_id} {self.receiver_id} {self.author_id}>" | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| from datetime import datetime, timezone | from datetime import datetime, timezone | ||||||
|  | from logging import log | ||||||
| from werkzeug.exceptions import Forbidden, BadRequest | from werkzeug.exceptions import Forbidden, BadRequest | ||||||
| from flask import Blueprint, request, jsonify | from flask import Blueprint, request, jsonify | ||||||
| 
 | 
 | ||||||
|  | @ -163,6 +164,7 @@ def get_balance(userid, current_session: Session): | ||||||
|         end = datetime.now(tz=timezone.utc) |         end = datetime.now(tz=timezone.utc) | ||||||
| 
 | 
 | ||||||
|     balance = balance_controller.get_balance(user, start, end) |     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]} |     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, |         show_cancelled=show_cancelled, | ||||||
|         descending=descending, |         descending=descending, | ||||||
|     ) |     ) | ||||||
|  |     logger.debug(f"transactions: {transactions}") | ||||||
|     return {"transactions": transactions, "count": count} |     return {"transactions": transactions, "count": count} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -321,7 +324,11 @@ def get_balances(current_session: Session): | ||||||
|     _filter = request.args.get("filter", None, type=str) |     _filter = request.args.get("filter", None, type=str) | ||||||
|     logger.debug(f"request.args: {request.args}") |     logger.debug(f"request.args: {request.args}") | ||||||
|     balances, count = balance_controller.get_balances( |     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( |     return jsonify( | ||||||
|         { |         { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue