From fcde2d68fc52e9c93c860bf4994a775971fbf2e3 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Mon, 23 Mar 2026 21:25:28 +0100 Subject: [PATCH] fix(loyalty): use SQL func.replace() for card number search list_cards() was calling Python .replace() on a SQLAlchemy column object instead of SQL func.replace(), causing AttributeError when searching cards by card number. Co-Authored-By: Claude Opus 4.6 (1M context) --- app/modules/loyalty/services/card_service.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/modules/loyalty/services/card_service.py b/app/modules/loyalty/services/card_service.py index c01ece46..b5c35626 100644 --- a/app/modules/loyalty/services/card_service.py +++ b/app/modules/loyalty/services/card_service.py @@ -393,12 +393,14 @@ class CardService: query = query.filter(LoyaltyCard.is_active == is_active) if search: + from sqlalchemy import func + # Normalize search term for card number matching search_normalized = search.replace("-", "").replace(" ", "") # Use relationship-based join to avoid direct Customer model import CustomerModel = LoyaltyCard.customer.property.mapper.class_ query = query.join(LoyaltyCard.customer).filter( - (LoyaltyCard.card_number.replace("-", "").ilike(f"%{search_normalized}%")) + (func.replace(LoyaltyCard.card_number, "-", "").ilike(f"%{search_normalized}%")) | (CustomerModel.email.ilike(f"%{search}%")) | (CustomerModel.first_name.ilike(f"%{search}%")) | (CustomerModel.last_name.ilike(f"%{search}%"))