fixup! WIP
This commit is contained in:
@@ -64,6 +64,7 @@ assert all(x <= _DYNAMIC_FIELDS for x in _EXPECTED_FIELDS.values()), (
|
|||||||
"All expected fields must be part of _DYNAMIC_FIELDS."
|
"All expected fields must be part of _DYNAMIC_FIELDS."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: ensure that the transaction types are not prefixed with 'TransactionType.' in the database
|
||||||
|
|
||||||
def _transaction_type_field_constraints(
|
def _transaction_type_field_constraints(
|
||||||
transaction_type: TransactionType,
|
transaction_type: TransactionType,
|
||||||
|
@@ -47,6 +47,7 @@ class User(Base):
|
|||||||
# return self.card == "11122233"
|
# return self.card == "11122233"
|
||||||
|
|
||||||
# TODO: move to 'queries'
|
# TODO: move to 'queries'
|
||||||
|
# TODO: allow filtering out 'special transactions' like 'ADJUST_INTEREST' and 'ADJUST_PENALTY'
|
||||||
def transactions(self, sql_session: Session) -> list[Transaction]:
|
def transactions(self, sql_session: Session) -> list[Transaction]:
|
||||||
"""
|
"""
|
||||||
Returns the transactions of the user in chronological order.
|
Returns the transactions of the user in chronological order.
|
||||||
|
@@ -1,54 +0,0 @@
|
|||||||
import math
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from sqlalchemy.orm import Session
|
|
||||||
|
|
||||||
from dibbler.models import (
|
|
||||||
Product,
|
|
||||||
Transaction,
|
|
||||||
User,
|
|
||||||
)
|
|
||||||
from dibbler.queries.current_interest import current_interest
|
|
||||||
from dibbler.queries.current_penalty import current_penalty
|
|
||||||
from dibbler.queries.user_balance import user_balance
|
|
||||||
|
|
||||||
from .product_price import product_price
|
|
||||||
|
|
||||||
|
|
||||||
def buy_product(
|
|
||||||
sql_session: Session,
|
|
||||||
user: User,
|
|
||||||
product: Product,
|
|
||||||
product_count: int,
|
|
||||||
time: datetime | None = None,
|
|
||||||
message: str | None = None,
|
|
||||||
) -> Transaction:
|
|
||||||
"""
|
|
||||||
Creates a BUY_PRODUCT transaction with the amount automatically calculated based on the product's current price.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# balance = user_balance(sql_session, user)
|
|
||||||
|
|
||||||
# price = product_price(sql_session, product)
|
|
||||||
|
|
||||||
# interest_rate = current_interest(sql_session)
|
|
||||||
|
|
||||||
# penalty_threshold, penalty_multiplier_percent = current_penalty(sql_session)
|
|
||||||
|
|
||||||
# price *= product_count
|
|
||||||
|
|
||||||
# price *= 1 + interest_rate / 100
|
|
||||||
|
|
||||||
# if balance < penalty_threshold:
|
|
||||||
# price *= 1 + penalty_multiplier_percent / 100
|
|
||||||
|
|
||||||
# price = math.ceil(price)
|
|
||||||
|
|
||||||
return Transaction.buy_product(
|
|
||||||
time=time,
|
|
||||||
# amount=price,
|
|
||||||
user_id=user.id,
|
|
||||||
product_id=product.id,
|
|
||||||
product_count=product_count,
|
|
||||||
message=message,
|
|
||||||
)
|
|
@@ -17,6 +17,7 @@ from dibbler.models import (
|
|||||||
TransactionType,
|
TransactionType,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: include the transaction id in the log for easier debugging
|
||||||
|
|
||||||
def _product_price_query(
|
def _product_price_query(
|
||||||
product_id: int,
|
product_id: int,
|
||||||
@@ -121,6 +122,13 @@ def _product_price_query(
|
|||||||
return recursive_cte.union_all(recursive_elements)
|
return recursive_cte.union_all(recursive_elements)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: create a function for the log that pretty prints the log entries
|
||||||
|
# for debugging purposes
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: wrap the log entries in a dataclass, the don't cost that much
|
||||||
|
|
||||||
def product_price_log(
|
def product_price_log(
|
||||||
sql_session: Session,
|
sql_session: Session,
|
||||||
product: Product,
|
product: Product,
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from sqlalchemy import case, func, select
|
from sqlalchemy import case, func, select
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
@@ -11,13 +13,16 @@ from dibbler.models import (
|
|||||||
def product_stock(
|
def product_stock(
|
||||||
sql_session: Session,
|
sql_session: Session,
|
||||||
product: Product,
|
product: Product,
|
||||||
# use_cache: bool = True,
|
use_cache: bool = True,
|
||||||
# until: datetime | None = None,
|
until: datetime | None = None,
|
||||||
) -> int:
|
) -> int:
|
||||||
"""
|
"""
|
||||||
Returns the number of products in stock.
|
Returns the number of products in stock.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if use_cache:
|
||||||
|
print("WARNING: Using cache for product stock query is not implemented yet.")
|
||||||
|
|
||||||
result = sql_session.scalars(
|
result = sql_session.scalars(
|
||||||
select(
|
select(
|
||||||
func.sum(
|
func.sum(
|
||||||
@@ -46,6 +51,7 @@ def product_stock(
|
|||||||
]
|
]
|
||||||
),
|
),
|
||||||
Transaction.product_id == product.id,
|
Transaction.product_id == product.id,
|
||||||
|
Transaction.time <= until if until is not None else 1 == 1,
|
||||||
)
|
)
|
||||||
).one_or_none()
|
).one_or_none()
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@ from sqlalchemy.orm import Session
|
|||||||
from dibbler.models import Product
|
from dibbler.models import Product
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: modernize queries to use SQLAlchemy 2.0 style
|
||||||
def search_product(
|
def search_product(
|
||||||
string: str,
|
string: str,
|
||||||
session: Session,
|
session: Session,
|
||||||
|
@@ -26,6 +26,7 @@ from dibbler.models.Transaction import (
|
|||||||
)
|
)
|
||||||
from dibbler.queries.product_price import _product_price_query
|
from dibbler.queries.product_price import _product_price_query
|
||||||
|
|
||||||
|
# TODO: include the transaction id in the log for easier debugging
|
||||||
|
|
||||||
def _user_balance_query(
|
def _user_balance_query(
|
||||||
user: User,
|
user: User,
|
||||||
@@ -197,6 +198,14 @@ def _user_balance_query(
|
|||||||
return recursive_cte.union_all(recursive_elements)
|
return recursive_cte.union_all(recursive_elements)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: create a function for the log that pretty prints the log entries
|
||||||
|
# for debugging purposes
|
||||||
|
|
||||||
|
# TODO: wrap the log entries in a dataclass, the don't cost that much
|
||||||
|
|
||||||
|
# TODO: add a method on the dataclass, using the running penalization data
|
||||||
|
# to figure out if the current row was penalized or not.
|
||||||
|
|
||||||
def user_balance_log(
|
def user_balance_log(
|
||||||
sql_session: Session,
|
sql_session: Session,
|
||||||
user: User,
|
user: User,
|
||||||
@@ -233,7 +242,6 @@ def user_balance(
|
|||||||
sql_session: Session,
|
sql_session: Session,
|
||||||
user: User,
|
user: User,
|
||||||
use_cache: bool = True,
|
use_cache: bool = True,
|
||||||
# Optional: calculate the balance until a certain transaction.
|
|
||||||
until: Transaction | None = None,
|
until: Transaction | None = None,
|
||||||
) -> int:
|
) -> int:
|
||||||
"""
|
"""
|
||||||
|
Reference in New Issue
Block a user