package handler import ( "apskel-pos-be/internal/appcontext" "apskel-pos-be/internal/constants" "apskel-pos-be/internal/contract" "apskel-pos-be/internal/logger" "apskel-pos-be/internal/models" "apskel-pos-be/internal/util" "strconv" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type UnitHandler struct { unitService UnitService } func NewUnitHandler(unitService UnitService) *UnitHandler { return &UnitHandler{ unitService: unitService, } } func (h *UnitHandler) Create(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) var request models.CreateUnitRequest if err := c.ShouldBindJSON(&request); err != nil { logger.FromContext(c.Request.Context()).WithError(err).Error("UnitHandler::Create -> request binding failed") validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::Create") return } request.OrganizationID = contextInfo.OrganizationID unitResponse, err := h.unitService.CreateUnit(ctx, &request) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::Create -> Failed to create unit from service") validationResponseError := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::Create") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(unitResponse), "UnitHandler::Create") } func (h *UnitHandler) GetByID(c *gin.Context) { ctx := c.Request.Context() idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::GetByID -> Invalid unit ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid unit ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::GetByID") return } unitResponse, err := h.unitService.GetUnitByID(ctx, id) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::GetByID -> Failed to get unit from service") validationResponseError := contract.NewResponseError(constants.NotFoundErrorCode, constants.RequestEntity, "Unit not found") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::GetByID") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(unitResponse), "UnitHandler::GetByID") } func (h *UnitHandler) GetAll(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) pageStr := c.DefaultQuery("page", "1") limitStr := c.DefaultQuery("limit", "10") search := c.Query("search") outletIDStr := c.Query("outlet_id") page, err := strconv.Atoi(pageStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::GetAll -> Invalid page parameter") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid page parameter") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::GetAll") return } limit, err := strconv.Atoi(limitStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::GetAll -> Invalid limit parameter") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid limit parameter") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::GetAll") return } var outletID *uuid.UUID if outletIDStr != "" { parsedOutletID, err := uuid.Parse(outletIDStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::GetAll -> Invalid outlet ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid outlet ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::GetAll") return } outletID = &parsedOutletID } unitResponse, err := h.unitService.ListUnits(ctx, contextInfo.OrganizationID, outletID, page, limit, search) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::GetAll -> Failed to get units from service") validationResponseError := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, "Failed to get units") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::GetAll") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(unitResponse), "UnitHandler::GetAll") } // UpdateUnit godoc // @Summary Update unit // @Description Update an existing unit // @Tags units // @Accept json // @Produce json // @Param id path string true "Unit ID" // @Param request body models.UpdateUnitRequest true "Update unit request" // @Success 200 {object} contract.Response{data=models.UnitResponse} // @Failure 400 {object} contract.Response // @Failure 404 {object} contract.Response // @Failure 500 {object} contract.Response // @Router /units/{id} [put] func (h *UnitHandler) Update(c *gin.Context) { ctx := c.Request.Context() idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::Update -> Invalid unit ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid unit ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::Update") return } var request models.UpdateUnitRequest if err := c.ShouldBindJSON(&request); err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::Update -> request binding failed") validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, "Invalid request body") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::Update") return } unitResponse, err := h.unitService.UpdateUnit(ctx, id, &request) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::Update -> Failed to update unit from service") validationResponseError := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::Update") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(unitResponse), "UnitHandler::Update") } // DeleteUnit godoc // @Summary Delete unit // @Description Delete a unit by its ID // @Tags units // @Produce json // @Param id path string true "Unit ID" // @Success 200 {object} contract.Response // @Failure 404 {object} contract.Response // @Failure 500 {object} contract.Response // @Router /units/{id} [delete] func (h *UnitHandler) Delete(c *gin.Context) { ctx := c.Request.Context() idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::Delete -> Invalid unit ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid unit ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::Delete") return } err = h.unitService.DeleteUnit(ctx, id) if err != nil { logger.FromContext(ctx).WithError(err).Error("UnitHandler::Delete -> Failed to delete unit from service") validationResponseError := contract.NewResponseError(constants.InternalServerErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "UnitHandler::Delete") return } util.HandleResponse(c.Writer, c.Request, contract.BuildSuccessResponse(map[string]interface{}{ "message": "Unit deleted successfully", }), "UnitHandler::Delete") }