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/util" "apskel-pos-be/internal/validator" "strconv" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type TableHandler struct { tableService TableService tableValidator *validator.TableValidator } func NewTableHandler(tableService TableService, tableValidator *validator.TableValidator) *TableHandler { return &TableHandler{ tableService: tableService, tableValidator: tableValidator, } } func (h *TableHandler) Create(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) var req contract.CreateTableRequest if err := c.ShouldBindJSON(&req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::Create -> request binding failed") validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::Create") return } if err := h.tableValidator.ValidateCreateTableRequest(req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::Create -> validation failed") validationResponseError := contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::Create") return } response := h.tableService.CreateTable(ctx, contextInfo, &req) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::Create -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::Create") } func (h *TableHandler) GetByID(c *gin.Context) { ctx := c.Request.Context() id := c.Param("id") tableID, err := uuid.Parse(id) if err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::GetByID -> Invalid table ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid table ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::GetByID") return } response := h.tableService.GetTableByID(ctx, tableID) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::GetByID -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::GetByID") } func (h *TableHandler) Update(c *gin.Context) { ctx := c.Request.Context() id := c.Param("id") tableID, err := uuid.Parse(id) if err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::Update -> Invalid table ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid table ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::Update") return } var req contract.UpdateTableRequest if err := c.ShouldBindJSON(&req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::Update -> request binding failed") validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::Update") return } if err := h.tableValidator.ValidateUpdateTableRequest(req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::Update -> validation failed") validationResponseError := contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::Update") return } response := h.tableService.UpdateTable(ctx, tableID, &req) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::Update -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::Update") } func (h *TableHandler) Delete(c *gin.Context) { ctx := c.Request.Context() id := c.Param("id") tableID, err := uuid.Parse(id) if err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::Delete -> Invalid table ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid table ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::Delete") return } response := h.tableService.DeleteTable(ctx, tableID) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::Delete -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::Delete") } func (h *TableHandler) List(c *gin.Context) { ctx := c.Request.Context() contextInfo := appcontext.FromGinContext(ctx) query := contract.ListTablesQuery{ OrganizationID: contextInfo.OrganizationID.String(), OutletID: c.Query("outlet_id"), Status: c.Query("status"), IsActive: c.Query("is_active"), Search: c.Query("search"), Page: 1, Limit: 100, } if pageStr := c.Query("page"); pageStr != "" { if page, err := strconv.Atoi(pageStr); err == nil && page > 0 { query.Page = page } } if limitStr := c.Query("limit"); limitStr != "" { if limit, err := strconv.Atoi(limitStr); err == nil && limit > 0 && limit <= 100 { query.Limit = limit } } if err := h.tableValidator.ValidateListTablesQuery(query); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::List -> validation failed") validationResponseError := contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::List") return } response := h.tableService.ListTables(ctx, &query) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::List -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::List") } func (h *TableHandler) OccupyTable(c *gin.Context) { ctx := c.Request.Context() id := c.Param("id") tableID, err := uuid.Parse(id) if err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::OccupyTable -> Invalid table ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid table ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::OccupyTable") return } var req contract.OccupyTableRequest if err := c.ShouldBindJSON(&req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::OccupyTable -> request binding failed") validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::OccupyTable") return } if err := h.tableValidator.ValidateOccupyTableRequest(req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::OccupyTable -> validation failed") validationResponseError := contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::OccupyTable") return } response := h.tableService.OccupyTable(ctx, tableID, &req) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::OccupyTable -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::OccupyTable") } func (h *TableHandler) ReleaseTable(c *gin.Context) { ctx := c.Request.Context() id := c.Param("id") tableID, err := uuid.Parse(id) if err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::ReleaseTable -> Invalid table ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid table ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::ReleaseTable") return } var req contract.ReleaseTableRequest if err := c.ShouldBindJSON(&req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::ReleaseTable -> request binding failed") validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::ReleaseTable") return } if err := h.tableValidator.ValidateReleaseTableRequest(req); err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::ReleaseTable -> validation failed") validationResponseError := contract.NewResponseError(constants.ValidationErrorCode, constants.RequestEntity, err.Error()) util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::ReleaseTable") return } response := h.tableService.ReleaseTable(ctx, tableID, &req) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::ReleaseTable -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::ReleaseTable") } func (h *TableHandler) GetAvailableTables(c *gin.Context) { ctx := c.Request.Context() outletIDStr := c.Param("outlet_id") outletID, err := uuid.Parse(outletIDStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::GetAvailableTables -> Invalid outlet ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid outlet ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::GetAvailableTables") return } response := h.tableService.GetAvailableTables(ctx, outletID) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::GetAvailableTables -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::GetAvailableTables") } func (h *TableHandler) GetOccupiedTables(c *gin.Context) { ctx := c.Request.Context() outletIDStr := c.Param("outlet_id") outletID, err := uuid.Parse(outletIDStr) if err != nil { logger.FromContext(ctx).WithError(err).Error("TableHandler::GetOccupiedTables -> Invalid outlet ID") validationResponseError := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.RequestEntity, "Invalid outlet ID") util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "TableHandler::GetOccupiedTables") return } response := h.tableService.GetOccupiedTables(ctx, outletID) if response.HasErrors() { errorResp := response.GetErrors()[0] logger.FromContext(ctx).WithError(errorResp).Error("TableHandler::GetOccupiedTables -> service failed") } util.HandleResponse(c.Writer, c.Request, response, "TableHandler::GetOccupiedTables") }