public async Task <DepartmentLoad> Generate(DepartmentLoadGenerateOptions options)
        {
            var model = options.departmentLoad;

            model.GroupDisciplineLoad.ForEach(o => o.StudyLoad.ForEach(sl => sl.UsersLoad.Clear()));
            await _generateStrategy.Generate(options, model);

            return(model);
        }
        ///<summary> Распределение коэффициентов по закрепленным дисициплинам для распределения нагрузки </summary>
        public async Task <DepartmentLoad> Generate(DepartmentLoadGenerateOptions options, DepartmentLoad model, List <GenerateRatio> generateRatios)
        {
            // Если не указан флаг использовать закрепленные дисциплины при распределении нагрузки
            if (!options.UsePinnedDisciplines.HasValue || !options.UsePinnedDisciplines.Value)
            {
                return(model);
            }

            var users = await _userService.Get(new UserGetOptions { DepartmentId = model.DepartmentId, OnlyWithPinnedDisciplines = true });

            var allPinnedDisciplines = users.SelectMany(u => u.PinnedDisciplines).ToList();

            var loads = model.GroupDisciplineLoad
                        .Where(o => allPinnedDisciplines.Any(pd => pd.DisciplineTitleId == o.DisciplineTitleId))
                        .Select(o => new KeyValuePair <int, List <StudyLoad> >(
                                    o.DisciplineTitleId,
                                    o.StudyLoad.Where(sl => allPinnedDisciplines.Any(pd => pd.ProjectType == sl.ProjectType)).ToList()
                                    )
                                )
                        .ToList();

            foreach (var load in loads)
            {
                var userPinnedDiscipline = users.Where(o => o.PinnedDisciplines.Any(o => o.DisciplineTitleId == load.Key));
                foreach (var studyLoad in load.Value)
                {
                    var generateRatio = generateRatios.FirstOrDefault(o => o.StudyLoadId == studyLoad.Id);
                    var ratios        = userPinnedDiscipline
                                        .Where(o => o.PinnedDisciplines.Any(pd => pd.ProjectType == studyLoad.ProjectType))
                                        .ToDictionary(o => o, o => ratioValue);

                    if (generateRatio == null)
                    {
                        generateRatios.Add(new GenerateRatio
                        {
                            StudyLoadId = studyLoad.Id,
                            Ratios      = ratios
                        });
                    }
                    else
                    {
                        foreach (var userRatio in ratios)
                        {
                            var existedUserRatio = generateRatio.Ratios.FirstOrDefault(o => o.Key.Id == userRatio.Key.Id);
                            if (existedUserRatio.Key != null)
                            {
                                existedUserRatio = new KeyValuePair <User, double>(existedUserRatio.Key, existedUserRatio.Value + ratioValue);
                            }
                            generateRatio.Ratios.Add(userRatio.Key, userRatio.Value);
                        }
                    }
                }
            }

            return(model);
        }
        ///<summary> Распределение коэффициентов по ученым степеням для распределения нагрузки </summary>
        public async Task <DepartmentLoad> Generate(DepartmentLoadGenerateOptions options, DepartmentLoad model, List <GenerateRatio> generateRatios)
        {
            // Если не указан флаг использовать закрепленные дисциплины при распределении нагрузки
            if (!options.UseGraduateDegrees.HasValue || !options.UseGraduateDegrees.Value)
            {
                return(model);
            }

            var users = await _userService.Get(new UserGetOptions { DepartmentId = model.DepartmentId });

            var loads = model.GroupDisciplineLoad;

            foreach (var load in loads)
            {
                foreach (var studyLoad in load.StudyLoad)
                {
                    var generateRatio = generateRatios.FirstOrDefault(o => o.StudyLoadId == studyLoad.Id);
                    var ratios        = users
                                        .ToDictionary(o => o,
                                                      o => o.GraduateDegrees.Any(gd => gd.GraduateDegree == GraduateDegree.DoctorOfSciences)
                                ? doctorOfSciencesRatioValue
                                : candidatOfSciencesRatioValue
                                                      );

                    if (generateRatio == null)
                    {
                        generateRatios.Add(new GenerateRatio
                        {
                            StudyLoadId = studyLoad.Id,
                            Ratios      = ratios
                        });
                    }
                    else
                    {
                        foreach (var userRatio in ratios)
                        {
                            var existedUserRatio = generateRatio.Ratios.FirstOrDefault(o => o.Key.Id == userRatio.Key.Id);
                            if (existedUserRatio.Key != null)
                            {
                                double newRatioValue = existedUserRatio.Value
                                                       + (existedUserRatio.Key.GraduateDegrees
                                                          .Any(gd => gd.GraduateDegree == GraduateDegree.DoctorOfSciences)
                                            ? doctorOfSciencesRatioValue
                                            : candidatOfSciencesRatioValue
                                                          );
                                existedUserRatio = new KeyValuePair <User, double>(existedUserRatio.Key, newRatioValue);
                            }
                            generateRatio.Ratios.Add(userRatio.Key, userRatio.Value);
                        }
                    }
                }
            }

            return(model);
        }
 public async Task <DepartmentLoad> Generate(DepartmentLoadGenerateOptions options, DepartmentLoad model)
 {
     return(await _membersFactory().GenerateExtensions(options, model));
 }
        public static async Task <DepartmentLoad> GenerateExtensions(this IEnumerable <IGenerateStrategy> members, DepartmentLoadGenerateOptions options, DepartmentLoad model)
        {
            List <GenerateRatio> generateRatios = new List <GenerateRatio>();

            var membersList = members.ToList();

            if (membersList != null)
            {
                for (int i = 0; i < membersList.Count; i++)
                {
                    model = await membersList[i].Generate(options, model, generateRatios);
                }
            }
            else
            {
                foreach (var member in members)
                {
                    model = await member.Generate(options, model, generateRatios);
                }
            }

            return(model);
        }
        public async Task <DepartmentLoad> Generate(DepartmentLoadGenerateOptions options, DepartmentLoad model, List <GenerateRatio> generateRatios)
        {
            await CalculateRatios(model, generateRatios);

            return(model);
        }
 public async Task <IActionResult> Generate([FromBody] DepartmentLoadGenerateOptions options)
 {
     return(Ok(await _service.Generate(options)));
 }