package handler import ( "apskel-pos-be/internal/constants" "apskel-pos-be/internal/contract" "apskel-pos-be/internal/logger" "apskel-pos-be/internal/service" "apskel-pos-be/internal/util" "apskel-pos-be/internal/validator" "strconv" "github.com/gin-gonic/gin" ) type VoucherHandler struct { voucherService service.VoucherService voucherValidator validator.VoucherValidator } func NewVoucherHandler( voucherService service.VoucherService, voucherValidator validator.VoucherValidator, ) *VoucherHandler { return &VoucherHandler{ voucherService: voucherService, voucherValidator: voucherValidator, } } func (h *VoucherHandler) GetRandomVouchersForSpin(c *gin.Context) { ctx := c.Request.Context() req := &contract.ListVouchersForSpinRequest{ Limit: 10, // Default limit } // Parse query parameters if limitStr := c.Query("limit"); limitStr != "" { if limit, err := strconv.Atoi(limitStr); err == nil { req.Limit = limit } } validationError, validationErrorCode := h.voucherValidator.ValidateListVouchersForSpinRequest(req) if validationError != nil { logger.FromContext(ctx).WithError(validationError).Error("VoucherHandler::GetRandomVouchersForSpin -> request validation failed") validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "VoucherHandler::GetRandomVouchersForSpin") return } vouchersResponse, err := h.voucherService.GetRandomVouchersForSpin(c.Request.Context(), req) if err != nil { logger.FromContext(ctx).WithError(err).Error("VoucherHandler::GetRandomVouchersForSpin -> Failed to get random vouchers from service") errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "VoucherHandler::GetRandomVouchersForSpin") return } logger.FromContext(ctx).Infof("VoucherHandler::GetRandomVouchersForSpin -> Successfully retrieved %d vouchers for spin", vouchersResponse.Count) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(vouchersResponse), "VoucherHandler::GetRandomVouchersForSpin") } func (h *VoucherHandler) GetRandomVouchersByRows(c *gin.Context) { ctx := c.Request.Context() req := &contract.ListVouchersByRowsRequest{ Rows: 4, // Default 4 rows } // Parse query parameters if rowsStr := c.Query("rows"); rowsStr != "" { if rows, err := strconv.Atoi(rowsStr); err == nil { req.Rows = rows } } // Parse winner_number parameter (optional) if winnerNumberStr := c.Query("winner_number"); winnerNumberStr != "" { if wn, err := strconv.Atoi(winnerNumberStr); err == nil { req.WinnerNumber = &wn } } validationError, validationErrorCode := h.voucherValidator.ValidateListVouchersByRowsRequest(req) if validationError != nil { logger.FromContext(ctx).WithError(validationError).Error("VoucherHandler::GetRandomVouchersByRows -> request validation failed") validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "VoucherHandler::GetRandomVouchersByRows") return } vouchersResponse, err := h.voucherService.GetRandomVouchersByRows(c.Request.Context(), req) if err != nil { logger.FromContext(ctx).WithError(err).Error("VoucherHandler::GetRandomVouchersByRows -> Failed to get random vouchers by rows from service") errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "VoucherHandler::GetRandomVouchersByRows") return } logger.FromContext(ctx).Infof("VoucherHandler::GetRandomVouchersByRows -> Successfully retrieved %d rows with %d total vouchers", vouchersResponse.TotalRows, vouchersResponse.TotalVouchers) util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(vouchersResponse), "VoucherHandler::GetRandomVouchersByRows") } func (h *VoucherHandler) GetVoucherByID(c *gin.Context) { ctx := c.Request.Context() voucherID, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { logger.FromContext(ctx).WithError(err).Error("VoucherHandler::GetVoucherByID -> Invalid voucher ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid voucher ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "VoucherHandler::GetVoucherByID") return } voucherResponse, err := h.voucherService.GetVoucherByID(c.Request.Context(), voucherID) if err != nil { logger.FromContext(ctx).WithError(err).Error("VoucherHandler::GetVoucherByID -> Failed to get voucher from service") errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "VoucherHandler::GetVoucherByID") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(voucherResponse), "VoucherHandler::GetVoucherByID") } func (h *VoucherHandler) GetVoucherByCode(c *gin.Context) { ctx := c.Request.Context() voucherCode := c.Param("code") if voucherCode == "" { logger.FromContext(ctx).Error("VoucherHandler::GetVoucherByCode -> Missing voucher code") validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, "Voucher code is required") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "VoucherHandler::GetVoucherByCode") return } voucherResponse, err := h.voucherService.GetVoucherByCode(c.Request.Context(), voucherCode) if err != nil { logger.FromContext(ctx).WithError(err).Error("VoucherHandler::GetVoucherByCode -> Failed to get voucher from service") errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "VoucherHandler::GetVoucherByCode") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(voucherResponse), "VoucherHandler::GetVoucherByCode") } func (h *VoucherHandler) ListVouchers(c *gin.Context) { ctx := c.Request.Context() page := 1 limit := 10 // Parse query parameters if pageStr := c.Query("page"); pageStr != "" { if p, err := strconv.Atoi(pageStr); err == nil && p > 0 { page = p } } if limitStr := c.Query("limit"); limitStr != "" { if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 { limit = l } } vouchersResponse, err := h.voucherService.ListVouchers(c.Request.Context(), page, limit) if err != nil { logger.FromContext(ctx).WithError(err).Error("VoucherHandler::ListVouchers -> Failed to list vouchers from service") errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{errorResp}), "VoucherHandler::ListVouchers") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(vouchersResponse), "VoucherHandler::ListVouchers") }