quzuu-api-test / controllers /event_controller.go
lifedebugger's picture
Deploy files from GitHub repository
56e28b7
package controllers
import (
"errors"
"net/http"
"strconv"
"time"
"abdanhafidz.com/go-boilerplate/models/dto"
entity "abdanhafidz.com/go-boilerplate/models/entity"
http_error "abdanhafidz.com/go-boilerplate/models/error"
"abdanhafidz.com/go-boilerplate/services"
"abdanhafidz.com/go-boilerplate/utils"
"github.com/gin-gonic/gin"
)
type EventController interface {
List(ctx *gin.Context)
DetailBySlug(ctx *gin.Context)
Join(ctx *gin.Context)
}
type eventController struct {
eventService services.EventService
}
func NewEventController(eventService services.EventService) EventController {
return &eventController{eventService: eventService}
}
// Event List godoc
// @Summary List Events
// @Description Retrieve a paginated list of events with optional filters
// @Tags Event
// @Accept json
// @Produce json
// @Param limit query int false "Number of items per page" default(10)
// @Param page query int false "Page number" default(1)
// @Param search query string false "Search term for event titles"
// @Param sortBy query string false "Field to sort by (e.g., 'date', 'title')"
// @Param order query string false "Sort order ('asc' or 'desc')"
// @Param registerStatus query int false "Filter by registration status"
// @Param status query string false "Filter by event status (upcoming, ongoing, ended)"
// @Success 200 {object} dto.SuccessResponse[[]entity.Events]
// @Failure 400 {object} dto.ErrorResponse
// @Router /api/v1/events [get]
func (c *eventController) List(ctx *gin.Context) {
limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10"))
page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
search := ctx.DefaultQuery("search", "")
sortBy := ctx.DefaultQuery("sortBy", "")
order := ctx.DefaultQuery("order", "")
var registerStatus *int
if val := ctx.Query("registerStatus"); val != "" {
if i, err := strconv.Atoi(val); err == nil {
registerStatus = &i
}
}
var status *string
if val := ctx.Query("status"); val != "" {
if val == entity.EventStatusUpcoming || val == entity.EventStatusOngoing || val == entity.EventStatusEnded {
status = &val
}
}
if limit < 1 {
limit = 10
} else if limit > 50 {
limit = 50
}
if page < 1 {
page = 1
}
offset := (page - 1) * limit
p := entity.Pagination{Limit: limit, Offset: offset, Search: search, SortBy: sortBy, Order: order, RegisterStatus: registerStatus, Status: status}
accountId := ParseAccountId(ctx)
list, total, err := c.eventService.List(ctx.Request.Context(), accountId, p)
var totalPages int
if total == 0 {
totalPages = 1
} else {
totalPages = int((total + int64(limit) - 1) / int64(limit))
}
if page > totalPages {
page = totalPages
offset = (page - 1) * limit
p.Offset = offset
list, total, err = c.eventService.List(ctx.Request.Context(), accountId, p)
}
meta := gin.H{
"totalItems": total,
"totalPages": totalPages,
"currentPage": page,
}
ResponseJSON(ctx, meta, list, err)
}
// Event Detail By Slug godoc
// @Summary Get Event Detail by Slug
// @Description Retrieve detailed information about a specific event using its slug
// @Tags Event
// @Accept json
// @Produce json
// @Param event_slug path string true "Event Slug"
// @Success 200 {object} dto.SuccessResponse[dto.EventDetailResponse]
// @Failure 400 {object} dto.ErrorResponse
// @Router /api/v1/events/{event_slug} [get]
func (c *eventController) DetailBySlug(ctx *gin.Context) {
slug := ctx.Param("event_slug")
accountId := ParseAccountId(ctx)
res, err := c.eventService.DetailBySlug(ctx.Request.Context(), slug, accountId)
ResponseJSON(ctx, gin.H{"event_slug": slug, "id_account": accountId}, res, err)
}
// Join Event godoc
// @Summary Join Event
// @Description Register the authenticated user for an event using an event code
// @Tags Event
// @Accept json
// @Produce json
// @Param request body dto.JoinEventRequest true "Join Event Request"
// @Success 200 {object} dto.SuccessResponse[dto.EventDetailResponse]
// @Failure 400 {object} dto.ErrorResponse
// @Failure 402 {object} dto.RegisterEventPaymentActionRequiredResponse
// @Security BearerAuth
// @Router /api/v1/events/register-event [post]
func (c *eventController) Join(ctx *gin.Context) {
req := RequestJSON[dto.JoinEventRequest](ctx)
if err := utils.ValidateCode(req.EventCode); err != nil {
ResponseJSON(ctx, req, gin.H{}, err)
return
}
accountId := ParseAccountId(ctx)
res, err := c.eventService.JoinByCode(ctx.Request.Context(), accountId, req.EventCode)
if errors.Is(err, http_error.PAYMENT_REQUIRED) {
ctx.JSON(http.StatusPaymentRequired, dto.RegisterEventPaymentActionRequiredResponse{
Data: dto.RegisterEventPaymentActionRequiredData{
AccountID: res.EventPayment.AccountId.String(),
Amount: res.EventPayment.Amount,
EventID: res.EventPayment.EventId.String(),
ExpiredAt: res.EventPayment.ExpiredAt.Format(time.RFC3339),
ID: res.EventPayment.Id.String(),
InvoiceID: res.EventPayment.InvoiceId,
InvoiceURL: res.EventPayment.InvoiceUrl,
Status: res.EventPayment.Status,
TransactionAt: res.EventPayment.TransactionAt.Format(time.RFC3339),
MayarTransactionID: res.EventPayment.ExternalId,
},
Message: http_error.PAYMENT_REQUIRED.Error(),
MetaData: req.EventCode,
Status: "action_required",
})
return
}
ResponseJSON(ctx, req, res, err)
}