fix(loyalty): translate category names in transaction history
Some checks failed
CI / ruff (push) Successful in 15s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has been cancelled

Category names in transaction tables now resolve to the current
page language instead of always showing English. Updated:
- category_service.validate_category_for_store: accepts lang param,
  uses get_translated_name()
- Store transactions list route: passes request.state.language
- Card detail transactions route: passes request.state.language
- card_service.get_customer_transactions_with_store_names: accepts
  lang param for storefront route

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-25 14:17:43 +02:00
parent 10e37e749b
commit 255ac6525e
3 changed files with 29 additions and 9 deletions

View File

@@ -639,6 +639,7 @@ def get_card_detail(
@router.get("/transactions", response_model=TransactionListResponse)
def list_store_transactions(
request: Request,
skip: int = Query(0, ge=0),
limit: int = Query(10, ge=1, le=100),
current_user: User = Depends(get_current_store_api),
@@ -647,6 +648,7 @@ def list_store_transactions(
"""List recent transactions for this merchant's loyalty program."""
store_id = current_user.token_store_id
merchant_id = get_store_merchant_id(db, store_id)
lang = getattr(request.state, "language", "en") or "en"
transactions, total = card_service.get_store_transactions(
db, merchant_id, skip=skip, limit=limit
@@ -663,7 +665,7 @@ def list_store_transactions(
names = []
for cid in t.category_ids:
name = category_service.validate_category_for_store(
db, cid, t.store_id or 0
db, cid, t.store_id or 0, lang=lang
)
if name:
names.append(name)
@@ -727,6 +729,7 @@ def enroll_customer(
@router.get("/cards/{card_id}/transactions", response_model=TransactionListResponse)
def get_card_transactions(
request: Request,
card_id: int = Path(..., gt=0),
skip: int = Query(0, ge=0),
limit: int = Query(50, ge=1, le=100),
@@ -735,6 +738,7 @@ def get_card_transactions(
):
"""Get transaction history for a card."""
store_id = current_user.token_store_id
lang = getattr(request.state, "language", "en") or "en"
# Verify card belongs to this merchant (raises LoyaltyCardNotFoundException if not found)
card_service.lookup_card_for_store(db, store_id, card_id=card_id)
@@ -743,10 +747,23 @@ def get_card_transactions(
db, card_id, skip=skip, limit=limit
)
return TransactionListResponse(
transactions=[TransactionResponse.model_validate(t) for t in transactions],
total=total,
)
from app.modules.loyalty.services.category_service import category_service
tx_responses = []
for t in transactions:
tx = TransactionResponse.model_validate(t)
if t.category_ids and isinstance(t.category_ids, list):
names = []
for cid in t.category_ids:
name = category_service.validate_category_for_store(
db, cid, t.store_id or 0, lang=lang
)
if name:
names.append(name)
tx.category_names = names if names else None
tx_responses.append(tx)
return TransactionListResponse(transactions=tx_responses, total=total)
# =============================================================================

View File

@@ -807,6 +807,7 @@ class CardService:
*,
skip: int = 0,
limit: int = 20,
lang: str = "en",
) -> tuple[list[dict], int]:
"""
Get transaction history for a card with store names resolved.
@@ -853,7 +854,7 @@ class CardService:
names = []
for cid in tx.category_ids:
name = category_service.validate_category_for_store(
db, cid, tx.store_id or 0
db, cid, tx.store_id or 0, lang=lang
)
if name:
names.append(name)

View File

@@ -138,11 +138,11 @@ class CategoryService:
logger.info(f"Deleted category {category_id} from store {store_id}")
def validate_category_for_store(
self, db: Session, category_id: int, store_id: int
self, db: Session, category_id: int, store_id: int, lang: str = "en"
) -> str | None:
"""Validate that a category belongs to the store.
Returns the category name if valid, None if not found.
Returns the translated category name if valid, None if not found.
"""
category = (
db.query(StoreTransactionCategory)
@@ -153,7 +153,9 @@ class CategoryService:
)
.first()
)
return category.name if category else None
if not category:
return None
return category.get_translated_name(lang)
# Singleton