package handlers import ( "net/http" "time" "github.com/gin-gonic/gin" "github.com/google/uuid" "github.com/shopspring/decimal" "go.uber.org/zap" "rmser/internal/services/drafts" "rmser/pkg/logger" ) type DraftsHandler struct { service *drafts.Service } func NewDraftsHandler(service *drafts.Service) *DraftsHandler { return &DraftsHandler{service: service} } // GetDraft возвращает полные данные черновика func (h *DraftsHandler) GetDraft(c *gin.Context) { idStr := c.Param("id") id, err := uuid.Parse(idStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"}) return } draft, err := h.service.GetDraft(id) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "draft not found"}) return } c.JSON(http.StatusOK, draft) } // GetStores возвращает список складов func (h *DraftsHandler) GetStores(c *gin.Context) { stores, err := h.service.GetActiveStores() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, stores) } // UpdateItemDTO - тело запроса на изменение строки type UpdateItemDTO struct { ProductID *string `json:"product_id"` ContainerID *string `json:"container_id"` Quantity float64 `json:"quantity"` Price float64 `json:"price"` } func (h *DraftsHandler) UpdateItem(c *gin.Context) { draftID, _ := uuid.Parse(c.Param("id")) itemID, _ := uuid.Parse(c.Param("itemId")) var req UpdateItemDTO if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var pID *uuid.UUID if req.ProductID != nil && *req.ProductID != "" { if uid, err := uuid.Parse(*req.ProductID); err == nil { pID = &uid } } var cID *uuid.UUID if req.ContainerID != nil && *req.ContainerID != "" { if uid, err := uuid.Parse(*req.ContainerID); err == nil { cID = &uid } } qty := decimal.NewFromFloat(req.Quantity) price := decimal.NewFromFloat(req.Price) if err := h.service.UpdateItem(draftID, itemID, pID, cID, qty, price); err != nil { logger.Log.Error("Failed to update item", zap.Error(err)) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"status": "updated"}) } type CommitRequestDTO struct { DateIncoming string `json:"date_incoming"` // YYYY-MM-DD StoreID string `json:"store_id"` SupplierID string `json:"supplier_id"` Comment string `json:"comment"` } // CommitDraft сохраняет шапку и отправляет в RMS func (h *DraftsHandler) CommitDraft(c *gin.Context) { draftID, err := uuid.Parse(c.Param("id")) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid draft id"}) return } var req CommitRequestDTO if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Парсинг данных шапки date, err := time.Parse("2006-01-02", req.DateIncoming) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid date format (YYYY-MM-DD)"}) return } storeID, err := uuid.Parse(req.StoreID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid store id"}) return } supplierID, err := uuid.Parse(req.SupplierID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid supplier id"}) return } // 1. Обновляем шапку if err := h.service.UpdateDraftHeader(draftID, &storeID, &supplierID, date, req.Comment); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to update header: " + err.Error()}) return } // 2. Отправляем docNum, err := h.service.CommitDraft(draftID) if err != nil { logger.Log.Error("Commit failed", zap.Error(err)) c.JSON(http.StatusBadGateway, gin.H{"error": "RMS error: " + err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "status": "completed", "document_number": docNum, }) }