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) @router.get("/transactions", response_model=TransactionListResponse)
def list_store_transactions( def list_store_transactions(
request: Request,
skip: int = Query(0, ge=0), skip: int = Query(0, ge=0),
limit: int = Query(10, ge=1, le=100), limit: int = Query(10, ge=1, le=100),
current_user: User = Depends(get_current_store_api), 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.""" """List recent transactions for this merchant's loyalty program."""
store_id = current_user.token_store_id store_id = current_user.token_store_id
merchant_id = get_store_merchant_id(db, 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( transactions, total = card_service.get_store_transactions(
db, merchant_id, skip=skip, limit=limit db, merchant_id, skip=skip, limit=limit
@@ -663,7 +665,7 @@ def list_store_transactions(
names = [] names = []
for cid in t.category_ids: for cid in t.category_ids:
name = category_service.validate_category_for_store( 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: if name:
names.append(name) names.append(name)
@@ -727,6 +729,7 @@ def enroll_customer(
@router.get("/cards/{card_id}/transactions", response_model=TransactionListResponse) @router.get("/cards/{card_id}/transactions", response_model=TransactionListResponse)
def get_card_transactions( def get_card_transactions(
request: Request,
card_id: int = Path(..., gt=0), card_id: int = Path(..., gt=0),
skip: int = Query(0, ge=0), skip: int = Query(0, ge=0),
limit: int = Query(50, ge=1, le=100), limit: int = Query(50, ge=1, le=100),
@@ -735,6 +738,7 @@ def get_card_transactions(
): ):
"""Get transaction history for a card.""" """Get transaction history for a card."""
store_id = current_user.token_store_id 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) # Verify card belongs to this merchant (raises LoyaltyCardNotFoundException if not found)
card_service.lookup_card_for_store(db, store_id, card_id=card_id) 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 db, card_id, skip=skip, limit=limit
) )
return TransactionListResponse( from app.modules.loyalty.services.category_service import category_service
transactions=[TransactionResponse.model_validate(t) for t in transactions],
total=total, 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, skip: int = 0,
limit: int = 20, limit: int = 20,
lang: str = "en",
) -> tuple[list[dict], int]: ) -> tuple[list[dict], int]:
""" """
Get transaction history for a card with store names resolved. Get transaction history for a card with store names resolved.
@@ -853,7 +854,7 @@ class CardService:
names = [] names = []
for cid in tx.category_ids: for cid in tx.category_ids:
name = category_service.validate_category_for_store( 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: if name:
names.append(name) names.append(name)

View File

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