private EmployeeWorkload GetEmployeeWorkloadForDateRange(Employee employee, DateTimeRange dateRange, WorkloadPeriod periodStep, IDictionary <DateTime, int> workhoursByDate, IDictionary <DateTime, Workload> dailyWorkload)
        {
            var employeeWorkload = new EmployeeWorkload
            {
                Employee = employee
            };

            DateTime dateFrom = dateRange.Begin.Date;

            DateTime dateTo;

            if (periodStep == WorkloadPeriod.Week)
            {
                int daysToSunday = (7 - (int)dateFrom.DayOfWeek) % 7;
                dateTo = dateFrom.AddDays(daysToSunday);
            }
            else if (periodStep == WorkloadPeriod.Month)
            {
                int lastDayOfMonth = DateTime.DaysInMonth(dateFrom.Year, dateFrom.Month);
                dateTo = new DateTime(dateFrom.Year, dateFrom.Month, lastDayOfMonth);
            }
            else
            {
                throw new NotImplementedException($"Обработка периода загрузки {periodStep} не реализована");
            }

            while (dateTo <= dateRange.End.Date)
            {
                EmployeeWorkloadRecord employeeWorkloadRecord = CalculateWorkloadForPeriod(dateFrom, dateTo, dailyWorkload, workhoursByDate);
                employeeWorkload.WorkloadRecords.Add(employeeWorkloadRecord);
                dateFrom = dateTo.AddDays(1);
                if (periodStep == WorkloadPeriod.Week)
                {
                    dateTo = dateTo.AddDays(7);
                }
                else if (periodStep == WorkloadPeriod.Month)
                {
                    dateTo = dateTo.AddMonths(1);
                    int lastDayOfMonth = DateTime.DaysInMonth(dateTo.Year, dateTo.Month);
                    dateTo = new DateTime(dateTo.Year, dateTo.Month, lastDayOfMonth);
                }
            }

            dateTo = dateRange.End.Date;
            if (dateFrom <= dateTo)
            {
                EmployeeWorkloadRecord employeeWorkloadRecord = CalculateWorkloadForPeriod(dateFrom, dateTo, dailyWorkload, workhoursByDate);
                employeeWorkload.WorkloadRecords.Add(employeeWorkloadRecord);
            }

            return(employeeWorkload);
        }
        private EmployeeWorkloadRecord CalculateWorkloadForPeriod(DateTime dateFrom, DateTime dateTo, IDictionary <DateTime, Workload> dailyWorkload, IDictionary <DateTime, int> workhours)
        {
            int      hoursInWeek         = 0;
            int      currentProjectHours = 0;
            int      totalProjectHours   = 0;
            DateTime date = dateFrom;

            while (date <= dateTo)
            {
                int workhoursInDay = workhours[date];
                hoursInWeek += workhoursInDay;
                if (dailyWorkload.TryGetValue(date, out Workload workload))
                {
                    currentProjectHours += (workload.CurrentProjectPercent * workhoursInDay);
                    totalProjectHours   += (workload.TotalPercent * workhoursInDay);
                }

                date = date.AddDays(1);
            }
            var employeeWorkloadRecord = new EmployeeWorkloadRecord();

            employeeWorkloadRecord.DateFrom = dateFrom;
            employeeWorkloadRecord.DateTo   = dateTo;
            if (hoursInWeek > 0)
            {
                employeeWorkloadRecord.CurrentProjectPercents = Math.Round(currentProjectHours / (double)hoursInWeek);
                employeeWorkloadRecord.TotalPercents          = Math.Round(totalProjectHours / (double)hoursInWeek);
            }
            else
            {
                // Обработка ситуации, когда на неделе нет ни одного рабочего дня (с 1 по 7 явнваря)
                // TODO: Нужно подмать, нет ли лучшего варианта
                employeeWorkloadRecord.CurrentProjectPercents = 0;
                employeeWorkloadRecord.TotalPercents          = 100;
            }
            employeeWorkloadRecord.CurrentProjectHours = hoursInWeek * employeeWorkloadRecord.CurrentProjectPercents / 100.0;

            return(employeeWorkloadRecord);
        }