Добавил черновики накладных и OCR через Яндекс. LLM для расшифровки универсальный

This commit is contained in:
2025-12-17 03:38:24 +03:00
parent fda30276a5
commit e2df2350f7
32 changed files with 1785 additions and 214 deletions

View File

@@ -55,4 +55,7 @@ type Repository interface {
SaveProducts(products []Product) error
GetAll() ([]Product, error)
GetActiveGoods() ([]Product, error)
// --- Stores ---
SaveStores(stores []Store) error
GetActiveStores() ([]Store, error)
}

View File

@@ -0,0 +1,18 @@
package catalog
import (
"time"
"github.com/google/uuid"
)
// Store - Склад (в терминологии iiko: Entity с типом Account и подтипом INVENTORY_ASSETS)
type Store struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;" json:"id"`
Name string `gorm:"type:varchar(255);not null" json:"name"`
ParentCorporateID uuid.UUID `gorm:"type:uuid;index" json:"parent_corporate_id"` // ID юр.лица/торгового предприятия
IsDeleted bool `gorm:"default:false" json:"is_deleted"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}

View File

@@ -0,0 +1,76 @@
package drafts
import (
"time"
"rmser/internal/domain/catalog"
"github.com/google/uuid"
"github.com/shopspring/decimal"
)
// Статусы черновика
const (
StatusProcessing = "PROCESSING" // OCR в процессе
StatusReadyToVerify = "READY_TO_VERIFY" // Распознано, ждет проверки пользователем
StatusCompleted = "COMPLETED" // Отправлено в RMS
StatusError = "ERROR" // Ошибка обработки
)
// DraftInvoice - Черновик накладной
type DraftInvoice struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
ChatID int64 `gorm:"index" json:"chat_id"` // ID чата в Telegram (кто прислал)
SenderPhotoURL string `gorm:"type:text" json:"photo_url"` // Ссылка на фото (если нужно отобразить на фронте)
Status string `gorm:"type:varchar(50);default:'PROCESSING'" json:"status"`
// Данные для отправки в RMS (заполняются пользователем)
DocumentNumber string `gorm:"type:varchar(100)" json:"document_number"`
DateIncoming *time.Time `json:"date_incoming"`
SupplierID *uuid.UUID `gorm:"type:uuid" json:"supplier_id"`
StoreID *uuid.UUID `gorm:"type:uuid" json:"store_id"`
Comment string `gorm:"type:text" json:"comment"`
// Связь с созданной накладной (когда статус COMPLETED)
RMSInvoiceID *uuid.UUID `gorm:"type:uuid" json:"rms_invoice_id"`
Items []DraftInvoiceItem `gorm:"foreignKey:DraftID;constraint:OnDelete:CASCADE" json:"items"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// DraftInvoiceItem - Позиция черновика
type DraftInvoiceItem struct {
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
DraftID uuid.UUID `gorm:"type:uuid;not null;index" json:"draft_id"`
// --- Результаты OCR (Исходные данные) ---
RawName string `gorm:"type:varchar(255);not null" json:"raw_name"` // Текст с чека
RawAmount decimal.Decimal `gorm:"type:numeric(19,4)" json:"raw_amount"` // Кол-во, которое увидел OCR
RawPrice decimal.Decimal `gorm:"type:numeric(19,4)" json:"raw_price"` // Цена, которую увидел OCR
// --- Результат Матчинга и Выбора пользователя ---
ProductID *uuid.UUID `gorm:"type:uuid;index" json:"product_id"`
Product *catalog.Product `gorm:"foreignKey:ProductID" json:"product,omitempty"`
ContainerID *uuid.UUID `gorm:"type:uuid;index" json:"container_id"`
Container *catalog.ProductContainer `gorm:"foreignKey:ContainerID" json:"container,omitempty"`
// Финальные цифры, которые пойдут в накладную
Quantity decimal.Decimal `gorm:"type:numeric(19,4);default:0" json:"quantity"`
Price decimal.Decimal `gorm:"type:numeric(19,4);default:0" json:"price"`
Sum decimal.Decimal `gorm:"type:numeric(19,4);default:0" json:"sum"`
IsMatched bool `gorm:"default:false" json:"is_matched"` // Удалось ли системе найти пару автоматически
}
// Repository интерфейс
type Repository interface {
Create(draft *DraftInvoice) error
GetByID(id uuid.UUID) (*DraftInvoice, error)
Update(draft *DraftInvoice) error
CreateItems(items []DraftInvoiceItem) error
// UpdateItem обновляет конкретную строку (например, при ручном выборе товара)
UpdateItem(itemID uuid.UUID, productID *uuid.UUID, containerID *uuid.UUID, qty, price decimal.Decimal) error
Delete(id uuid.UUID) error
}

View File

@@ -36,7 +36,7 @@ type UnmatchedItem struct {
type Repository interface {
// SaveMatch теперь принимает quantity и containerID
SaveMatch(rawName string, productID uuid.UUID, quantity decimal.Decimal, containerID *uuid.UUID) error
DeleteMatch(rawName string) error
FindMatch(rawName string) (*ProductMatch, error) // Возвращаем полную структуру, чтобы получить qty
GetAllMatches() ([]ProductMatch, error)