Перевел на multi-tenant

Добавил поставщиков
Накладные успешно создаются из фронта
This commit is contained in:
2025-12-18 03:56:21 +03:00
parent 47ec8094e5
commit 542beafe0e
38 changed files with 1942 additions and 977 deletions

View File

@@ -9,38 +9,45 @@ import (
"github.com/shopspring/decimal"
)
// ProductMatch связывает текст из чека с конкретным товаром в iiko
// ProductMatch
type ProductMatch struct {
RawName string `gorm:"type:varchar(255);primary_key" json:"raw_name"`
// RawName больше не PrimaryKey, так как в разных серверах один текст может значить разное
// Делаем составной ключ или суррогатный ID.
// Для простоты GORM: ID - uuid, а уникальность через индекс (RawName + ServerID)
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
RMSServerID uuid.UUID `gorm:"type:uuid;not null;index:idx_raw_server,unique"`
RawName string `gorm:"type:varchar(255);not null;index:idx_raw_server,unique" json:"raw_name"`
ProductID uuid.UUID `gorm:"type:uuid;not null;index" json:"product_id"`
Product catalog.Product `gorm:"foreignKey:ProductID" json:"product"`
// Количество и фасовки
Quantity decimal.Decimal `gorm:"type:numeric(19,4);default:1" json:"quantity"`
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:1" json:"quantity"`
ContainerID *uuid.UUID `gorm:"type:uuid;index" json:"container_id"`
Container *catalog.ProductContainer `gorm:"foreignKey:ContainerID" json:"container,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
CreatedAt time.Time `json:"created_at"`
}
// UnmatchedItem хранит строки, которые не удалось распознать, для подсказок
// UnmatchedItem тоже стоит делить, чтобы подсказывать пользователю только его нераспознанные,
// хотя глобальная база unmatched может быть полезна для аналитики.
// Сделаем раздельной для чистоты SaaS.
type UnmatchedItem struct {
RawName string `gorm:"type:varchar(255);primary_key" json:"raw_name"`
Count int `gorm:"default:1" json:"count"` // Сколько раз встречалось
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()"`
RMSServerID uuid.UUID `gorm:"type:uuid;not null;index:idx_unm_raw_server,unique"`
RawName string `gorm:"type:varchar(255);not null;index:idx_unm_raw_server,unique" json:"raw_name"`
Count int `gorm:"default:1" json:"count"`
LastSeen time.Time `json:"last_seen"`
}
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)
SaveMatch(serverID uuid.UUID, rawName string, productID uuid.UUID, quantity decimal.Decimal, containerID *uuid.UUID) error
DeleteMatch(serverID uuid.UUID, rawName string) error
FindMatch(serverID uuid.UUID, rawName string) (*ProductMatch, error)
GetAllMatches(serverID uuid.UUID) ([]ProductMatch, error)
UpsertUnmatched(rawName string) error
GetTopUnmatched(limit int) ([]UnmatchedItem, error)
DeleteUnmatched(rawName string) error
UpsertUnmatched(serverID uuid.UUID, rawName string) error
GetTopUnmatched(serverID uuid.UUID, limit int) ([]UnmatchedItem, error)
DeleteUnmatched(serverID uuid.UUID, rawName string) error
}