Exemplo n.º 1
0
        public async Task <IActionResult> PutShiftParticipation([FromRoute] int id, [FromBody] ShiftParticipation shiftParticipation)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            if (id != shiftParticipation.ShiftParticipationId)
            {
                return(BadRequest());
            }

            _context.Entry(shiftParticipation).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ShiftParticipationExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(NoContent());
        }
        public async Task <IActionResult> Edit(int id, [Bind("ShiftParticipationId,EmployeeId,ShiftId")] ShiftParticipation shiftParticipation)
        {
            if (id != shiftParticipation.ShiftParticipationId)
            {
                return(NotFound());
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(shiftParticipation);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ShiftParticipationExists(shiftParticipation.ShiftParticipationId))
                    {
                        return(NotFound());
                    }
                    else
                    {
                        throw;
                    }
                }
                return(RedirectToAction(nameof(Index)));
            }
            ViewData["EmployeeId"] = new SelectList(_context.Employees, "EmployeeId", "Name", shiftParticipation.EmployeeId);
            ViewData["ShiftId"]    = new SelectList(_context.Shifts, "ShiftId", "ShiftId", shiftParticipation.ShiftId);
            return(View(shiftParticipation));
        }
Exemplo n.º 3
0
        public async Task <ActionResult <ShiftParticipation> > CreateShiftParticipation([FromBody] ShiftParticipation shiftParticipation)
        {
            ShiftParticipation sp = await _mediator.Send(new CreateShiftParticipationCommand()
            {
                ShiftParticipation = shiftParticipation
            });

            return(CreatedAtAction("GetShiftParticipation", new { id = shiftParticipation.Id }, sp));
        }
        public async Task <bool> Handle(FollowShiftParticipationCommand request, CancellationToken cancellationToken)
        {
            // get all the shift participations to follow
            var spList = await _context.ShiftParticipations
                         .Where(sp => (sp.Shift.ShiftDate >= request.StartDate) &&
                                (sp.Shift.ShiftDate <= request.EndDate) &&
                                (sp.EmployeeId == request.TargetEmployeeId) &&
                                (request.TargetParticipationTypeId == -1 ? true : (sp.ShiftParticipationTypeId == request.TargetParticipationTypeId))
                                )
                         .ToListAsync();

            // create similar shift participations for the new employee
            foreach (ShiftParticipation sp in spList)
            {
                int newPartTypeId = request.NewParticipationTypeId;
                newPartTypeId = (newPartTypeId == -1) ? sp.ShiftParticipationTypeId : newPartTypeId;

                int newPartSeq = request.NewParticipationSequence;
                newPartSeq += -1;
                newPartSeq  = (newPartSeq == -1) ? sp.ParticipationSequence : newPartSeq;

                ShiftParticipation newPart = new ShiftParticipation
                {
                    EmployeeId = request.NewEmployeeId,
                    ShiftId    = sp.ShiftId,
                    ShiftParticipationTypeId = newPartTypeId,
                    ParticipationSequence    = newPartSeq
                };

                try
                {
                    if (request.NewEmployeeId != request.TargetEmployeeId)
                    {
                        // we are trying to follow an employee participation
                        _context.ShiftParticipations.Add(newPart);
                        await _context.SaveChangesAsync();
                    }
                    else
                    {
                        // we are trying to modify an existing participation
                        sp.EmployeeId = newPart.EmployeeId;
                        sp.ShiftId    = newPart.ShiftId;
                        sp.ShiftParticipationTypeId = newPart.ShiftParticipationTypeId;
                        sp.ParticipationSequence    = newPart.ParticipationSequence;
                        _context.Entry(sp).State    = EntityState.Modified;
                        await _context.SaveChangesAsync();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }

            return(true);
        }
Exemplo n.º 5
0
        public async Task <IActionResult> PostShiftParticipation([FromBody] ShiftParticipation shiftParticipation)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            _context.ShiftParticipations.Add(shiftParticipation);
            await _context.SaveChangesAsync();

            return(CreatedAtAction("GetShiftParticipation", new { id = shiftParticipation.ShiftParticipationId }, shiftParticipation));
        }
Exemplo n.º 6
0
        public async Task <ActionResult <ShiftParticipation> > DeleteShiftParticipation([FromRoute] int id)
        {
            ShiftParticipation sp = await _mediator.Send(new DeleteShiftParticipationCommand()
            {
                Id = id
            });

            if (sp == null)
            {
                return(NotFound());
            }
            return(sp);
        }
        public async Task <IActionResult> Create([Bind("ShiftParticipationId,EmployeeId,ShiftId")] ShiftParticipation shiftParticipation)
        {
            if (ModelState.IsValid)
            {
                _context.Add(shiftParticipation);
                await _context.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }
            ViewData["EmployeeId"] = new SelectList(_context.Employees, "EmployeeId", "Name", shiftParticipation.EmployeeId);
            ViewData["ShiftId"]    = new SelectList(_context.Shifts, "ShiftId", "ShiftId", shiftParticipation.ShiftId);
            return(View(shiftParticipation));
        }
Exemplo n.º 8
0
        public async Task <ActionResult <ShiftParticipation> > GetShiftParticipation([FromRoute] int id)
        {
            ShiftParticipation shiftParticipation = await _mediator.Send(new GetShiftParticipationQuery()
            {
                Id = id
            });

            if (shiftParticipation == null)
            {
                return(NotFound());
            }

            return(Ok(shiftParticipation));
        }
Exemplo n.º 9
0
        public async Task <IActionResult> EditShiftParticipation([FromRoute] int id, [FromBody] ShiftParticipation shiftParticipation)
        {
            if (id != shiftParticipation.Id)
            {
                return(BadRequest());
            }

            bool res = await _mediator.Send(new EditShiftParticipationCommand()
            {
                ShiftParticipation = shiftParticipation
            });

            if (res == false)
            {
                return(NotFound());
            }

            return(NoContent());
        }
        public async Task <IActionResult> AutoCreate([Bind("StartDate,EndDate")] AutoInitializeParamsViewModel autoInitParams)
        {
            if (ModelState.IsValid)
            {
                DateTime startDate = autoInitParams.StartDate;
                DateTime endDate   = autoInitParams.EndDate;

                // create shift type Ids in the roaster sequence for automated shift
                List <int> orderedShiftTypeIds = await _context.ShiftCycleItems.OrderBy(sci => sci.ShiftSequence).Select(sci => sci.ShiftTypeId).ToListAsync();

                // List<ShiftType> shiftTypes = await _context.ShiftTypes.OrderBy(st => st.RoasterSequence).ToListAsync();
                // List<int> orderedShiftTypeIds_old = shiftTypes.Select(st => st.ShiftTypeId).ToList();

                //Func<int, int, Tuple<int, int>> GetNextShiftTypeInfo = (currentShiftTypeId, numTimesAlreadyOccured) =>
                //{
                //    if (numTimesAlreadyOccured == 1)
                //    {
                //        return new Tuple<int, int>(currentShiftTypeId, 2);
                //    }
                //    int nextShiftTypeId = -1;
                //    int updatedAlreadyOccured = -1;
                //    if (orderedShiftTypeIds.Any(sti => sti == currentShiftTypeId))
                //    {
                //        int currentShiftTypeIdIndex = orderedShiftTypeIds.FindIndex(sti => sti == currentShiftTypeId);
                //        int nextShiftTypeIdIndex = currentShiftTypeIdIndex + 1;
                //        if (nextShiftTypeIdIndex >= orderedShiftTypeIds.Count)
                //        {
                //            nextShiftTypeIdIndex = 0;
                //        }
                //        nextShiftTypeId = orderedShiftTypeIds[nextShiftTypeIdIndex];
                //        updatedAlreadyOccured = 1;
                //    }
                //    return new Tuple<int, int>(nextShiftTypeId, updatedAlreadyOccured);
                //};

                // defining function as variable - https://stackoverflow.com/questions/12127020/c-sharp-variable-new-function
                Func <int, int> GetNextShiftTypeIndex = (currentShiftTypeIndex) =>
                {
                    int nextShiftTypeIndex = -1;
                    if (currentShiftTypeIndex < 0)
                    {
                        return(-1);
                    }
                    if (currentShiftTypeIndex == orderedShiftTypeIds.Count - 1)
                    {
                        nextShiftTypeIndex = 0;
                    }
                    else
                    {
                        nextShiftTypeIndex = currentShiftTypeIndex + 1;
                    }
                    return(nextShiftTypeIndex);
                };

                // get the shifts on the start Date
                List <Shift> startDayShifts = await _context.Shifts.Include(s => s.ShiftType).Include(s => s.ShiftParticipations).Where(s => s.ShiftDate == startDate).OrderBy(s => s.ShiftType.RoasterSequence).ToListAsync();

                // iterate through each shift in the start date
                foreach (Shift startDayShift in startDayShifts)
                {
                    List <ShiftParticipation> startDayShiftParticipations = startDayShift.ShiftParticipations.ToList();
                    int currentShiftTypeId    = startDayShift.ShiftTypeId;
                    int currentShiftTypeIndex = orderedShiftTypeIds.IndexOf(currentShiftTypeId);

                    // iterate through each shift date for automation
                    for (DateTime shiftDate = startDate.AddDays(1); (shiftDate.Date <= endDate.Date) && (currentShiftTypeIndex != -1); shiftDate = shiftDate.AddDays(1))
                    {
                        // get the next ShiftType in the shift cycle sequence creating the new shift
                        currentShiftTypeIndex = GetNextShiftTypeIndex(currentShiftTypeIndex);
                        currentShiftTypeId    = orderedShiftTypeIds[currentShiftTypeIndex];

                        // delete all the shifts of the particular shift type on that day if present
                        List <Shift> existingShifts = await _context.Shifts.Where(s => s.ShiftDate == shiftDate && s.ShiftTypeId == currentShiftTypeId).ToListAsync();

                        foreach (Shift existingShift in existingShifts)
                        {
                            _context.Shifts.Remove(existingShift);
                        }

                        // create new shift with the shift participations
                        Shift newShift = new Shift {
                            ShiftTypeId = currentShiftTypeId, ShiftDate = shiftDate
                        };
                        _context.Add(newShift);
                        await _context.SaveChangesAsync();

                        // create the shift participations for the new shift
                        foreach (ShiftParticipation shiftPart in startDayShift.ShiftParticipations)
                        {
                            ShiftParticipation newShiftPart = new ShiftParticipation {
                                ShiftId = newShift.ShiftId, EmployeeId = shiftPart.EmployeeId, ParticipationSequence = shiftPart.ParticipationSequence, ShiftParticipationTypeId = shiftPart.ShiftParticipationTypeId
                            };
                            _context.ShiftParticipations.Add(newShiftPart);
                            await _context.SaveChangesAsync();
                        }
                    }
                }

                return(RedirectToAction(nameof(Index)));
            }
            return(View());
        }
        public async Task <Shift> Handle(MoveShiftParticipationCommand request, CancellationToken cancellationToken)
        {
            if (request.Direction != -1 && request.Direction != 1)
            {
                return(null);
            }

            //get the id of the shift that contains the participation to move
            ShiftParticipation shiftParticipation = await _context.ShiftParticipations.FindAsync(request.ShiftParticipationId);

            if (shiftParticipation == null)
            {
                return(null);
            }

            // get the shift that has the participation to be moved
            Shift shift = await _context.Shifts.Include(s => s.ShiftParticipations).FirstOrDefaultAsync(s => s.Id == shiftParticipation.ShiftId);

            if (shift == null)
            {
                return(null);
            }
            // get the interested shift participation
            ShiftParticipation interestedShiftPart = shift.ShiftParticipations.SingleOrDefault(sp => sp.Id == request.ShiftParticipationId);
            ShiftParticipation nextPart            = null;

            // find the next shift Participation sequence
            foreach (ShiftParticipation shiftPart in shift.ShiftParticipations)
            {
                if (shiftPart.Id != request.ShiftParticipationId)
                {
                    if (request.Direction == -1 && shiftPart.ParticipationSequence >= interestedShiftPart.ParticipationSequence)
                    {
                        if (nextPart == null)
                        {
                            nextPart = shiftPart;
                        }
                        else
                        {
                            if (shiftPart.ParticipationSequence < nextPart.ParticipationSequence)
                            {
                                nextPart = shiftPart;
                            }
                        }
                    }
                    else if (request.Direction == 1 && shiftPart.ParticipationSequence <= interestedShiftPart.ParticipationSequence)
                    {
                        if (nextPart == null)
                        {
                            nextPart = shiftPart;
                        }
                        else
                        {
                            if (shiftPart.ParticipationSequence > nextPart.ParticipationSequence)
                            {
                                nextPart = shiftPart;
                            }
                        }
                    }
                }
            }

            // if there is no next participation, do nothing
            if (nextPart != null)
            {
                if (nextPart.ParticipationSequence != interestedShiftPart.ParticipationSequence)
                {
                    // swap the sequences if possible
                    int tempSeq = nextPart.ParticipationSequence;
                    nextPart.ParticipationSequence            = interestedShiftPart.ParticipationSequence;
                    interestedShiftPart.ParticipationSequence = tempSeq;
                    _context.Entry(interestedShiftPart).State = EntityState.Modified;
                    _context.Entry(nextPart).State            = EntityState.Modified;
                    await _context.SaveChangesAsync();
                }
                else
                {
                    if (request.Direction == -1)
                    {
                        // if direction is -1, then we have move the participation down, i.e., add one to sequence
                        interestedShiftPart.ParticipationSequence += 1;
                        _context.Entry(interestedShiftPart).State  = EntityState.Modified;
                        await _context.SaveChangesAsync();
                    }
                    else if (request.Direction == 1)
                    {
                        if (interestedShiftPart.ParticipationSequence > 0)
                        {
                            // if direction is 1, then we have move the participation up, i.e., subtract one to sequence
                            interestedShiftPart.ParticipationSequence -= 1;
                            _context.Entry(interestedShiftPart).State  = EntityState.Modified;
                            await _context.SaveChangesAsync();
                        }
                        else
                        {
                            // if direction is 1, then we have move the participation up, add one to all other since already seq < zero
                            foreach (ShiftParticipation shiftPart in shift.ShiftParticipations)
                            {
                                if (shiftPart.Id != interestedShiftPart.Id)
                                {
                                    shiftPart.ParticipationSequence += 1;
                                    _context.Entry(shiftPart).State  = EntityState.Modified;
                                }
                            }
                            await _context.SaveChangesAsync();
                        }
                    }
                }
            }
            return(await _context.Shifts.Include(s => s.ShiftParticipations).FirstOrDefaultAsync(s => s.Id == shift.Id));
        }
Exemplo n.º 12
0
        public async Task <List <EmployeeStatsDTO> > Handle(GetAllEmployeeStatsQuery request, CancellationToken cancellationToken)
        {
            List <EmployeeStatsDTO> vm = new List <EmployeeStatsDTO>();

            // get all the shift participations
            List <ShiftParticipation> shiftParts = await _context.ShiftParticipations.Where(sp => sp.Shift.ShiftDate >= request.StartDate.Date && sp.Shift.ShiftDate <= request.EndDate.Date)
                                                   .Include(sp => sp.ShiftParticipationType)
                                                   .Include(sp => sp.Shift)
                                                   .ThenInclude(s => s.ShiftType)
                                                   .ToListAsync();

            List <ShiftType> shiftTypes = await _context.ShiftTypes.ToListAsync();

            List <ShiftParticipationType> shiftPartTypes = await _context.ShiftParticipationTypes.ToListAsync();

            List <ApplicationUser> employees = await _userManager.Users
                                               .Include(e => e.ShiftGroup)
                                               .Include(e => e.ShiftRole)
                                               .Include(e => e.Gender)
                                               .ToListAsync();

            // compute stats for each employee
            foreach (ApplicationUser emp in employees)
            {
                string         userRole      = "";
                IList <string> existingRoles = await _userManager.GetRolesAsync(emp);

                if (existingRoles.Count > 0)
                {
                    userRole = existingRoles.ElementAt(0);
                }
                if (userRole != SecurityConstants.AdminRoleString)
                {
                    UserDTO uDTO = _mapper.Map <UserDTO>(emp);
                    uDTO.UserRole = userRole;
                    EmployeeStatsDTO stats = new EmployeeStatsDTO
                    {
                        Employee = uDTO
                    };

                    // count as per shift type
                    foreach (ShiftType sType in shiftTypes)
                    {
                        int numEmpShiftsOfThisType = shiftParts.Count(sp => sp.EmployeeId == emp.Id && sp.Shift.ShiftTypeId == sType.Id);
                        stats.NumShiftsPerType.Add($"{sType.Name}_Allotted", numEmpShiftsOfThisType);

                        numEmpShiftsOfThisType = shiftParts.Count(sp => sp.EmployeeId == emp.Id && sp.Shift.ShiftTypeId == sType.Id && !sp.ShiftParticipationType.IsAbsence);
                        stats.NumShiftsPerType.Add($"{sType.Name}_Attended", numEmpShiftsOfThisType);
                    }

                    // count as per participation type
                    foreach (var sPartType in shiftPartTypes)
                    {
                        int numEmpShiftsOfThisType = shiftParts.Count(sp => sp.EmployeeId == emp.Id && sp.ShiftParticipationTypeId == sPartType.Id);
                        stats.NumShiftsPerType.Add(sPartType.Name, numEmpShiftsOfThisType);
                        if (sPartType.IsAbsence)
                        {
                            stats.numAbsenceShifts += numEmpShiftsOfThisType;
                        }
                        else
                        {
                            stats.numPresenceShifts += numEmpShiftsOfThisType;
                        }
                    }

                    // fetch the latest night shift date
                    ShiftParticipation latestNightPart = await _context.ShiftParticipations.Where(sp => (sp.EmployeeId == emp.Id) && (sp.Shift.ShiftType.Name.ToLower() == "night"))
                                                         .Include(sp => sp.Shift)
                                                         .ThenInclude(s => s.ShiftType)
                                                         .OrderByDescending(sp => sp.Shift.ShiftDate)
                                                         .FirstOrDefaultAsync();

                    if (latestNightPart != default(ShiftParticipation))
                    {
                        stats.LatestNightParticipation = latestNightPart.Shift.ShiftDate;
                    }

                    // fetch the latest shift date
                    ShiftParticipation latestPart = await _context.ShiftParticipations.Where(sp => (sp.EmployeeId == emp.Id))
                                                    .Include(sp => sp.Shift)
                                                    .ThenInclude(s => s.ShiftType)
                                                    .OrderByDescending(sp => sp.Shift.ShiftDate)
                                                    .FirstOrDefaultAsync();

                    if (latestPart != default(ShiftParticipation))
                    {
                        stats.LatestParticipation = latestPart.Shift.ShiftDate;
                    }

                    vm.Add(stats);
                }
            }
            return(vm);
        }
        public async Task <IActionResult> MoveShiftParticipation([FromRoute] int shiftPartId, [FromBody] ShiftPartMoveFormModel formModel)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }
            if (formModel.Direction != -1 && formModel.Direction != 1)
            {
                return(BadRequest());
            }

            //get the id of the shift that contains the participation to move
            ShiftParticipation shiftParticipation = await _context.ShiftParticipations.FindAsync(shiftPartId);

            if (shiftParticipation == null)
            {
                return(BadRequest());
            }

            // get the shift that has the participation to be moved
            Shift shift = await _context.Shifts.Include(s => s.ShiftParticipations).FirstOrDefaultAsync(s => s.ShiftId == shiftParticipation.ShiftId);

            if (shift == null)
            {
                return(BadRequest());
            }
            // get the interested shift participation
            ShiftParticipation interestedShiftPart = shift.ShiftParticipations.SingleOrDefault(sp => sp.ShiftParticipationId == shiftPartId);
            ShiftParticipation nextPart            = null;

            // find the next shift Participation sequence
            foreach (ShiftParticipation shiftPart in shift.ShiftParticipations)
            {
                if (shiftPart.ShiftParticipationId != shiftPartId)
                {
                    if (formModel.Direction == -1 && shiftPart.ParticipationSequence >= interestedShiftPart.ParticipationSequence)
                    {
                        if (nextPart == null)
                        {
                            nextPart = shiftPart;
                        }
                        else
                        {
                            if (shiftPart.ParticipationSequence < nextPart.ParticipationSequence)
                            {
                                nextPart = shiftPart;
                            }
                        }
                    }
                    else if (formModel.Direction == 1 && shiftPart.ParticipationSequence <= interestedShiftPart.ParticipationSequence)
                    {
                        if (nextPart == null)
                        {
                            nextPart = shiftPart;
                        }
                        else
                        {
                            if (shiftPart.ParticipationSequence > nextPart.ParticipationSequence)
                            {
                                nextPart = shiftPart;
                            }
                        }
                    }
                }
            }

            // if there is no next participation, do nothing
            if (nextPart != null)
            {
                if (nextPart.ParticipationSequence != interestedShiftPart.ParticipationSequence)
                {
                    // swap the sequences if possible
                    int tempSeq = nextPart.ParticipationSequence;
                    nextPart.ParticipationSequence            = interestedShiftPart.ParticipationSequence;
                    interestedShiftPart.ParticipationSequence = tempSeq;
                    _context.Entry(interestedShiftPart).State = EntityState.Modified;
                    _context.Entry(nextPart).State            = EntityState.Modified;
                    await _context.SaveChangesAsync();
                }
                else
                {
                    if (formModel.Direction == -1)
                    {
                        // if direction is -1, then we have move the participation down, i.e., add one to sequence
                        interestedShiftPart.ParticipationSequence += 1;
                        _context.Entry(interestedShiftPart).State  = EntityState.Modified;
                        await _context.SaveChangesAsync();
                    }
                    else if (formModel.Direction == 1)
                    {
                        if (interestedShiftPart.ParticipationSequence > 0)
                        {
                            // if direction is 1, then we have move the participation up, i.e., subtract one to sequence
                            interestedShiftPart.ParticipationSequence -= 1;
                            _context.Entry(interestedShiftPart).State  = EntityState.Modified;
                            await _context.SaveChangesAsync();
                        }
                        else
                        {
                            // if direction is 1, then we have move the participation up, add one to all other since already seq < zero
                            foreach (ShiftParticipation shiftPart in shift.ShiftParticipations)
                            {
                                if (shiftPart.ShiftParticipationId != interestedShiftPart.ShiftParticipationId)
                                {
                                    shiftPart.ParticipationSequence += 1;
                                    _context.Entry(shiftPart).State  = EntityState.Modified;
                                }
                            }
                            await _context.SaveChangesAsync();
                        }
                    }
                }
            }
            return(Ok(await _context.Shifts.Include(s => s.ShiftParticipations).FirstOrDefaultAsync(s => s.ShiftId == shift.ShiftId)));
        }
