feat(backend): remove auto loyalty redemption from booking progress
Remove auto-apply of pending loyalty redemption during ProgressBookingHandler. Now only checks if loyalty was applied on this booking (via booking_discounts) to skip stamp award. Redemption is purely manual via ApplyLoyaltyRedemption. Use LoyaltyStampCost constant instead of hardcoded 10. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -2553,51 +2553,13 @@ func ProgressBookingHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("Failed to calculate booking total for %s: %v", bookingID, err)
|
||||
}
|
||||
|
||||
// Apply existing pending loyalty redemption (earned from previous 10 bookings)
|
||||
// Skip if already applied at payment time (or by admin)
|
||||
var loyaltyAlreadyApplied bool
|
||||
tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'loyalty')`, bookingID).Scan(&loyaltyAlreadyApplied)
|
||||
if bookingTotal > 0 && !loyaltyAlreadyApplied {
|
||||
var redemptionID string
|
||||
if err := tx.QueryRow(r.Context(), `
|
||||
SELECT id FROM loyalty_redemptions
|
||||
WHERE user_id = $1 AND status = 'pending' AND expires_at > NOW()
|
||||
ORDER BY redeemed_at ASC LIMIT 1
|
||||
`, booking.User.ID).Scan(&redemptionID); err == nil && redemptionID != "" {
|
||||
discountAmount := roundTo2(bookingTotal * 0.10)
|
||||
// Don't award a stamp if this booking already used a loyalty redemption
|
||||
// (take or receive, never both).
|
||||
var loyaltyAppliedOnThisBooking bool
|
||||
tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM booking_discounts WHERE booking_id = $1 AND discount_source = 'loyalty')`, bookingID).Scan(&loyaltyAppliedOnThisBooking)
|
||||
|
||||
if _, err := tx.Exec(r.Context(), `
|
||||
INSERT INTO booking_discounts (booking_id, user_id, discount_source, source_id, campaign_type, milestone_type, discount_percent, original_total, discount_amount)
|
||||
VALUES ($1, $2, 'loyalty', $3, NULL, NULL, 10.00, $4, $5)
|
||||
`, bookingID, booking.User.ID, redemptionID, bookingTotal, discountAmount); err != nil {
|
||||
log.Printf("ALERT: failed to insert booking discount: %v", err)
|
||||
}
|
||||
|
||||
if _, err := tx.Exec(r.Context(), `
|
||||
INSERT INTO payments (booking_id, payment_type, payment_method, amount, status, created_by)
|
||||
VALUES ($1, 'partial', 'discount', $2, 'completed', $3)
|
||||
`, bookingID, discountAmount, booking.User.ID); err != nil {
|
||||
log.Printf("ALERT: failed to insert payment record: %v", err)
|
||||
}
|
||||
|
||||
if _, err := tx.Exec(r.Context(), `
|
||||
UPDATE loyalty_redemptions SET status = 'applied', applied_to_booking_id = $1, applied_at = NOW()
|
||||
WHERE id = $2
|
||||
`, bookingID, redemptionID); err != nil {
|
||||
log.Printf("ALERT: failed to update loyalty redemption: %v", err)
|
||||
}
|
||||
|
||||
if _, err := tx.Exec(r.Context(), `
|
||||
UPDATE users SET loyalty_stamps = GREATEST(0, loyalty_stamps - 10) WHERE id = $1
|
||||
`, booking.User.ID); err != nil {
|
||||
log.Printf("ALERT: failed to update loyalty stamps: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Increment stamps (max 1 per day, only for paid bookings)
|
||||
var newStampCount int
|
||||
if bookingTotal > 0 {
|
||||
if bookingTotal > 0 && !loyaltyAppliedOnThisBooking {
|
||||
if err := tx.QueryRow(r.Context(), `
|
||||
UPDATE users
|
||||
SET loyalty_stamps = loyalty_stamps + 1
|
||||
@@ -2617,12 +2579,12 @@ func ProgressBookingHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// Create pending redemption when stamps reach 10
|
||||
if newStampCount == 10 {
|
||||
// Create pending redemption when stamps reach LoyaltyStampCost
|
||||
if newStampCount == payments.LoyaltyStampCost {
|
||||
_, err = tx.Exec(r.Context(), `
|
||||
INSERT INTO loyalty_redemptions (user_id, stamps_redeemed, status, redeemed_at)
|
||||
VALUES ($1, 10, 'pending', NOW())
|
||||
`, booking.User.ID)
|
||||
VALUES ($1, $2, 'pending', NOW())
|
||||
`, booking.User.ID, payments.LoyaltyStampCost)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create loyalty redemption for user %s: %v", booking.User.ID, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user