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