diff options
| author | stuppie | 2026-09-03 10:38:27 -0600 |
|---|---|---|
| committer | stuppie | 2026-09-03 10:38:27 -0600 |
| commit | f9213cdbe4e1000898f9fc259603daa88546df73 (patch) | |
| tree | bd0b1450529f491620ddd6bf2d0ebb7f3e879cc7 | |
| parent | 8d1c0c6b98c403186516f8e6bcadf0be5bcf7a84 (diff) | |
| download | generalresearch-f9213cdbe4e1000898f9fc259603daa88546df73.tar.gz generalresearch-f9213cdbe4e1000898f9fc259603daa88546df73.zip | |
add tx manager: get_session_attempt_credit and helpers
| -rw-r--r-- | generalresearch/managers/thl/ledger_manager/ledger.py | 44 | ||||
| -rw-r--r-- | generalresearch/managers/thl/ledger_manager/thl_ledger.py | 25 |
2 files changed, 49 insertions, 20 deletions
diff --git a/generalresearch/managers/thl/ledger_manager/ledger.py b/generalresearch/managers/thl/ledger_manager/ledger.py index 864f1dd..a344430 100644 --- a/generalresearch/managers/thl/ledger_manager/ledger.py +++ b/generalresearch/managers/thl/ledger_manager/ledger.py @@ -2,9 +2,9 @@ from __future__ import annotations import logging from collections import defaultdict -from collections.abc import Collection +from collections.abc import Callable, Collection from datetime import datetime, timedelta, timezone -from typing import Any, Callable +from typing import Any from uuid import UUID import redis @@ -118,9 +118,9 @@ class LedgerManagerBasePostgres(PostgresManager, RedisManager): filters.append("key = %(metadata_key)s") params["metadata_key"] = metadata_key if metadata_value is not None: - assert ( - metadata_key is not None - ), "cannot filter by metadata_value without metadata_key" + assert metadata_key is not None, ( + "cannot filter by metadata_value without metadata_key" + ) filters.append("value = %(metadata_value)s") params["metadata_value"] = metadata_value @@ -129,7 +129,6 @@ class LedgerManagerBasePostgres(PostgresManager, RedisManager): class LedgerTransactionManager(LedgerManagerBasePostgres): - def create_tx( self, entries: list[LedgerEntry], @@ -145,9 +144,9 @@ class LedgerTransactionManager(LedgerManagerBasePostgres): lastrowid) """ - assert ( - Permission.CREATE in self.permissions - ), "LedgerTransactionManager has insufficient Permissions" + assert Permission.CREATE in self.permissions, ( + "LedgerTransactionManager has insufficient Permissions" + ) if metadata is None: metadata = dict() @@ -342,7 +341,7 @@ class LedgerTransactionManager(LedgerManagerBasePostgres): assert len(tag) > 6, "Please confirm the tag is valid" res = self.pg_config.execute_sql_query( - query=f""" + query=""" SELECT lt.id FROM ledger_transaction AS lt WHERE tag = %s @@ -354,13 +353,21 @@ class LedgerTransactionManager(LedgerManagerBasePostgres): raise ValueError(f"Too many txs with this tag: {tag}") return {x["id"] for x in res} - def get_tx_by_tag(self, tag: str) -> list[LedgerTransaction]: + def get_txs_by_tag(self, tag: str) -> list[LedgerTransaction]: tx_ids = self.get_tx_ids_by_tag(tag=tag) return self.get_tx_by_ids(transaction_ids=tx_ids) + def get_tx_by_tag_if_exists(self, tag: str) -> LedgerTransaction | None: + tx_ids = self.get_tx_ids_by_tag(tag=tag) + if not tx_ids: + return None + if len(tx_ids) != 1: + raise ValueError(f"Two transactions found for tag: {tag}!") + return self.get_tx_by_id(transaction_id=next(iter(tx_ids))) + def get_tx_ids_by_tags(self, tags: list[str]) -> set[PositiveInt]: res = self.pg_config.execute_sql_query( - query=f""" + query=""" SELECT lt.id, lt.tag, lt.created, lt.ext_description FROM ledger_transaction AS lt WHERE tag = ANY(%s) @@ -796,7 +803,6 @@ class LedgerMetadataManager(LedgerManagerBasePostgres): class LedgerEntryManager(LedgerManagerBasePostgres): - def get_tx_entries_by_tx(self, transaction: LedgerTransaction) -> list[LedgerEntry]: return self.get_tx_entries_by_txs(transactions=[transaction]) @@ -828,9 +834,9 @@ class LedgerAccountManager(LedgerManagerBasePostgres): """ def create_account(self, account: LedgerAccount) -> LedgerAccount: - assert ( - Permission.CREATE in self.permissions - ), "LedgerManager does not have sufficient permissions" + assert Permission.CREATE in self.permissions, ( + "LedgerManager does not have sufficient permissions" + ) d = account.model_dump(mode="json") @@ -868,7 +874,7 @@ class LedgerAccountManager(LedgerManagerBasePostgres): # qualified_name has a unique index so there can only be 0 or 1 match. res = self.pg_config.execute_sql_query( - query=f""" + query=""" SELECT uuid, display_name, qualified_name, account_type, normal_balance, reference_type, @@ -927,7 +933,7 @@ class LedgerAccountManager(LedgerManagerBasePostgres): # TODO: Move to RR with long timeout (2min+), it causes problems res = self.pg_config.execute_sql_query( - query=f""" + query=""" SELECT SUM(amount * direction) AS total FROM ledger_entry WHERE account_id = %s @@ -1045,7 +1051,7 @@ class LedgerManager( """This is for testing only, as it'll take forever to run this if the ledger_manager is huge """ - res = self.pg_config.execute_sql_query(f""" + res = self.pg_config.execute_sql_query(""" SELECT SUM(CASE WHEN normal_balance = -1 THEN total ELSE 0 END) AS credit_total, SUM(CASE WHEN normal_balance = 1 THEN total ELSE 0 END) AS debit_total diff --git a/generalresearch/managers/thl/ledger_manager/thl_ledger.py b/generalresearch/managers/thl/ledger_manager/thl_ledger.py index aac47ed..295385d 100644 --- a/generalresearch/managers/thl/ledger_manager/thl_ledger.py +++ b/generalresearch/managers/thl/ledger_manager/thl_ledger.py @@ -1586,7 +1586,7 @@ class ThlLedgerManager(LedgerManager): This must be for an abandoned session, as when a session if finished and is eligible for an attempt credit, then the credit is automatically given.""" - + assert user.user_id is not None session = session_manager.get_latest_for_user(user_id=user.user_id) if session is None: raise ValueError("User has no session to claim attempt credit for") @@ -1600,6 +1600,29 @@ class ThlLedgerManager(LedgerManager): skip_flag_check=skip_flag_check, ) + def get_session_attempt_credit( + self, + session_uuid: UUIDStr, + ) -> int | None: + tag = ( + f"{self.currency.value}:" + f"{TransactionType.USER_ATTEMPT_CREDIT.value}:" + f"{session_uuid}" + ) + tx = self.get_tx_by_tag_if_exists(tag) + if not tx: + return None + + credit_entries = [ + entry for entry in tx.entries if entry.direction == Direction.CREDIT + ] + if len(credit_entries) != 1: + raise ValueError( + f"Expected one credit entry for attempt-credit transaction {tx.id}" + ) + + return credit_entries[0].amount + def create_tx_user_enter_contest( self, contest_uuid: UUIDStr, |
