PR Review Lab · Limit Coupon Redemptions

25:00left of 25:00

Limit Coupon Redemptions

Marketing wants coupons that run out. Each coupon now has an expiry and a redemption limit, and each customer can redeem a coupon once. Also adds the HTTP handler for the redeem button.

Mcoupons/service.go1 of 3

Files Changed

coupons/

coupons/service.go

Go · Click a line number to comment · Tap a line to comment
@@ -1,20 +1,43 @@
package coupons
import (
"context"
"errors"
Added: "time"
)
Removed: var ErrNotFound = errors.New("coupon not found")
Added: var (
Added: ErrNotFound = errors.New("coupon not found")
Added: ErrExpired = errors.New("coupon expired")
Added: ErrExhausted = errors.New("coupon fully redeemed")
Added: ErrAlreadyRedeemed = errors.New("coupon already redeemed")
Added: )
type Service struct {
store Store
}
func (s *Service) Redeem(ctx context.Context, userID, code string) error {
c, err := s.store.GetCoupon(ctx, code)
if err != nil {
return err
}
Added: if time.Now().After(c.ExpiresAt) {
Added: return ErrExpired
Added: }
Added: used, err := s.store.HasRedeemed(ctx, userID, c.Code)
Added: if err != nil {
Added: return err
Added: }
Added: if used {
Added: return ErrAlreadyRedeemed
Added: }
Added: if c.Redemptions >= c.MaxRedemptions {
Added: return ErrExhausted
Added: }
Added: c.Redemptions++
Added: if err := s.store.SaveCoupon(ctx, c); err != nil {
Added: return err
Added: }
return s.store.AddRedemption(ctx, userID, c.Code)
}