MIF_E31222379_BE/internal/collector/collector_handler.go

361 lines
10 KiB
Go

package collector
import (
"rijig/middleware"
"rijig/utils"
"strconv"
"strings"
"github.com/gofiber/fiber/v2"
)
type CollectorHandler struct {
collectorService CollectorService
}
func NewCollectorHandler(collectorService CollectorService) *CollectorHandler {
return &CollectorHandler{
collectorService: collectorService,
}
}
func (h *CollectorHandler) CreateCollector(c *fiber.Ctx) error {
claims, err := middleware.GetUserFromContext(c)
if err != nil {
return err
}
var req CreateCollectorRequest
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request format")
}
errors, isValid := req.ValidateCreateCollectorRequest()
if !isValid {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", errors)
}
req.SetDefaults()
collector, err := h.collectorService.CreateCollector(c.Context(), &req, claims.UserID)
if err != nil {
if strings.Contains(err.Error(), "already exists") {
return utils.BadRequest(c, err.Error())
}
return utils.InternalServerError(c, "Failed to create collector")
}
return utils.CreateSuccessWithData(c, "Collector created successfully", collector)
}
func (h *CollectorHandler) GetCollectorByID(c *fiber.Ctx) error {
id := c.Params("id")
if strings.TrimSpace(id) == "" {
return utils.BadRequest(c, "Collector ID is required")
}
collector, err := h.collectorService.GetCollectorByID(c.Context(), id)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Collector not found")
}
return utils.InternalServerError(c, "Failed to get collector")
}
return utils.SuccessWithData(c, "Collector retrieved successfully", collector)
}
func (h *CollectorHandler) GetCollectorByUserID(c *fiber.Ctx) error {
// userID := c.Params("userID")
// if strings.TrimSpace(userID) == "" {
// return utils.BadRequest(c, "User ID is required")
// }
claims, err := middleware.GetUserFromContext(c)
if err != nil {
return err
}
collector, err := h.collectorService.GetCollectorByUserID(c.Context(), claims.UserID)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Collector not found for this user")
}
return utils.InternalServerError(c, "Failed to get collector")
}
return utils.SuccessWithData(c, "Collector retrieved successfully", collector)
}
func (h *CollectorHandler) UpdateCollector(c *fiber.Ctx) error {
/* id := c.Params("id")
if strings.TrimSpace(id) == "" {
return utils.BadRequest(c, "Collector ID is required")
} */
claims, err := middleware.GetUserFromContext(c)
if err != nil {
return err
}
var req UpdateCollectorRequest
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request format")
}
errors, isValid := req.ValidateUpdateCollectorRequest()
if !isValid {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", errors)
}
req.NormalizeJobStatus()
collector, err := h.collectorService.UpdateCollector(c.Context(), claims.UserID, &req)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Collector not found")
}
return utils.InternalServerError(c, "Failed to update collector")
}
return utils.SuccessWithData(c, "Collector updated successfully", collector)
}
func (h *CollectorHandler) DeleteCollector(c *fiber.Ctx) error {
claims, err := middleware.GetUserFromContext(c)
if err != nil {
return err
}
err = h.collectorService.DeleteCollector(c.Context(), claims.UserID)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Collector not found")
}
return utils.InternalServerError(c, "Failed to delete collector")
}
return utils.Success(c, "Collector deleted successfully")
}
func (h *CollectorHandler) ListCollectors(c *fiber.Ctx) error {
limit, offset, page := h.parsePaginationParams(c)
collectors, total, err := h.collectorService.ListCollectors(c.Context(), limit, offset)
if err != nil {
return utils.InternalServerError(c, "Failed to get collectors")
}
responseData := map[string]interface{}{
"collectors": collectors,
"total": total,
}
return utils.SuccessWithPagination(c, "Collectors retrieved successfully", responseData, page, limit)
}
func (h *CollectorHandler) GetActiveCollectors(c *fiber.Ctx) error {
limit, offset, page := h.parsePaginationParams(c)
collectors, total, err := h.collectorService.GetActiveCollectors(c.Context(), limit, offset)
if err != nil {
return utils.InternalServerError(c, "Failed to get active collectors")
}
responseData := map[string]interface{}{
"collectors": collectors,
"total": total,
}
return utils.SuccessWithPagination(c, "Active collectors retrieved successfully", responseData, page, limit)
}
func (h *CollectorHandler) GetCollectorsByAddress(c *fiber.Ctx) error {
addressID := c.Params("addressID")
if strings.TrimSpace(addressID) == "" {
return utils.BadRequest(c, "Address ID is required")
}
limit, offset, page := h.parsePaginationParams(c)
collectors, total, err := h.collectorService.GetCollectorsByAddress(c.Context(), addressID, limit, offset)
if err != nil {
return utils.InternalServerError(c, "Failed to get collectors by address")
}
responseData := map[string]interface{}{
"collectors": collectors,
"total": total,
"address_id": addressID,
}
return utils.SuccessWithPagination(c, "Collectors by address retrieved successfully", responseData, page, limit)
}
func (h *CollectorHandler) GetCollectorsByTrashCategory(c *fiber.Ctx) error {
trashCategoryID := c.Params("trashCategoryID")
if strings.TrimSpace(trashCategoryID) == "" {
return utils.BadRequest(c, "Trash category ID is required")
}
limit, offset, page := h.parsePaginationParams(c)
collectors, total, err := h.collectorService.GetCollectorsByTrashCategory(c.Context(), trashCategoryID, limit, offset)
if err != nil {
return utils.InternalServerError(c, "Failed to get collectors by trash category")
}
responseData := map[string]interface{}{
"collectors": collectors,
"total": total,
"trash_category_id": trashCategoryID,
}
return utils.SuccessWithPagination(c, "Collectors by trash category retrieved successfully", responseData, page, limit)
}
func (h *CollectorHandler) UpdateJobStatus(c *fiber.Ctx) error {
id := c.Params("id")
if strings.TrimSpace(id) == "" {
return utils.BadRequest(c, "Collector ID is required")
}
var req struct {
JobStatus string `json:"job_status" binding:"required"`
}
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request format")
}
if strings.TrimSpace(req.JobStatus) == "" {
return utils.BadRequest(c, "Job status is required")
}
jobStatus := strings.ToLower(strings.TrimSpace(req.JobStatus))
validStatuses := []string{"active", "inactive", "busy"}
if !h.isValidJobStatus(jobStatus, validStatuses) {
return utils.BadRequest(c, "Invalid job status. Valid statuses: active, inactive, busy")
}
err := h.collectorService.UpdateJobStatus(c.Context(), id, jobStatus)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Collector not found")
}
return utils.InternalServerError(c, "Failed to update job status")
}
return utils.Success(c, "Job status updated successfully")
}
func (h *CollectorHandler) UpdateRating(c *fiber.Ctx) error {
id := c.Params("id")
if strings.TrimSpace(id) == "" {
return utils.BadRequest(c, "Collector ID is required")
}
var req struct {
Rating float32 `json:"rating" binding:"required"`
}
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request format")
}
if req.Rating < 1.0 || req.Rating > 5.0 {
return utils.BadRequest(c, "Rating must be between 1.0 and 5.0")
}
err := h.collectorService.UpdateRating(c.Context(), id, req.Rating)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Collector not found")
}
return utils.InternalServerError(c, "Failed to update rating")
}
return utils.Success(c, "Rating updated successfully")
}
func (h *CollectorHandler) UpdateAvailableTrash(c *fiber.Ctx) error {
id := c.Params("id")
if strings.TrimSpace(id) == "" {
return utils.BadRequest(c, "Collector ID is required")
}
var req BulkUpdateAvailableTrashRequest
req.CollectorID = id
if err := c.BodyParser(&req); err != nil {
return utils.BadRequest(c, "Invalid request format")
}
errors, isValid := req.ValidateBulkUpdateAvailableTrashRequest()
if !isValid {
return utils.ResponseErrorData(c, fiber.StatusBadRequest, "Validation failed", errors)
}
err := h.collectorService.UpdateAvailableTrash(c.Context(), id, req.AvailableTrashItems)
if err != nil {
if strings.Contains(err.Error(), "not found") {
return utils.NotFound(c, "Collector not found")
}
return utils.InternalServerError(c, "Failed to update available trash")
}
return utils.Success(c, "Available trash updated successfully")
}
func (h *CollectorHandler) parsePaginationParams(c *fiber.Ctx) (limit, offset, page int) {
limitStr := c.Query("limit", "10")
limit, err := strconv.Atoi(limitStr)
if err != nil || limit <= 0 {
limit = 10
}
if limit > 100 {
limit = 100
}
pageStr := c.Query("page", "1")
page, err = strconv.Atoi(pageStr)
if err != nil || page <= 0 {
page = 1
}
offset = (page - 1) * limit
return limit, offset, page
}
func (h *CollectorHandler) isValidJobStatus(status string, validStatuses []string) bool {
for _, validStatus := range validStatuses {
if status == validStatus {
return true
}
}
return false
}
func (h *CollectorHandler) RegisterRoutes(app *fiber.App) {
collectors := app.Group("/api/v1/collectors")
collectors.Post("/", h.CreateCollector)
collectors.Get("/:id", h.GetCollectorByID)
collectors.Put("/:id", h.UpdateCollector)
collectors.Delete("/:id", h.DeleteCollector)
collectors.Get("/", h.ListCollectors)
collectors.Get("/active", h.GetActiveCollectors)
collectors.Get("/user/:userID", h.GetCollectorByUserID)
collectors.Get("/address/:addressID", h.GetCollectorsByAddress)
collectors.Get("/trash-category/:trashCategoryID", h.GetCollectorsByTrashCategory)
collectors.Patch("/:id/job-status", h.UpdateJobStatus)
collectors.Patch("/:id/rating", h.UpdateRating)
collectors.Put("/:id/available-trash", h.UpdateAvailableTrash)
}