public IActionResult Roaster()
        {
            DateTime             dt         = DateTime.Now;
            DateTime             monthStart = new DateTime(dt.Year, dt.Month, 1);
            DateTime             monthEnd   = monthStart.AddMonths(1).AddDays(-1);
            ShiftsPrintViewModel vm         = new ShiftsPrintViewModel {
                StartDate = monthStart, EndDate = monthEnd
            };

            return(View(vm));
        }
        public async Task <IActionResult> Roaster(ShiftsPrintViewModel vm)
        {
            if (ModelState.IsValid)
            {
                // check if start date > end date
                if (vm.StartDate > vm.EndDate)
                {
                    return(View(vm));
                }

                //fetch the shift types
                List <ShiftType> shiftTypes = await _context.ShiftTypes.OrderBy(st => st.RoasterSequence).ToListAsync();

                List <int> shiftTypeIds = shiftTypes.Select(st => st.ShiftTypeId).ToList();

                //fetch the shift Participation types
                List <ShiftParticipationType> shiftPartTypes = await _context.ShiftParticipationTypes.ToListAsync();

                List <int> shiftPartTypeIds = shiftPartTypes.Select(spt => spt.ShiftParticipationTypeId).ToList();

                // set the view model shift Types
                vm.ShiftTypes = new List <string>();
                foreach (ShiftType shiftType in shiftTypes)
                {
                    vm.ShiftTypes.Add(shiftType.Name);
                }

                // initiaize the shift participations in view model
                vm.ShiftParticipations = new Dictionary <DateTime, List <List <Tuple <string, ShiftParticipationType> > > >();
                for (DateTime dt = vm.StartDate; dt <= vm.EndDate; dt = dt.AddDays(1))
                {
                    vm.ShiftParticipations.Add(dt, new List <List <Tuple <string, ShiftParticipationType> > >());
                    foreach (var sType in shiftTypes)
                    {
                        vm.ShiftParticipations[dt].Add(new List <Tuple <string, ShiftParticipationType> >());
                    }
                }

                // get the shift participations from db
                List <ShiftParticipation> shiftParticipations = await _context.ShiftParticipations.Include(sp => sp.Shift).Include(sp => sp.Employee).Where(sp => sp.Shift.ShiftDate >= vm.StartDate && sp.Shift.ShiftDate <= vm.EndDate).ToListAsync();

                // assign the fetched shift participations to the vm
                foreach (ShiftParticipation shiftPart in shiftParticipations.OrderBy(sp => sp.ParticipationSequence))
                {
                    DateTime shiftDate = shiftPart.Shift.ShiftDate;
                    ShiftParticipationType participationType = null;
                    int shiftTypeIndex     = -1;
                    int shiftPartTypeIndex = -1;
                    try
                    {
                        shiftTypeIndex     = shiftTypeIds.FindIndex(sTId => sTId == shiftPart.Shift.ShiftTypeId);
                        shiftPartTypeIndex = shiftPartTypeIds.FindIndex(sPTId => sPTId == shiftPart.ShiftParticipationTypeId);
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                    if (shiftPartTypeIndex != -1)
                    {
                        participationType = shiftPartTypes[shiftPartTypeIndex];
                    }
                    vm.ShiftParticipations[shiftPart.Shift.ShiftDate][shiftTypeIndex].Add(new Tuple <string, ShiftParticipationType>(shiftPart.Employee.Name, participationType));
                }

                // get all the shift objects for comments
                List <Shift> shifts = await _context.Shifts.Where(s => s.ShiftDate >= vm.StartDate && s.ShiftDate <= vm.EndDate).OrderBy(s => s.ShiftDate).ToListAsync();

                // assign the fetched shift comments to the vm
                vm.ShiftComments = new List <Tuple <DateTime, string, string> >();
                foreach (Shift shift in shifts)
                {
                    if (shift.Comments != null && shift.Comments != "")
                    {
                        DateTime shiftDate      = shift.ShiftDate;
                        int      shiftTypeIndex = -1;
                        try
                        {
                            shiftTypeIndex = shiftTypeIds.FindIndex(sTId => sTId == shift.ShiftTypeId);
                        }
                        catch (Exception)
                        {
                            continue;
                        }
                        vm.ShiftComments.Add(new Tuple <DateTime, string, string>(shift.ShiftDate, shiftTypes[shiftTypeIndex].Name, shift.Comments));
                    }
                }
            }
            return(View(vm));
        }