Exemplo n.º 14
0
            public async Task <bool> Handle(AutoCreateShiftsCommand request, CancellationToken cancellationToken)
            {
                DateTime startDate = request.StartDate;
                DateTime endDate   = request.EndDate;

                // create shift type Ids in the roaster sequence for automated shift
                List <int> orderedShiftTypeIds = await _context.ShiftCycleItems.OrderBy(sci => sci.ShiftSequence).Select(sci => sci.ShiftTypeId).ToListAsync();

                // List<ShiftType> shiftTypes = await _context.ShiftTypes.OrderBy(st => st.RoasterSequence).ToListAsync();
                // List<int> orderedShiftTypeIds_old = shiftTypes.Select(st => st.ShiftTypeId).ToList();

                //Func<int, int, Tuple<int, int>> GetNextShiftTypeInfo = (currentShiftTypeId, numTimesAlreadyOccured) =>
                //{
                //    if (numTimesAlreadyOccured == 1)
                //    {
                //        return new Tuple<int, int>(currentShiftTypeId, 2);
                //    }
                //    int nextShiftTypeId = -1;
                //    int updatedAlreadyOccured = -1;
                //    if (orderedShiftTypeIds.Any(sti => sti == currentShiftTypeId))
                //    {
                //        int currentShiftTypeIdIndex = orderedShiftTypeIds.FindIndex(sti => sti == currentShiftTypeId);
                //        int nextShiftTypeIdIndex = currentShiftTypeIdIndex + 1;
                //        if (nextShiftTypeIdIndex >= orderedShiftTypeIds.Count)
                //        {
                //            nextShiftTypeIdIndex = 0;
                //        }
                //        nextShiftTypeId = orderedShiftTypeIds[nextShiftTypeIdIndex];
                //        updatedAlreadyOccured = 1;
                //    }
                //    return new Tuple<int, int>(nextShiftTypeId, updatedAlreadyOccured);
                //};

                // using local function
                int GetNextShiftTypeIndex(int currentShiftTypeIndex)
                {
                    int nextShiftTypeIndex = -1;

                    if (currentShiftTypeIndex < 0)
                    {
                        return(-1);
                    }
                    if (currentShiftTypeIndex == orderedShiftTypeIds.Count - 1)
                    {
                        nextShiftTypeIndex = 0;
                    }
                    else
                    {
                        nextShiftTypeIndex = currentShiftTypeIndex + 1;
                    }
                    return(nextShiftTypeIndex);
                }

                // get the shifts on the start Date
                List <Shift> startDayShifts = await _context.Shifts.Include(s => s.ShiftType).Include(s => s.ShiftParticipations).Where(s => s.ShiftDate == startDate).ToListAsync();

                // iterate through each shift in the start date
                foreach (Shift startDayShift in startDayShifts)
                {
                    List <ShiftParticipation> startDayShiftParticipations = startDayShift.ShiftParticipations.ToList();
                    int currentShiftTypeId    = startDayShift.ShiftTypeId;
                    int currentShiftTypeIndex = orderedShiftTypeIds.IndexOf(currentShiftTypeId);

                    // iterate through each shift date for automation
                    for (DateTime shiftDate = startDate.AddDays(1); (shiftDate.Date <= endDate.Date) && (currentShiftTypeIndex != -1); shiftDate = shiftDate.AddDays(1))
                    {
                        // get the next ShiftType in the shift cycle sequence creating the new shift
                        currentShiftTypeIndex = GetNextShiftTypeIndex(currentShiftTypeIndex);
                        currentShiftTypeId    = orderedShiftTypeIds[currentShiftTypeIndex];

                        // delete all the shifts of the particular shift type on that day if present
                        List <Shift> existingShifts = await _context.Shifts.Where(s => s.ShiftDate == shiftDate && s.ShiftTypeId == currentShiftTypeId).ToListAsync();

                        foreach (Shift existingShift in existingShifts)
                        {
                            _context.Shifts.Remove(existingShift);
                        }

                        // create new shift with the shift participations
                        Shift newShift = new Shift {
                            ShiftTypeId = currentShiftTypeId, ShiftDate = shiftDate
                        };
                        _context.Add(newShift);
                        await _context.SaveChangesAsync();

                        // create the shift participations for the new shift
                        foreach (ShiftParticipation shiftPart in startDayShift.ShiftParticipations)
                        {
                            ShiftParticipation newShiftPart = new ShiftParticipation {
                                ShiftId = newShift.Id, EmployeeId = shiftPart.EmployeeId, ParticipationSequence = shiftPart.ParticipationSequence, ShiftParticipationTypeId = shiftPart.ShiftParticipationTypeId
                            };
                            _context.ShiftParticipations.Add(newShiftPart);
                            await _context.SaveChangesAsync();
                        }
                    }
                }
                return(true);
            }