private IEnumerable <VacationDay> GetRandomDays(int month, int year, List <Employee> employees) { if (employees == null) { throw new ArgumentNullException(nameof(employees)); } var avaliableHolidayDays = AvaliableHolidayDays; var numberOfDaysInMonth = DateTime.DaysInMonth(year, month); var generatedVacationDays = new List <VacationDay>(); foreach (var employee in employees) { var employeeHolidayDays = new List <DateTime>(); while (avaliableHolidayDays > 0) { var rnd = new Random(); var rndDay = rnd.Next(1, numberOfDaysInMonth); var randomDay = new DateTime(year, month, rndDay); // Condition when employee can't go to work if ((randomDay.DayOfWeek != DayOfWeek.Sunday) && (randomDay.DayOfWeek != DayOfWeek.Saturday) && !Holidays.Exists(x => x == randomDay) && !employeeHolidayDays.Exists(x => x == randomDay)) { employeeHolidayDays.Add(randomDay); // Employee cannot be twice on the single day at work. if (generatedVacationDays.Exists(x => x.Day == randomDay) && (generatedVacationDays.Where(x => x.Day == randomDay).FirstOrDefault().Employees.Count < MaxNumberOfPersonOnVacationPerDay)) { generatedVacationDays.Where(x => x.Day == randomDay) .FirstOrDefault() .Employees.Add(employee); avaliableHolidayDays--; } else if (!generatedVacationDays.Exists(x => x.Day == randomDay)) { generatedVacationDays.Add(new VacationDay { Day = randomDay, Employees = new List <Employee> { employee } }); avaliableHolidayDays--; } } } avaliableHolidayDays = 2; } return(generatedVacationDays); }
private List <WorkingDay> GetWorkingDays(Tuple <int, int, Calendar <VacationDay> > vacationCalendar) { var numberOfDays = DateTime.DaysInMonth(vacationCalendar.Item2, vacationCalendar.Item1); var currentDayCounter = 1; var workingCalendar = new List <WorkingDay>(); var dutiesEmployee = new Dictionary <Employee, int>(); foreach (var employee in Employess) { dutiesEmployee.Add(employee, 0); } while (currentDayCounter <= numberOfDays) { var currentDay = new DateTime(vacationCalendar.Item2, vacationCalendar.Item1, currentDayCounter); if ((currentDay.DayOfWeek == DayOfWeek.Sunday) || (currentDay.DayOfWeek == DayOfWeek.Saturday) || Holidays.Exists(x => x == currentDay)) { workingCalendar.Add(new WorkingDay { Day = currentDay, IsVacation = true }); } else { var availableEmployees = new List <Employee>(); var employeeOnHolidayInCurrentDay = vacationCalendar.Item3.Days.FirstOrDefault(y => y.Day == currentDay); foreach (var employee in Employess) { if ((employeeOnHolidayInCurrentDay == null) || !employeeOnHolidayInCurrentDay.Employees.Exists(x => x == employee)) { availableEmployees.Add(employee); } } // Smallest number of duties var potentialCandidates = GetPotentialCandidates(availableEmployees, dutiesEmployee); var rnd = new Random(); var randomEmployeeId = rnd.Next(potentialCandidates.Count); var potentialEmployeeForWorking = potentialCandidates[randomEmployeeId]; if (currentDayCounter > NumberOfEmployeeDutiesPerWeek) { var checkIfEmployeeWorkSecondDay = workingCalendar.Exists( x => (x.Day == currentDay.AddDays(-1)) && (x.Employee == potentialEmployeeForWorking)); var checkIfEmployeeWorkThirdTimes = workingCalendar.Exists( x => (x.Day == currentDay.AddDays(-2)) && (x.Employee == potentialEmployeeForWorking)); if (checkIfEmployeeWorkSecondDay == false) { workingCalendar.Add(new WorkingDay { Day = currentDay, Employee = potentialEmployeeForWorking, IsVacation = false }); dutiesEmployee[potentialEmployeeForWorking]++; } else if (checkIfEmployeeWorkThirdTimes && (potentialCandidates.Count == 1)) { workingCalendar.Add(new WorkingDay { Day = currentDay, Employee = potentialEmployeeForWorking, IsVacation = false }); } else { potentialEmployeeForWorking = potentialCandidates.FirstOrDefault(x => x.Id != potentialEmployeeForWorking.Id); workingCalendar.Add(new WorkingDay { Day = currentDay, Employee = potentialEmployeeForWorking, IsVacation = false }); if (potentialEmployeeForWorking != null) { dutiesEmployee[potentialEmployeeForWorking]++; } } } else { workingCalendar.Add(new WorkingDay { Day = currentDay, Employee = potentialEmployeeForWorking, IsVacation = false }); dutiesEmployee[potentialEmployeeForWorking]++; } } currentDayCounter++; } return(workingCalendar); }