package controller import ( "net/http" "strconv" "users_management/m/middleware" "users_management/m/model/dto/req" "users_management/m/usecase" "users_management/m/utils/common" "github.com/gin-gonic/gin" "github.com/google/uuid" ) type DeviceInspectionController struct { inspectionUC usecase.DeviceInspectionUseCase rg *gin.RouterGroup } func NewDeviceInspectionController(inspectionUC usecase.DeviceInspectionUseCase, rg *gin.RouterGroup) *DeviceInspectionController { return &DeviceInspectionController{ inspectionUC: inspectionUC, rg: rg, } } func (c *DeviceInspectionController) Route() { inspections := c.rg.Group("/device-inspections") { // Teknisi can create and read their own inspections inspections.POST("", middleware.RequireAnyRole("Teknisi", "Admin", "Superadmin"), c.createInspection) inspections.GET("/my-inspections", middleware.RequireAnyRole("Teknisi", "Admin", "Superadmin"), c.getMyInspections) // Admin and Superadmin can see all inspections inspections.GET("", middleware.RequireAdminRole(), c.getAllInspections) inspections.GET("/:id", middleware.RequireAnyRole("Teknisi", "Admin", "Superadmin"), c.getInspectionByID) // Update inspections - teknisi can update their own, admin can update any inspections.PUT("/:id", middleware.RequireAnyRole("Teknisi", "Admin", "Superadmin"), c.updateInspection) // Only admin can approve inspections inspections.PATCH("/:id/approve", middleware.RequireAdminRole(), c.approveInspection) } } func (c *DeviceInspectionController) createInspection(ctx *gin.Context) { userID, exists := ctx.Get("userID") if !exists { common.ErrorResponses(ctx, http.StatusUnauthorized, "User ID not found") return } uid, ok := userID.(uuid.UUID) if !ok { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid user ID") return } var inspectionDTO req.DeviceInspectionDTO if err := ctx.ShouldBindJSON(&inspectionDTO); err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } err := c.inspectionUC.CreateInspection(uid, inspectionDTO) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } common.SingleResponses(ctx, "Device inspection created successfully", nil) } func (c *DeviceInspectionController) getAllInspections(ctx *gin.Context) { page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10")) if page < 1 { page = 1 } if limit < 1 || limit > 100 { limit = 10 } inspections, total, err := c.inspectionUC.GetAllInspections(page, limit) if err != nil { common.ErrorResponses(ctx, http.StatusInternalServerError, err.Error()) return } response := gin.H{ "inspections": inspections, "total": total, "page": page, "limit": limit, "total_pages": (total + int64(limit) - 1) / int64(limit), } common.SingleResponses(ctx, "All inspections retrieved successfully", response) } func (c *DeviceInspectionController) getMyInspections(ctx *gin.Context) { userID, exists := ctx.Get("userID") if !exists { common.ErrorResponses(ctx, http.StatusUnauthorized, "User ID not found") return } uid, ok := userID.(uuid.UUID) if !ok { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid user ID") return } page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "10")) if page < 1 { page = 1 } if limit < 1 || limit > 100 { limit = 10 } inspections, total, err := c.inspectionUC.GetUserInspections(uid, page, limit) if err != nil { common.ErrorResponses(ctx, http.StatusInternalServerError, err.Error()) return } response := gin.H{ "inspections": inspections, "total": total, "page": page, "limit": limit, "total_pages": (total + int64(limit) - 1) / int64(limit), } common.SingleResponses(ctx, "User inspections retrieved successfully", response) } func (c *DeviceInspectionController) getInspectionByID(ctx *gin.Context) { id := ctx.Param("id") inspectionID, err := uuid.Parse(id) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid inspection ID") return } userID, exists := ctx.Get("userID") if !exists { common.ErrorResponses(ctx, http.StatusUnauthorized, "User ID not found") return } uid, ok := userID.(uuid.UUID) if !ok { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid user ID") return } userRole, exists := ctx.Get("userRole") if !exists { common.ErrorResponses(ctx, http.StatusUnauthorized, "User role not found") return } role, ok := userRole.(string) if !ok { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid user role") return } // Get the inspection first inspection, err := c.inspectionUC.GetInspectionByID(inspectionID) if err != nil { common.ErrorResponses(ctx, http.StatusNotFound, err.Error()) return } // For teknisi, check if they own this inspection if role == "Teknisi" { isOwner, err := c.inspectionUC.CheckInspectionOwnership(inspectionID, uid) if err != nil { common.ErrorResponses(ctx, http.StatusInternalServerError, "Error checking inspection ownership") return } if !isOwner { common.ErrorResponses(ctx, http.StatusForbidden, "Unauthorized: you can only view your own inspections") return } } common.SingleResponses(ctx, "Inspection retrieved successfully", inspection) } func (c *DeviceInspectionController) updateInspection(ctx *gin.Context) { id := ctx.Param("id") inspectionID, err := uuid.Parse(id) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid inspection ID") return } userID, exists := ctx.Get("userID") if !exists { common.ErrorResponses(ctx, http.StatusUnauthorized, "User ID not found") return } uid, ok := userID.(uuid.UUID) if !ok { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid user ID") return } userRole, _ := ctx.Get("userRole") role, _ := userRole.(string) var inspectionDTO req.UpdateDeviceInspectionDTO if err := ctx.ShouldBindJSON(&inspectionDTO); err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } err = c.inspectionUC.UpdateInspection(inspectionID, uid, inspectionDTO, role) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } common.SingleResponses(ctx, "Inspection updated successfully", nil) } func (c *DeviceInspectionController) approveInspection(ctx *gin.Context) { id := ctx.Param("id") inspectionID, err := uuid.Parse(id) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, "Invalid inspection ID") return } var approvalDTO req.ApproveInspectionDTO if err := ctx.ShouldBindJSON(&approvalDTO); err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } err = c.inspectionUC.ApproveInspection(inspectionID, approvalDTO) if err != nil { common.ErrorResponses(ctx, http.StatusBadRequest, err.Error()) return } common.SingleResponses(ctx, "Inspection approval updated successfully", nil) }