@@ -66,6 +66,7 @@ EXPECTED_FIELDS: dict[TransactionType, set[str]] = {
|
|||||||
TransactionType.BUY_PRODUCT: {"product_count", "product_id"},
|
TransactionType.BUY_PRODUCT: {"product_count", "product_id"},
|
||||||
TransactionType.JOINT: {"product_count", "product_id"},
|
TransactionType.JOINT: {"product_count", "product_id"},
|
||||||
TransactionType.JOINT_BUY_PRODUCT: {"joint_transaction_id"},
|
TransactionType.JOINT_BUY_PRODUCT: {"joint_transaction_id"},
|
||||||
|
TransactionType.THROW_PRODUCT: {"product_count", "product_id"},
|
||||||
TransactionType.TRANSFER: {"amount", "transfer_user_id"},
|
TransactionType.TRANSFER: {"amount", "transfer_user_id"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class TransactionType(StrEnum):
|
|||||||
BUY_PRODUCT = auto()
|
BUY_PRODUCT = auto()
|
||||||
JOINT = auto()
|
JOINT = auto()
|
||||||
JOINT_BUY_PRODUCT = auto()
|
JOINT_BUY_PRODUCT = auto()
|
||||||
|
THROW_PRODUCT = auto()
|
||||||
TRANSFER = auto()
|
TRANSFER = auto()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,28 +29,33 @@ def _product_stock_query(
|
|||||||
Transaction.type_ == TransactionType.ADD_PRODUCT,
|
Transaction.type_ == TransactionType.ADD_PRODUCT,
|
||||||
Transaction.product_count,
|
Transaction.product_count,
|
||||||
),
|
),
|
||||||
(
|
|
||||||
Transaction.type_ == TransactionType.BUY_PRODUCT,
|
|
||||||
-Transaction.product_count,
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
Transaction.type_ == TransactionType.ADJUST_STOCK,
|
Transaction.type_ == TransactionType.ADJUST_STOCK,
|
||||||
Transaction.product_count,
|
Transaction.product_count,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
Transaction.type_ == TransactionType.BUY_PRODUCT,
|
||||||
|
-Transaction.product_count,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
Transaction.type_ == TransactionType.JOINT,
|
Transaction.type_ == TransactionType.JOINT,
|
||||||
-Transaction.product_count,
|
-Transaction.product_count,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
Transaction.type_ == TransactionType.THROW_PRODUCT,
|
||||||
|
-Transaction.product_count,
|
||||||
|
),
|
||||||
else_=0,
|
else_=0,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).where(
|
).where(
|
||||||
Transaction.type_.in_(
|
Transaction.type_.in_(
|
||||||
[
|
[
|
||||||
TransactionType.BUY_PRODUCT,
|
|
||||||
TransactionType.ADD_PRODUCT,
|
TransactionType.ADD_PRODUCT,
|
||||||
TransactionType.ADJUST_STOCK,
|
TransactionType.ADJUST_STOCK,
|
||||||
|
TransactionType.BUY_PRODUCT,
|
||||||
TransactionType.JOINT,
|
TransactionType.JOINT,
|
||||||
|
TransactionType.THROW_PRODUCT,
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
Transaction.product_id == product_id,
|
Transaction.product_id == product_id,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from dibbler.models import User
|
|||||||
def search_user(
|
def search_user(
|
||||||
string: str,
|
string: str,
|
||||||
sql_session: Session,
|
sql_session: Session,
|
||||||
ignorethisflag=None,
|
|
||||||
) -> User | list[User]:
|
) -> User | list[User]:
|
||||||
string = string.lower()
|
string = string.lower()
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ from dibbler.models import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: should this include full joint transactions that involve a user?
|
||||||
|
# TODO: should this involve throw-away transactions that affects a user?
|
||||||
def transaction_log(
|
def transaction_log(
|
||||||
sql_session: Session,
|
sql_session: Session,
|
||||||
user: User | None = None,
|
user: User | None = None,
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ def _user_balance_query(
|
|||||||
),
|
),
|
||||||
Transaction.type_.in_(
|
Transaction.type_.in_(
|
||||||
[
|
[
|
||||||
|
TransactionType.THROW_PRODUCT,
|
||||||
TransactionType.ADJUST_INTEREST,
|
TransactionType.ADJUST_INTEREST,
|
||||||
TransactionType.ADJUST_PENALTY,
|
TransactionType.ADJUST_PENALTY,
|
||||||
]
|
]
|
||||||
@@ -155,10 +156,10 @@ def _user_balance_query(
|
|||||||
# at the moment of writing, after sound right, but maybe ask someone?
|
# at the moment of writing, after sound right, but maybe ask someone?
|
||||||
# Interest
|
# Interest
|
||||||
* (cast(recursive_cte.c.interest_rate_percent, Float) / 100)
|
* (cast(recursive_cte.c.interest_rate_percent, Float) / 100)
|
||||||
|
# TODO: these should be added together, not multiplied, see specification
|
||||||
# Penalty
|
# Penalty
|
||||||
* case(
|
* case(
|
||||||
(
|
(
|
||||||
# TODO: should this be <= or <?
|
|
||||||
recursive_cte.c.balance < recursive_cte.c.penalty_threshold,
|
recursive_cte.c.balance < recursive_cte.c.penalty_threshold,
|
||||||
(
|
(
|
||||||
cast(recursive_cte.c.penalty_multiplier_percent, Float)
|
cast(recursive_cte.c.penalty_multiplier_percent, Float)
|
||||||
@@ -188,6 +189,13 @@ def _user_balance_query(
|
|||||||
),
|
),
|
||||||
recursive_cte.c.balance - trx_subset.c.amount,
|
recursive_cte.c.balance - trx_subset.c.amount,
|
||||||
),
|
),
|
||||||
|
# Throws a product -> if the user is considered to have bought it, balance increases
|
||||||
|
# TODO:
|
||||||
|
# (
|
||||||
|
# trx_subset.c.type_ == TransactionType.THROW_PRODUCT,
|
||||||
|
# recursive_cte.c.balance + trx_subset.c.amount,
|
||||||
|
# ),
|
||||||
|
|
||||||
# Interest adjustment -> balance stays the same
|
# Interest adjustment -> balance stays the same
|
||||||
# Penalty adjustment -> balance stays the same
|
# Penalty adjustment -> balance stays the same
|
||||||
else_=recursive_cte.c.balance,
|
else_=recursive_cte.c.balance,
|
||||||
|
|||||||
@@ -177,3 +177,7 @@ def test_product_stock_joint_transaction(sql_session: Session) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert product_stock(sql_session, product) == 5 - 3
|
assert product_stock(sql_session, product) == 5 - 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_product_stock_throw_away(sql_session: Session) -> None:
|
||||||
|
...
|
||||||
|
|||||||
@@ -563,6 +563,7 @@ def test_transaction_log_combined_filter_product_transaction_id_transaction_type
|
|||||||
|
|
||||||
assert len(result) == 2
|
assert len(result) == 2
|
||||||
|
|
||||||
|
# NOTE: see the corresponding TODO's above the function definition
|
||||||
|
|
||||||
# NOTE: how should this work? Do we includ the entire JOINT transaction, or only the part relevant to the user?
|
|
||||||
def test_transaction_log_filtered_by_user_joint_transactions(sql_session: Session) -> None: ...
|
def test_transaction_log_filtered_by_user_joint_transactions(sql_session: Session) -> None: ...
|
||||||
|
def test_transaction_log_filtered_by_user_throw_away_transactions(sql_session: Session) -> None: ...
|
||||||
|
|||||||
@@ -324,3 +324,6 @@ def test_user_balance_joint_transactions_changing_penalty(sql_session: Session):
|
|||||||
|
|
||||||
def test_user_balance_joint_transactions_penalty_interest_combined(sql_session: Session):
|
def test_user_balance_joint_transactions_penalty_interest_combined(sql_session: Session):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def test_user_balance_throw_away_products(sql_session: Session):
|
||||||
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user