Exemplo n.º 1
0
        public List <EngineerSchedule> GetAllEngineerSchedules()
        {
            List <Engineer>         engineers    = _repository.GetAllEngineers().Where(e => e.IsAvailable == true).ToList();
            List <Engineer>         initialList  = _repository.GetAllEngineers().ToList();
            List <EngineerSchedule> previousweek = null;

            if (engineers.Count < (shiftDays / 2))
            {
                throw new InvalidOperationException("There are no enough engineers to generate schedule,adhering the rules");
            }
            List <EngineerSchedule> engineerSchedules = new List <EngineerSchedule>();
            DateTime currentDate = System.DateTime.Now;
            //Schedule starts from next monday
            int diffDays = ((int)DayOfWeek.Monday - (int)currentDate.DayOfWeek + 7) % 7;

            DateTime scheduleStartdate = currentDate.AddDays(diffDays);
            //Schedule spans for 2weeks 12 days(Monday to friday)
            DateTime scheduleEnddate      = scheduleStartdate.AddDays(12);
            DateTime currentScheduleStart = scheduleStartdate;

            for (int j = 0; j < scheduleSpan; j++)
            {
                if (j > 0)
                {
                    //To ensure that we are not getting the same random numbers in each week
                    Thread.Sleep(100);
                }
                var rand            = new Random();
                var randomEngineers = engineers.OrderBy(item => rand.Next()).Where(e => e.IsAvailable == true).ToList();
                if (randomEngineers.Count < shiftDays)
                {
                    int noOfengShortage = shiftDays - randomEngineers.Count;
                    //To make sure randomEngineers picked for 2nd week hasnt completed 1 day of support already in previous week
                    if (j > 0 && previousweek.Count > 0)
                    {
                        List <Engineer> assignedEngineers = new List <Engineer>();
                        foreach (EngineerSchedule es in previousweek)
                        {
                            foreach (Engineer eng in es.engineer)
                            {
                                assignedEngineers.Add(eng);
                            }
                        }


                        //To avoid duplicates in 2nd week,and make sure engineers opt out in last week completes 1 whole day of support
                        foreach (Engineer e in engineers)
                        {
                            bool isShiftcompletedPrevweek = assignedEngineers.Any(emp => emp.ID == e.ID);
                            bool isRandom = randomEngineers.Any(emp => emp.ID == e.ID);

                            if (isShiftcompletedPrevweek == true && isRandom == true)
                            {
                                e.IsAvailable = false;
                            }
                        }
                    }
                    //Shuffle the available Engineers list again,so that we get enough engineers to work for the existing week
                    var randomEngineers1 = engineers.OrderBy(item => rand.Next()).Where(e => e.IsAvailable == true).ToList().Take(noOfengShortage).ToList();
                    //Add it to the original randomEngineers list
                    foreach (Engineer e in randomEngineers1)
                    {
                        bool isOvertime = false;

                        if (isOvertime == false)
                        {
                            randomEngineers.Add(e);
                        }
                    }

                    if (j == 0)
                    {
                        //Set IsAvailable=false for engineers picked in 2nd shuffle,if they have completed 1 day of support
                        engineers = UpdateAvailableEngineersPool(randomEngineers, initialList);
                    }
                }
                if (j > 0 && engineerSchedules.Count > 0)
                {
                    currentScheduleStart = Convert.ToDateTime(engineerSchedules[engineerSchedules.Count - 1].ScheduleDate);
                    if (currentScheduleStart.DayOfWeek == DayOfWeek.Friday)
                    {
                        int diffDay = ((int)DayOfWeek.Monday - (int)currentScheduleStart.DayOfWeek + 7) % 7;

                        currentScheduleStart = currentScheduleStart.AddDays(diffDay);
                    }
                }
                engineerSchedules = GenerateSschedulePerWeek(currentScheduleStart, scheduleStartdate, scheduleEnddate, randomEngineers, engineerSchedules, previousweek);
                previousweek      = engineerSchedules;
            }

            return(engineerSchedules);
        }