MIF_E31222379_BE/internal/trash/trash_handler.go

522 lines
16 KiB
Go

package trash
import (
"rijig/utils"
"strconv"
"strings"
"github.com/gofiber/fiber/v2"
)
type TrashHandler struct {
trashService TrashServiceInterface
}
func NewTrashHandler(trashService TrashServiceInterface) *TrashHandler {
return &TrashHandler{
trashService: trashService,
}
}
func (h *TrashHandler) CreateTrashCategory(c *fiber.Ctx) error {
var req RequestTrashCategoryDTO
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
response, err := h.trashService.CreateTrashCategory(c.Context(), req)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
return utils.InternalServerError(c, "Failed to create trash category")
}
return utils.CreateSuccessWithData(c, "Trash category created successfully", response)
}
func (h *TrashHandler) CreateTrashCategoryWithIcon(c *fiber.Ctx) error {
var req RequestTrashCategoryDTO
req.Name = c.FormValue("name")
req.Variety = c.FormValue("variety")
if estimatedPriceStr := c.FormValue("estimated_price"); estimatedPriceStr != "" {
if price, err := strconv.ParseFloat(estimatedPriceStr, 64); err == nil {
req.EstimatedPrice = price
}
}
iconFile, err := c.FormFile("icon")
if err != nil && err.Error() != "there is no uploaded file associated with the given key" {
return utils.BadRequest(c, "Invalid icon file")
}
response, err := h.trashService.CreateTrashCategoryWithIcon(c.Context(), req, iconFile)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "invalid file type") {
return utils.BadRequest(c, err.Error())
}
return utils.InternalServerError(c, "Failed to create trash category")
}
return utils.CreateSuccessWithData(c, "Trash category created successfully", response)
}
func (h *TrashHandler) CreateTrashCategoryWithDetails(c *fiber.Ctx) error {
var req struct {
Category RequestTrashCategoryDTO `json:"category"`
Details []RequestTrashDetailDTO `json:"details"`
}
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
response, err := h.trashService.CreateTrashCategoryWithDetails(c.Context(), req.Category, req.Details)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
return utils.InternalServerError(c, "Failed to create trash category with details")
}
return utils.CreateSuccessWithData(c, "Trash category with details created successfully", response)
}
func (h *TrashHandler) UpdateTrashCategory(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Category ID is required")
}
var req RequestTrashCategoryDTO
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
response, err := h.trashService.UpdateTrashCategory(c.Context(), id, req)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
return utils.InternalServerError(c, "Failed to update trash category")
}
return utils.SuccessWithData(c, "Trash category updated successfully", response)
}
func (h *TrashHandler) UpdateTrashCategoryWithIcon(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Category ID is required")
}
var req RequestTrashCategoryDTO
req.Name = c.FormValue("name")
req.Variety = c.FormValue("variety")
if estimatedPriceStr := c.FormValue("estimated_price"); estimatedPriceStr != "" {
if price, err := strconv.ParseFloat(estimatedPriceStr, 64); err == nil {
req.EstimatedPrice = price
}
}
iconFile, _ := c.FormFile("icon")
response, err := h.trashService.UpdateTrashCategoryWithIcon(c.Context(), id, req, iconFile)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
if strings.Contains(err.Error(), "invalid file type") {
return utils.BadRequest(c, err.Error())
}
return utils.InternalServerError(c, "Failed to update trash category")
}
return utils.SuccessWithData(c, "Trash category updated successfully", response)
}
func (h *TrashHandler) GetAllTrashCategories(c *fiber.Ctx) error {
withDetails := c.Query("with_details", "false")
if withDetails == "true" {
response, err := h.trashService.GetAllTrashCategoriesWithDetails(c.Context())
if err != nil {
return utils.InternalServerError(c, "Failed to get trash categories")
}
return utils.SuccessWithData(c, "Trash categories retrieved successfully", response)
}
response, err := h.trashService.GetAllTrashCategories(c.Context())
if err != nil {
return utils.InternalServerError(c, "Failed to get trash categories")
}
return utils.SuccessWithData(c, "Trash categories retrieved successfully", response)
}
func (h *TrashHandler) GetTrashCategoryByID(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Category ID is required")
}
withDetails := c.Query("with_details", "false")
if withDetails == "true" {
response, err := h.trashService.GetTrashCategoryByIDWithDetails(c.Context(), id)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
return utils.InternalServerError(c, "Failed to get trash category")
}
return utils.SuccessWithData(c, "Trash category retrieved successfully", response)
}
response, err := h.trashService.GetTrashCategoryByID(c.Context(), id)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
return utils.InternalServerError(c, "Failed to get trash category")
}
return utils.SuccessWithData(c, "Trash category retrieved successfully", response)
}
func (h *TrashHandler) DeleteTrashCategory(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Category ID is required")
}
err := h.trashService.DeleteTrashCategory(c.Context(), id)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
return utils.InternalServerError(c, "Failed to delete trash category")
}
return utils.Success(c, "Trash category deleted successfully")
}
func (h *TrashHandler) CreateTrashDetail(c *fiber.Ctx) error {
var req RequestTrashDetailDTO
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
response, err := h.trashService.CreateTrashDetail(c.Context(), req)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
return utils.InternalServerError(c, "Failed to create trash detail")
}
return utils.CreateSuccessWithData(c, "Trash detail created successfully", response)
}
func (h *TrashHandler) CreateTrashDetailWithIcon(c *fiber.Ctx) error {
var req RequestTrashDetailDTO
req.CategoryID = c.FormValue("category_id")
req.Description = c.FormValue("description")
if stepOrderStr := c.FormValue("step_order"); stepOrderStr != "" {
if stepOrder, err := strconv.Atoi(stepOrderStr); err == nil {
req.StepOrder = stepOrder
}
}
iconFile, err := c.FormFile("icon")
if err != nil && err.Error() != "there is no uploaded file associated with the given key" {
return utils.BadRequest(c, "Invalid icon file")
}
response, err := h.trashService.CreateTrashDetailWithIcon(c.Context(), req, iconFile)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "invalid file type") {
return utils.BadRequest(c, err.Error())
}
return utils.InternalServerError(c, "Failed to create trash detail")
}
return utils.CreateSuccessWithData(c, "Trash detail created successfully", response)
}
func (h *TrashHandler) AddTrashDetailToCategory(c *fiber.Ctx) error {
categoryID := c.Params("categoryId")
if categoryID == "" {
return utils.BadRequest(c, "Category ID is required")
}
var req RequestTrashDetailDTO
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
response, err := h.trashService.AddTrashDetailToCategory(c.Context(), categoryID, req)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
return utils.InternalServerError(c, "Failed to add trash detail to category")
}
return utils.CreateSuccessWithData(c, "Trash detail added to category successfully", response)
}
func (h *TrashHandler) AddTrashDetailToCategoryWithIcon(c *fiber.Ctx) error {
categoryID := c.Params("categoryId")
if categoryID == "" {
return utils.BadRequest(c, "Category ID is required")
}
var req RequestTrashDetailDTO
req.Description = c.FormValue("description")
if stepOrderStr := c.FormValue("step_order"); stepOrderStr != "" {
if stepOrder, err := strconv.Atoi(stepOrderStr); err == nil {
req.StepOrder = stepOrder
}
}
iconFile, err := c.FormFile("icon")
if err != nil && err.Error() != "there is no uploaded file associated with the given key" {
return utils.BadRequest(c, "Invalid icon file")
}
response, err := h.trashService.AddTrashDetailToCategoryWithIcon(c.Context(), categoryID, req, iconFile)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "invalid file type") {
return utils.BadRequest(c, err.Error())
}
return utils.InternalServerError(c, "Failed to add trash detail to category")
}
return utils.CreateSuccessWithData(c, "Trash detail added to category successfully", response)
}
func (h *TrashHandler) UpdateTrashDetail(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Detail ID is required")
}
var req RequestTrashDetailDTO
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
response, err := h.trashService.UpdateTrashDetail(c.Context(), id, req)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash detail not found")
}
return utils.InternalServerError(c, "Failed to update trash detail")
}
return utils.SuccessWithData(c, "Trash detail updated successfully", response)
}
func (h *TrashHandler) UpdateTrashDetailWithIcon(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Detail ID is required")
}
var req RequestTrashDetailDTO
req.Description = c.FormValue("description")
if stepOrderStr := c.FormValue("step_order"); stepOrderStr != "" {
if stepOrder, err := strconv.Atoi(stepOrderStr); err == nil {
req.StepOrder = stepOrder
}
}
iconFile, _ := c.FormFile("icon")
response, err := h.trashService.UpdateTrashDetailWithIcon(c.Context(), id, req, iconFile)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash detail not found")
}
if strings.Contains(err.Error(), "invalid file type") {
return utils.BadRequest(c, err.Error())
}
return utils.InternalServerError(c, "Failed to update trash detail")
}
return utils.SuccessWithData(c, "Trash detail updated successfully", response)
}
func (h *TrashHandler) GetTrashDetailsByCategory(c *fiber.Ctx) error {
categoryID := c.Params("categoryId")
if categoryID == "" {
return utils.BadRequest(c, "Category ID is required")
}
response, err := h.trashService.GetTrashDetailsByCategory(c.Context(), categoryID)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
return utils.InternalServerError(c, "Failed to get trash details")
}
return utils.SuccessWithData(c, "Trash details retrieved successfully", response)
}
func (h *TrashHandler) GetTrashDetailByID(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Detail ID is required")
}
response, err := h.trashService.GetTrashDetailByID(c.Context(), id)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash detail not found")
}
return utils.InternalServerError(c, "Failed to get trash detail")
}
return utils.SuccessWithData(c, "Trash detail retrieved successfully", response)
}
func (h *TrashHandler) DeleteTrashDetail(c *fiber.Ctx) error {
id := c.Params("id")
if id == "" {
return utils.BadRequest(c, "Detail ID is required")
}
err := h.trashService.DeleteTrashDetail(c.Context(), id)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash detail not found")
}
return utils.InternalServerError(c, "Failed to delete trash detail")
}
return utils.Success(c, "Trash detail deleted successfully")
}
func (h *TrashHandler) BulkCreateTrashDetails(c *fiber.Ctx) error {
categoryID := c.Params("categoryId")
if categoryID == "" {
return utils.BadRequest(c, "Category ID is required")
}
var req struct {
Details []RequestTrashDetailDTO `json:"details"`
}
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
if len(req.Details) == 0 {
return utils.BadRequest(c, "At least one detail is required")
}
response, err := h.trashService.BulkCreateTrashDetails(c.Context(), categoryID, req.Details)
if err != nil {
if strings.Contains(err.Error(), "validation failed") {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", extractValidationErrors(err.Error()))
}
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
return utils.InternalServerError(c, "Failed to bulk create trash details")
}
return utils.CreateSuccessWithData(c, "Trash details created successfully", response)
}
func (h *TrashHandler) BulkDeleteTrashDetails(c *fiber.Ctx) error {
var req struct {
DetailIDs []string `json:"detail_ids"`
}
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
if len(req.DetailIDs) == 0 {
return utils.BadRequest(c, "At least one detail ID is required")
}
err := h.trashService.BulkDeleteTrashDetails(c.Context(), req.DetailIDs)
if err != nil {
return utils.InternalServerError(c, "Failed to bulk delete trash details")
}
return utils.Success(c, "Trash details deleted successfully")
}
func (h *TrashHandler) ReorderTrashDetails(c *fiber.Ctx) error {
categoryID := c.Params("categoryId")
if categoryID == "" {
return utils.BadRequest(c, "Category ID is required")
}
var req struct {
OrderedDetailIDs []string `json:"ordered_detail_ids"`
}
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request body")
}
if len(req.OrderedDetailIDs) == 0 {
return utils.BadRequest(c, "At least one detail ID is required")
}
err := h.trashService.ReorderTrashDetails(c.Context(), categoryID, req.OrderedDetailIDs)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Trash category not found")
}
return utils.InternalServerError(c, "Failed to reorder trash details")
}
return utils.Success(c, "Trash details reordered successfully")
}
func extractValidationErrors(errMsg string) interface{} {
if strings.Contains(errMsg, "validation failed:") {
return strings.TrimSpace(strings.Split(errMsg, "validation failed:")[1])
}
return errMsg
}