package site import ( "enaklo-pos-be/internal/common/errors" "enaklo-pos-be/internal/entity" "enaklo-pos-be/internal/handlers/request" "enaklo-pos-be/internal/handlers/response" "enaklo-pos-be/internal/services" "net/http" "strconv" "time" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" ) type Handler struct { service services.Site } func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { route := group.Group("/site") route.POST("/", jwt, h.Create) route.GET("/list", jwt, h.GetAll) route.PUT("/:id", jwt, h.Update) route.GET("/:id", jwt, h.GetByID) route.DELETE("/:id", jwt, h.Delete) route.GET("/count", jwt, h.Count) } func NewHandler(service services.Site) *Handler { return &Handler{ service: service, } } // Create handles the creation of a new Site. // @Summary Create a new Site // @Description Create a new Site based on the provided data. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param req body request.Site true "New Site details" // @Success 200 {object} response.BaseResponse{data=response.Site} "Site created successfully" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/site [post] // @Tags Site APIs func (h *Handler) Create(c *gin.Context) { ctx := request.GetMyContext(c) var req request.Site if err := c.ShouldBindJSON(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } if !ctx.IsAdmin() { req.PartnerID = ctx.GetPartnerID() } validate := validator.New() if err := validate.Struct(req); err != nil { response.ErrorWrapper(c, err) return } res, err := h.service.Create(ctx, req.ToEntity(ctx.RequestedBy())) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toSiteResponse(res), }) } // Update handles the update of an existing Site. // @Summary Update an existing Site // @Description Update the details of an existing Site based on the provided ID. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param id path int64 true "Site ID to update" // @Param req body request.Site true "Updated Site details" // @Success 200 {object} response.BaseResponse{data=response.Site} "Site updated successfully" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/site/{id} [put] // @Tags Site APIs func (h *Handler) Update(c *gin.Context) { ctx := request.GetMyContext(c) id := c.Param("id") SiteID, err := strconv.ParseInt(id, 10, 64) if err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } var req request.Site if err := c.ShouldBindJSON(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } validate := validator.New() if err := validate.Struct(req); err != nil { response.ErrorWrapper(c, err) return } updatedSite, err := h.service.Update(ctx, SiteID, req.ToEntity(ctx.RequestedBy())) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toSiteResponse(updatedSite), }) } // GetAll retrieves a list of Sites. // @Summary Get a list of Sites // @Description Get a paginated list of Sites based on query parameters. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param Limit query int false "Number of items to retrieve (default 10)" // @Param Offset query int false "Offset for pagination (default 0)" // @Success 200 {object} response.BaseResponse{data=response.SiteList} "List of Sites" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/site/list [get] // @Tags Site APIs func (h *Handler) GetAll(c *gin.Context) { var req request.SiteParam if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } ctx := request.GetMyContext(c) Sites, total, err := h.service.GetAll(c.Request.Context(), req.ToEntity(ctx, ctx.GetPartnerID(), ctx.GetSiteID())) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toSiteResponseList(Sites, int64(total), req), }) } // Delete handles the deletion of a Site by ID. // @Summary Delete a Site by ID // @Description Delete a Site based on the provided ID. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param id path int64 true "Site ID to delete" // @Success 200 {object} response.BaseResponse "Site deleted successfully" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/site/{id} [delete] // @Tags Site APIs func (h *Handler) Delete(c *gin.Context) { ctx := request.GetMyContext(c) id := c.Param("id") // Parse the ID into a uint SiteID, err := strconv.ParseInt(id, 10, 64) if err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } err = h.service.Delete(ctx, SiteID) if err != nil { c.JSON(http.StatusInternalServerError, response.BaseResponse{ Success: false, Status: http.StatusInternalServerError, Message: err.Error(), Data: nil, }) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: nil, }) } // GetByID retrieves details of a specific Site by ID. // @Summary Get details of a Site by ID // @Description Get details of a Site based on the provided ID. // @Accept json // @Produce json // @Param Authorization header string true "JWT token" // @Param id path int64 true "Site ID to retrieve" // @Success 200 {object} response.BaseResponse{data=response.Site} "Site details" // @Failure 400 {object} response.BaseResponse{data=errors.Error} "Bad request" // @Failure 401 {object} response.BaseResponse{data=errors.Error} "Unauthorized" // @Router /api/v1/site/{id} [get] // @Tags Site APIs func (h *Handler) GetByID(c *gin.Context) { id := c.Param("id") // Parse the ID into a uint SiteID, err := strconv.ParseInt(id, 10, 64) if err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } res, err := h.service.GetByID(c.Request.Context(), SiteID) if err != nil { c.JSON(http.StatusInternalServerError, response.BaseResponse{ Success: false, Status: http.StatusInternalServerError, Message: err.Error(), Data: nil, }) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: h.toSiteResponse(res), }) } func (h *Handler) Count(c *gin.Context) { var req request.SiteParam if err := c.ShouldBindQuery(&req); err != nil { response.ErrorWrapper(c, errors.ErrorBadRequest) return } ctx := request.GetMyContext(c) res, err := h.service.Count(ctx, req.ToEntity(ctx, ctx.GetPartnerID(), ctx.GetSiteID())) if err != nil { response.ErrorWrapper(c, err) return } c.JSON(http.StatusOK, response.BaseResponse{ Success: true, Status: http.StatusOK, Data: response.SiteCount{ Count: res.Count, }, }) } func (h *Handler) toSiteResponse(resp *entity.Site) response.Site { return response.Site{ ID: &resp.ID, Name: resp.Name, PartnerID: resp.PartnerID, Image: resp.Image, Address: resp.Address, LocationLink: resp.LocationLink, Description: resp.Description, Highlight: resp.Highlight, ContactPerson: resp.ContactPerson, TnC: resp.TnC, AdditionalInfo: resp.AdditionalInfo, Status: resp.Status, IsSeasonTicket: resp.IsSeasonTicket, IsDiscountActive: resp.IsDiscountActive, CreatedAt: resp.CreatedAt.Format(time.RFC3339), UpdatedAt: resp.UpdatedAt.Format(time.RFC3339), Products: h.toProductResponseList(resp.Products), Lat: *resp.Latitude, Long: *resp.Longitude, Region: resp.Region, Regency: resp.Regency, } } func (h *Handler) toSiteResponseList(resp []*entity.Site, total int64, req request.SiteParam) response.SiteList { sites := []response.Site{} for _, b := range resp { sites = append(sites, h.toSiteResponse(b)) } return response.SiteList{ Sites: sites, Total: total, Limit: req.Limit, Offset: req.Offset, } } func (h *Handler) toProductResponseList(products []entity.Product) []response.Product { var res []response.Product for _, product := range products { res = append(res, response.Product{ ID: product.ID, PartnerID: product.PartnerID, SiteID: product.SiteID, Name: product.Name, Type: product.Type, Price: product.Price, Status: product.Status, Description: product.Description, CreatedAt: product.CreatedAt.Format(time.RFC3339), UpdatedAt: product.UpdatedAt.Format(time.RFC3339), }) } return res }