package handlers import ( "net/http" "erp-mvp/core-service/internal/api/middleware" "erp-mvp/core-service/internal/models" "erp-mvp/core-service/internal/service" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" "github.com/google/uuid" ) type OperationsHandler struct { operationsService service.OperationsService validate *validator.Validate } func NewOperationsHandler(operationsService service.OperationsService) *OperationsHandler { return &OperationsHandler{ operationsService: operationsService, validate: validator.New(), } } // PlaceItem размещает товар в месте хранения func (h *OperationsHandler) PlaceItem(c *gin.Context) { claims := middleware.GetClaims(c) if claims == nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } var req models.PlaceItemRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) return } if err := h.validate.Struct(req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Validation failed", "details": err.Error()}) return } placement, err := h.operationsService.PlaceItem(c.Request.Context(), claims.OrganizationID, &req) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to place item"}) return } c.JSON(http.StatusCreated, placement) } // MoveItem перемещает товар в другое место хранения func (h *OperationsHandler) MoveItem(c *gin.Context) { claims := middleware.GetClaims(c) if claims == nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } placementIDStr := c.Param("id") placementID, err := uuid.Parse(placementIDStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid placement ID"}) return } var req struct { NewLocationID uuid.UUID `json:"new_location_id" validate:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) return } if err := h.validate.Struct(req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Validation failed", "details": err.Error()}) return } if err := h.operationsService.MoveItem(c.Request.Context(), placementID, req.NewLocationID, claims.OrganizationID); err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Placement not found"}) return } c.JSON(http.StatusOK, gin.H{"message": "Item moved successfully"}) } // GetItemPlacements получает все размещения товара func (h *OperationsHandler) GetItemPlacements(c *gin.Context) { claims := middleware.GetClaims(c) if claims == nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } itemIDStr := c.Param("item_id") itemID, err := uuid.Parse(itemIDStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid item ID"}) return } placements, err := h.operationsService.GetItemPlacements(c.Request.Context(), itemID, claims.OrganizationID) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Item not found"}) return } c.JSON(http.StatusOK, placements) } // GetLocationPlacements получает все товары в месте хранения func (h *OperationsHandler) GetLocationPlacements(c *gin.Context) { claims := middleware.GetClaims(c) if claims == nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } locationIDStr := c.Param("location_id") locationID, err := uuid.Parse(locationIDStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid location ID"}) return } placements, err := h.operationsService.GetLocationPlacements(c.Request.Context(), locationID, claims.OrganizationID) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Location not found"}) return } c.JSON(http.StatusOK, placements) } // UpdateQuantity обновляет количество товара в размещении func (h *OperationsHandler) UpdateQuantity(c *gin.Context) { claims := middleware.GetClaims(c) if claims == nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } placementIDStr := c.Param("id") placementID, err := uuid.Parse(placementIDStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid placement ID"}) return } var req struct { Quantity int `json:"quantity" validate:"required,min=1"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body"}) return } if err := h.validate.Struct(req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Validation failed", "details": err.Error()}) return } if err := h.operationsService.UpdateQuantity(c.Request.Context(), placementID, req.Quantity, claims.OrganizationID); err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Placement not found"}) return } c.JSON(http.StatusOK, gin.H{"message": "Quantity updated successfully"}) } // DeletePlacement удаляет размещение товара func (h *OperationsHandler) DeletePlacement(c *gin.Context) { claims := middleware.GetClaims(c) if claims == nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } placementIDStr := c.Param("id") placementID, err := uuid.Parse(placementIDStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid placement ID"}) return } if err := h.operationsService.DeletePlacement(c.Request.Context(), placementID, claims.OrganizationID); err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Placement not found"}) return } c.JSON(http.StatusNoContent, nil) } // Search выполняет поиск товаров с местами размещения func (h *OperationsHandler) Search(c *gin.Context) { claims := middleware.GetClaims(c) if claims == nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) return } var req models.SearchRequest if err := c.ShouldBindQuery(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid query parameters"}) return } // Устанавливаем значения по умолчанию if req.Page <= 0 { req.Page = 1 } if req.PageSize <= 0 { req.PageSize = 20 } response, err := h.operationsService.Search(c.Request.Context(), claims.OrganizationID, &req) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to search"}) return } c.JSON(http.StatusOK, response) }