package recommend import ( "github.com/google/uuid" "go.uber.org/zap" "rmser/internal/domain/recommendations" "rmser/pkg/logger" ) const ( AnalyzeDaysNoIncoming = 90 // Ищем ингредиенты без закупок за 30 дней AnalyzeDaysStale = 90 // Ищем неликвид за 60 дней ) type Service struct { repo recommendations.Repository } func NewService(repo recommendations.Repository) *Service { return &Service{repo: repo} } // RefreshRecommendations выполняет анализ и сохраняет результаты в БД для конкретного сервера func (s *Service) RefreshRecommendations(serverID uuid.UUID) error { logger.Log.Info("Запуск пересчета рекомендаций...", zap.String("server_id", serverID.String())) var all []recommendations.Recommendation // 1. Unused if unused, err := s.repo.FindUnusedGoods(serverID); err == nil { all = append(all, unused...) } else { logger.Log.Error("Ошибка unused", zap.Error(err)) } // 2. Purchased but Unused if purchUnused, err := s.repo.FindPurchasedButUnused(serverID, AnalyzeDaysNoIncoming); err == nil { all = append(all, purchUnused...) } else { logger.Log.Error("Ошибка purchased_unused", zap.Error(err)) } // 3. No Incoming (Ингредиенты без закупок) if noInc, err := s.repo.FindNoIncomingIngredients(serverID, AnalyzeDaysNoIncoming); err == nil { all = append(all, noInc...) } else { logger.Log.Error("Ошибка no_incoming", zap.Error(err)) } // 4. Usage without Purchase (Расход без прихода) if usageNoPurch, err := s.repo.FindUsageWithoutPurchase(serverID, AnalyzeDaysNoIncoming); err == nil { all = append(all, usageNoPurch...) } else { logger.Log.Error("Ошибка usage_no_purchase", zap.Error(err)) } // 5. Stale (Неликвид) if stale, err := s.repo.FindStaleGoods(serverID, AnalyzeDaysStale); err == nil { all = append(all, stale...) } else { logger.Log.Error("Ошибка stale", zap.Error(err)) } // 6. Dish in Recipe if dishInRec, err := s.repo.FindDishesInRecipes(serverID); err == nil { all = append(all, dishInRec...) } else { logger.Log.Error("Ошибка dish_in_recipe", zap.Error(err)) } // Сохраняем if err := s.repo.SaveAll(serverID, all); err != nil { return err } logger.Log.Info("Рекомендации обновлены", zap.Int("total_count", len(all))) return nil } // GetRecommendations возвращает рекомендации для конкретного сервера func (s *Service) GetRecommendations(serverID uuid.UUID) ([]recommendations.Recommendation, error) { return s.repo.GetAll(serverID) }