aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstuppie2026-09-03 10:38:27 -0600
committerstuppie2026-09-03 10:38:27 -0600
commitf9213cdbe4e1000898f9fc259603daa88546df73 (patch)
treebd0b1450529f491620ddd6bf2d0ebb7f3e879cc7
parent8d1c0c6b98c403186516f8e6bcadf0be5bcf7a84 (diff)
downloadgeneralresearch-f9213cdbe4e1000898f9fc259603daa88546df73.tar.gz
generalresearch-f9213cdbe4e1000898f9fc259603daa88546df73.zip
add tx manager: get_session_attempt_credit and helpers
-rw-r--r--generalresearch/managers/thl/ledger_manager/ledger.py44
-rw-r--r--generalresearch/managers/thl/ledger_manager/thl_ledger.py25
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,