package services import ( "net/http" "strconv" "time" "wm-backend/global" "wm-backend/internal/models" "wm-backend/internal/models/requests" "wm-backend/internal/models/responses" "wm-backend/internal/repositories" "wm-backend/pkg/helper" "wm-backend/response" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" ) // RoomCreate creates a new room. // It validates the request body and creates the room in the database. // // @Summary Create a new room // @Description Create a new room with the provided details // @Tags room // @Accept json // @Produce json // @Param body body requests.CreateRoomRequest true "Room request body" // @Success 201 {object} response.SuccessResponse{data=responses.CreateRoomResponse} // @Failure 400 {object} response.ErrorResponse // @Failure 500 {object} response.ErrorResponse // @Router /v1/rooms [post] func RoomCreate(c *gin.Context) error { requestBody := requests.CreateRoomRequest{} if helper.IsShouldBindJSON(c, &requestBody) { return nil } roomModel := &models.Room{ WarehouseID: requestBody.WarehouseID, Name: requestBody.Name, Description: requestBody.Description, CreatedAt: time.Now(), } room, err := repositories.CreateRoom(c.Request.Context(), global.Queries, *roomModel) if err != nil { log.Error().Err(err).Msg("Failed to create room") response.InternalServerError(c, http.StatusInternalServerError, "Failed to create room") return nil } response.Created(c, "Room created successfully", &responses.CreateRoomResponse{ ID: room.ID, }) return nil } // RoomGetByID retrieves a single room by its ID. // // @Summary Get room by ID // @Description Retrieve a single room using its unique identifier // @Tags room // @Accept json // @Produce json // @Param id path int true "Room ID" // @Success 200 {object} response.SuccessResponse{data=models.Room} // @Failure 400 {object} response.ErrorResponse // @Failure 404 {object} response.ErrorResponse // @Failure 500 {object} response.ErrorResponse // @Router /v1/rooms/{id} [get] func RoomGetByID(c *gin.Context) error { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { response.BadRequestError(c, http.StatusBadRequest, "Invalid ID") return nil } room, err := repositories.GetRoomByID(c.Request.Context(), global.Queries, id) if err != nil { log.Error().Err(err).Msgf("Failed to get room by ID: %d", id) response.NotFoundError(c, http.StatusNotFound, "Room not found") return nil } response.Ok(c, "Success", room) return nil } // RoomList retrieves all rooms. // // @Summary List all rooms // @Description Retrieve a list of all rooms ordered by creation date // @Tags room // @Accept json // @Produce json // @Success 200 {object} response.SuccessResponse{data=[]models.Room} // @Failure 500 {object} response.ErrorResponse // @Router /v1/rooms [get] func RoomList(c *gin.Context) error { rooms, err := repositories.ListRooms(c.Request.Context(), global.Queries) if err != nil { response.InternalServerError(c, http.StatusInternalServerError, "Failed to list rooms") return nil } response.Ok(c, "Success", rooms) return nil } // RoomUpdate updates an existing room by its ID. // It validates the request body, fetches the existing record, // merges non-empty fields from the request, and updates the room in the database. // // @Summary Update room // @Description Update an existing room by its ID. Only non-empty fields will be updated. // @Tags room // @Accept json // @Produce json // @Param id path int true "Room ID" // @Param body body requests.UpdateRoomRequest true "Room request body" // @Success 200 {object} response.SuccessResponse{data=responses.UpdateRoomResponse} // @Failure 400 {object} response.ErrorResponse // @Failure 404 {object} response.ErrorResponse // @Failure 500 {object} response.ErrorResponse // @Router /v1/rooms/{id} [put] func RoomUpdate(c *gin.Context) error { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { response.BadRequestError(c, http.StatusBadRequest, "Invalid ID") return nil } requestBody := requests.UpdateRoomRequest{} if helper.IsShouldBindJSON(c, &requestBody) { return nil } existing, err := repositories.GetRoomByID(c.Request.Context(), global.Queries, id) if err != nil { response.NotFoundError(c, http.StatusNotFound, "Room not found") return nil } if requestBody.Name != "" { existing.Name = requestBody.Name } if requestBody.Description != "" { existing.Description = requestBody.Description } existing.UpdatedAt = time.Now() room, err := repositories.UpdateRoom(c.Request.Context(), global.Queries, existing) if err != nil { log.Error().Err(err).Msgf("Failed to update room with ID: %d", id) response.InternalServerError(c, http.StatusInternalServerError, "Failed to update room") return nil } response.Ok(c, "Room updated successfully", &responses.UpdateRoomResponse{ ID: room.ID, WarehouseID: room.WarehouseID, Name: room.Name, Description: room.Description, }) return nil } // RoomDelete deletes a room by its ID. // // @Summary Delete room // @Description Delete a room by its unique identifier // @Tags room // @Accept json // @Produce json // @Param id path int true "Room ID" // @Success 200 {object} response.SuccessResponse // @Failure 400 {object} response.ErrorResponse // @Failure 500 {object} response.ErrorResponse // @Router /v1/rooms/{id} [delete] func RoomDelete(c *gin.Context) error { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { response.BadRequestError(c, http.StatusBadRequest, "Invalid ID") return nil } err = repositories.DeleteRoom(c.Request.Context(), global.Queries, id) if err != nil { log.Error().Err(err).Msgf("Failed to delete room with ID: %d", id) response.InternalServerError(c, http.StatusInternalServerError, "Failed to delete room") return nil } response.Ok(c, "Đã xóa thành công", nil) return nil }