package catalog import ( "rmser/internal/domain/catalog" "github.com/google/uuid" "gorm.io/gorm" "gorm.io/gorm/clause" ) type pgRepository struct { db *gorm.DB } func NewRepository(db *gorm.DB) catalog.Repository { return &pgRepository{db: db} } func (r *pgRepository) SaveProducts(products []catalog.Product) error { // Сортировка (родители -> дети) sorted := sortProductsByHierarchy(products) return r.db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, UpdateAll: true, }).CreateInBatches(sorted, 100).Error } func (r *pgRepository) GetAll() ([]catalog.Product, error) { var products []catalog.Product err := r.db.Find(&products).Error return products, err } // Вспомогательная функция сортировки func sortProductsByHierarchy(products []catalog.Product) []catalog.Product { if len(products) == 0 { return products } childrenMap := make(map[uuid.UUID][]catalog.Product) var roots []catalog.Product allIDs := make(map[uuid.UUID]struct{}, len(products)) for _, p := range products { allIDs[p.ID] = struct{}{} } for _, p := range products { if p.ParentID == nil { roots = append(roots, p) } else { if _, exists := allIDs[*p.ParentID]; exists { childrenMap[*p.ParentID] = append(childrenMap[*p.ParentID], p) } else { roots = append(roots, p) } } } result := make([]catalog.Product, 0, len(products)) queue := roots for len(queue) > 0 { current := queue[0] queue = queue[1:] result = append(result, current) if children, ok := childrenMap[current.ID]; ok { queue = append(queue, children...) delete(childrenMap, current.ID) } } for _, remaining := range childrenMap { result = append(result, remaining...) } return result } // GetActiveGoods возвращает только активные товары (не удаленные, тип GOODS) func (r *pgRepository) GetActiveGoods() ([]catalog.Product, error) { var products []catalog.Product // iikoRMS: GOODS - товары, PREPARED - заготовки (иногда их тоже покупают) err := r.db.Where("is_deleted = ? AND type IN ?", false, []string{"GOODS"}). Order("name ASC"). Find(&products).Error return products, err }