fix: add card detail and store transactions endpoints for loyalty terminal
Some checks failed
Some checks failed
- Fix GET /cards/{card_id} 500 error (program_type → loyalty_type)
- Add GET /transactions endpoint for store-wide recent transactions
- Add get_store_transactions service method (merchant-scoped, store-filterable)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -346,7 +346,7 @@ def get_card_detail(
|
|||||||
merchant_name=card.merchant.name if card.merchant else None,
|
merchant_name=card.merchant.name if card.merchant else None,
|
||||||
qr_code_data=card.qr_code_data or card.card_number,
|
qr_code_data=card.qr_code_data or card.card_number,
|
||||||
program_name=program.display_name,
|
program_name=program.display_name,
|
||||||
program_type=program.program_type,
|
program_type=program.loyalty_type,
|
||||||
reward_description=program.stamps_reward_description,
|
reward_description=program.stamps_reward_description,
|
||||||
stamp_count=card.stamp_count,
|
stamp_count=card.stamp_count,
|
||||||
stamps_target=program.stamps_target,
|
stamps_target=program.stamps_target,
|
||||||
@@ -367,6 +367,27 @@ def get_card_detail(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@store_router.get("/transactions", response_model=TransactionListResponse)
|
||||||
|
def list_store_transactions(
|
||||||
|
skip: int = Query(0, ge=0),
|
||||||
|
limit: int = Query(10, ge=1, le=100),
|
||||||
|
current_user: User = Depends(get_current_store_api),
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
):
|
||||||
|
"""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)
|
||||||
|
|
||||||
|
transactions, total = card_service.get_store_transactions(
|
||||||
|
db, merchant_id, skip=skip, limit=limit
|
||||||
|
)
|
||||||
|
|
||||||
|
return TransactionListResponse(
|
||||||
|
transactions=[TransactionResponse.model_validate(t) for t in transactions],
|
||||||
|
total=total,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _build_card_lookup_response(card, db=None) -> CardLookupResponse:
|
def _build_card_lookup_response(card, db=None) -> CardLookupResponse:
|
||||||
"""Build a CardLookupResponse from a card object."""
|
"""Build a CardLookupResponse from a card object."""
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|||||||
@@ -640,6 +640,31 @@ class CardService:
|
|||||||
|
|
||||||
return transactions, total
|
return transactions, total
|
||||||
|
|
||||||
|
def get_store_transactions(
|
||||||
|
self,
|
||||||
|
db: Session,
|
||||||
|
merchant_id: int,
|
||||||
|
*,
|
||||||
|
store_id: int | None = None,
|
||||||
|
skip: int = 0,
|
||||||
|
limit: int = 10,
|
||||||
|
) -> tuple[list[LoyaltyTransaction], int]:
|
||||||
|
"""Get recent transactions for a merchant (optionally filtered by store)."""
|
||||||
|
query = (
|
||||||
|
db.query(LoyaltyTransaction)
|
||||||
|
.join(LoyaltyCard, LoyaltyTransaction.card_id == LoyaltyCard.id)
|
||||||
|
.options(joinedload(LoyaltyTransaction.store))
|
||||||
|
.filter(LoyaltyCard.merchant_id == merchant_id)
|
||||||
|
)
|
||||||
|
if store_id:
|
||||||
|
query = query.filter(LoyaltyTransaction.store_id == store_id)
|
||||||
|
|
||||||
|
query = query.order_by(LoyaltyTransaction.transaction_at.desc())
|
||||||
|
total = query.count()
|
||||||
|
transactions = query.offset(skip).limit(limit).all()
|
||||||
|
|
||||||
|
return transactions, total
|
||||||
|
|
||||||
def get_customer_transactions_with_store_names(
|
def get_customer_transactions_with_store_names(
|
||||||
self,
|
self,
|
||||||
db: Session,
|
db: Session,
|
||||||
|
|||||||
Reference in New Issue
Block a user