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);
        }