package handlers import ( "fmt" "net/http" "time" "github.com/gin-gonic/gin" "git.mchus.pro/mchus/quoteforge/internal/middleware" "git.mchus.pro/mchus/quoteforge/internal/services" ) type ExportHandler struct { exportService *services.ExportService configService services.ConfigurationGetter componentService *services.ComponentService } func NewExportHandler( exportService *services.ExportService, configService services.ConfigurationGetter, componentService *services.ComponentService, ) *ExportHandler { return &ExportHandler{ exportService: exportService, configService: configService, componentService: componentService, } } type ExportRequest struct { Name string `json:"name" binding:"required"` Items []struct { LotName string `json:"lot_name" binding:"required"` Quantity int `json:"quantity" binding:"required,min=1"` UnitPrice float64 `json:"unit_price"` } `json:"items" binding:"required,min=1"` Notes string `json:"notes"` } func (h *ExportHandler) ExportCSV(c *gin.Context) { var req ExportRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } data := h.buildExportData(&req) csvData, err := h.exportService.ToCSV(data) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } filename := fmt.Sprintf("%s %s SPEC.csv", time.Now().Format("2006-01-02"), req.Name) c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename)) c.Data(http.StatusOK, "text/csv; charset=utf-8", csvData) } func (h *ExportHandler) buildExportData(req *ExportRequest) *services.ExportData { items := make([]services.ExportItem, len(req.Items)) var total float64 for i, item := range req.Items { itemTotal := item.UnitPrice * float64(item.Quantity) // Получаем информацию о компоненте для заполнения категории и описания componentView, err := h.componentService.GetByLotName(item.LotName) if err != nil { // Если не удалось получить информацию о компоненте, используем только основные данные items[i] = services.ExportItem{ LotName: item.LotName, Quantity: item.Quantity, UnitPrice: item.UnitPrice, TotalPrice: itemTotal, } } else { items[i] = services.ExportItem{ LotName: item.LotName, Description: componentView.Description, Category: componentView.Category, Quantity: item.Quantity, UnitPrice: item.UnitPrice, TotalPrice: itemTotal, } } total += itemTotal } return &services.ExportData{ Name: req.Name, Items: items, Total: total, Notes: req.Notes, CreatedAt: time.Now(), } } func (h *ExportHandler) ExportConfigCSV(c *gin.Context) { userID := middleware.GetUserID(c) uuid := c.Param("uuid") config, err := h.configService.GetByUUID(uuid, userID) if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) return } data := h.exportService.ConfigToExportData(config, h.componentService) csvData, err := h.exportService.ToCSV(data) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } filename := fmt.Sprintf("%s %s SPEC.csv", config.CreatedAt.Format("2006-01-02"), config.Name) c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename)) c.Data(http.StatusOK, "text/csv; charset=utf-8", csvData) }