Files
rmser/internal/services/invoices/service.go
2025-11-29 08:40:24 +03:00

87 lines
2.6 KiB
Go

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
}