package invoices import ( "fmt" "time" "github.com/google/uuid" "github.com/shopspring/decimal" "go.uber.org/zap" "rmser/internal/domain/invoices" "rmser/internal/infrastructure/rms" "rmser/pkg/logger" ) type Service struct { rmsClient rms.ClientI // Здесь можно добавить репозитории каталога и контрагентов для валидации, // но для краткости пока опустим глубокую валидацию. } func NewService(rmsClient rms.ClientI) *Service { return &Service{ rmsClient: rmsClient, } } // CreateRequestDTO - структура входящего JSON запроса от фронта/OCR type CreateRequestDTO struct { DocumentNumber string `json:"document_number"` DateIncoming string `json:"date_incoming"` // YYYY-MM-DD SupplierID uuid.UUID `json:"supplier_id"` StoreID uuid.UUID `json:"store_id"` Items []struct { ProductID uuid.UUID `json:"product_id"` Amount decimal.Decimal `json:"amount"` Price decimal.Decimal `json:"price"` } `json:"items"` } // SendInvoiceToRMS валидирует DTO, собирает доменную модель и отправляет в RMS func (s *Service) SendInvoiceToRMS(req CreateRequestDTO) (string, error) { // 1. Базовая валидация if len(req.Items) == 0 { return "", fmt.Errorf("список товаров пуст") } dateInc, err := time.Parse("2006-01-02", req.DateIncoming) if err != nil { return "", fmt.Errorf("неверный формат даты (ожидается YYYY-MM-DD): %v", err) } // 2. Сборка доменной модели inv := invoices.Invoice{ ID: uuid.Nil, // Новый документ DocumentNumber: req.DocumentNumber, DateIncoming: dateInc, SupplierID: req.SupplierID, DefaultStoreID: req.StoreID, Status: "NEW", Items: make([]invoices.InvoiceItem, 0, len(req.Items)), } for _, itemDTO := range req.Items { sum := itemDTO.Amount.Mul(itemDTO.Price) // Пересчитываем сумму inv.Items = append(inv.Items, invoices.InvoiceItem{ ProductID: itemDTO.ProductID, Amount: itemDTO.Amount, Price: itemDTO.Price, Sum: sum, }) } // 3. Отправка через клиент logger.Log.Info("Отправка накладной в RMS", zap.String("supplier", req.SupplierID.String()), zap.Int("items_count", len(inv.Items))) docNum, err := s.rmsClient.CreateIncomingInvoice(inv) if err != nil { return "", err } return docNum, nil }