package controller import ( "errors" "time" "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/model" "github.com/gin-gonic/gin" "gorm.io/gorm" ) const invalidPromoCodeReason = "invalid" type validatePromoCodeRequest struct { Code string `json:"code"` Amount int `json:"amount"` } type validatePromoCodeResponse struct { Valid bool `json:"valid"` Reason string `json:"reason"` PromoCodeId int `json:"promo_code_id"` BonusAmount int `json:"bonus_amount"` Code string `json:"code"` } func ValidatePromoCode(c *gin.Context) { var req validatePromoCodeRequest if err := c.ShouldBindJSON(&req); err != nil { common.ApiError(c, err) return } code := normalizePromoCode(req.Code) if !isPromoCodeSyntaxValid(code) { common.ApiSuccess(c, newInvalidPromoCodeResponse(code)) return } promoCode, err := model.GetPromoCodeByCode(code) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { common.ApiSuccess(c, newInvalidPromoCodeResponse(code)) return } common.ApiError(c, err) return } if promoCode.Status != 1 { common.ApiSuccess(c, newInvalidPromoCodeResponse(code)) return } if promoCode.ExpiresAt != nil && promoCode.ExpiresAt.Before(time.Now()) { common.ApiSuccess(c, newInvalidPromoCodeResponse(code)) return } if promoCode.MaxUses > 0 && promoCode.UsedCount >= promoCode.MaxUses { common.ApiSuccess(c, newInvalidPromoCodeResponse(code)) return } if req.Amount < promoCode.MinRechargeAmount { common.ApiSuccess(c, newInvalidPromoCodeResponse(code)) return } userId := c.GetInt("id") if _, err := model.GetPromoCodeUsageByCodeAndUser(promoCode.Id, userId); err == nil { common.ApiSuccess(c, newInvalidPromoCodeResponse(code)) return } else if !errors.Is(err, gorm.ErrRecordNotFound) { common.ApiError(c, err) return } common.ApiSuccess(c, validatePromoCodeResponse{ Valid: true, Reason: "", PromoCodeId: promoCode.Id, BonusAmount: promoCode.BonusAmount, Code: promoCode.Code, }) } func newInvalidPromoCodeResponse(code string) validatePromoCodeResponse { return validatePromoCodeResponse{ Valid: false, Reason: invalidPromoCodeReason, Code: code, } }