public async Task CanCreateShiftRecurringWorkItem() { var dto = new RecurringWorkItemDto(); int userId = 1; var shift = new Shift() { Name = "Shift", Id = 60, StartHour = 9, EndHour = 17 }; dto.CompletionMode = CompletionMode.AnyAssigned; dto.DescriptionMarkup = "Description"; dto.Location = "Location"; dto.Name = "Name"; dto.PatrolId = 1; dto.Shifts = new List <ShiftRecurringWorkItemDto>(); var shiftRecurringWorkItem = new ShiftRecurringWorkItemDto() { ScheduledAtHour = 10, ScheduledAtMinute = 0, ShiftAssignmentMode = ShiftAssignmentMode.Auto, ShiftId = shift.Id }; dto.Shifts.Add(shiftRecurringWorkItem); var patrol = new Api.Models.Patrol() { Id = 1, Name = "Patrol", TimeZone = TimeZoneInfo.Local.Id }; _patrolRepositoryMock.Setup(x => x.GetPatrol(patrol.Id)) .Returns(Task.FromResult(patrol)) .Verifiable(); _workItemRepository.Setup(x => x.InsertShiftRecurringWorkItem(It.Is <ShiftRecurringWorkItem>(y => y.ShiftId == shiftRecurringWorkItem.ShiftId))) .Verifiable(); _workItemRepository.Setup(x => x.InsertRecurringWorkItem(It.Is <RecurringWorkItem>(y => y.Name == dto.Name))) .Verifiable(); var now = new DateTimeOffset(2001, 1, 1, 0, 0, 0, new TimeSpan()); _systemClockMock.Setup(x => x.UtcNow).Returns(now); await _workItemService.SaveRecurringWorkItem(dto, userId, false, false); _workItemRepository.Verify(); }
public async Task <RecurringWorkItemDto> GetRecurringWorkItem(int id) { var now = _clock.UtcNow.UtcDateTime; var dto = new RecurringWorkItemDto(); _mapper.Map <RecurringWorkItem, RecurringWorkItemDto>(await _workItemRepository.GetRecurringWorkItem(id), dto); if (dto.AdminGroupId.HasValue) { dto.AdminGroup = await _groupRepository.GetGroup(dto.AdminGroupId.Value); } dto.CreatedBy = await _userRepository.GetUser(dto.CreatedByUserId); dto.Shifts = new List <ShiftRecurringWorkItemDto>(); var shifts = await _workItemRepository.GetShiftRecurringWorkItems(id); foreach (var shift in shifts) { var shiftDto = _mapper.Map <ShiftRecurringWorkItem, ShiftRecurringWorkItemDto>(shift); shiftDto.Shift = await _shiftRepository.GetShift(shiftDto.ShiftId); dto.Shifts.Add(shiftDto); } var nextOccurences = await _workItemRepository.GetWorkItems(id, now); var next = nextOccurences.OrderBy(x => x.ScheduledAt).FirstOrDefault(); dto.NextOccurenceUsers = new List <UserIdentifier>(); if (next != null) { var assignments = await _workItemRepository.GetWorkItemAssignments(next.Id); foreach (var assignment in assignments) { var user = await _userRepository.GetUser(assignment.UserId); dto.NextOccurenceUsers.Add((UserIdentifier)user); } } return(dto); }
public async Task <IActionResult> SaveRecurringWorkItem(RecurringWorkItemDto workItem) { if (User.RoleInPatrol(workItem.PatrolId).CanMaintainWorkItems()) { if (workItem.Id != default(int)) { var existing = await _workItemService.GetRecurringWorkItem(workItem.Id); if (!User.RoleInPatrol(existing.PatrolId).CanMaintainWorkItems()) { return(Forbid()); } } await _workItemService.SaveRecurringWorkItem(workItem, User.UserId()); return(Ok()); } else { return(Forbid()); } }
public async Task CanCreateRecurringWorkItem() { var dto = new RecurringWorkItemDto(); int userId = 1; dto.CompletionMode = CompletionMode.AnyAssigned; dto.DescriptionMarkup = "Description"; dto.Location = "Location"; dto.Name = "Name"; dto.PatrolId = 1; dto.RecurStart = new DateTime(2001, 1, 1, 9, 0, 0); dto.RecurEnd = new DateTime(2001, 1, 10, 9, 0, 0); dto.RecurInterval = RecurInterval.Day; dto.RecurIntervalCount = 1; var patrol = new Api.Models.Patrol() { Id = 1, Name = "Patrol", TimeZone = TimeZoneInfo.Local.Id }; _patrolRepositoryMock.Setup(x => x.GetPatrol(patrol.Id)) .Returns(Task.FromResult(patrol)) .Verifiable(); _workItemRepository.Setup(x => x.InsertRecurringWorkItem(It.Is <RecurringWorkItem>(y => y.Name == dto.Name))) .Verifiable(); var now = new DateTimeOffset(2001, 1, 1, 0, 0, 0, new TimeSpan()); _systemClockMock.Setup(x => x.UtcNow).Returns(now); await _workItemService.SaveRecurringWorkItem(dto, userId, false, false); _workItemRepository.Verify(); }
public async Task PopulateShiftWorkItemOccurences(RecurringWorkItemDto recurringWorkItem, DateTime now, int userId, Models.Patrol patrol, bool populateWorkitemAssignments = true) { var shifts = await _workItemRepository.GetShiftRecurringWorkItems(recurringWorkItem.Id); var workItems = await _workItemRepository.GetWorkItems(recurringWorkItem.Id, now); var allScheduledShiftAssignments = new List <ScheduledShiftAssignmentDto>(); foreach (var shift in shifts) { var scheduledShiftAssignments = await _shiftRepository.GetScheduledShiftAssignments(recurringWorkItem.PatrolId, from : now, shiftId : shift.ShiftId); allScheduledShiftAssignments.AddRange(scheduledShiftAssignments); var scheduledShifts = scheduledShiftAssignments.GroupBy(x => x.ScheduledShiftId); foreach (var scheduledShift in scheduledShifts) { var shiftWorkItems = workItems.Where(x => x.ScheduledShiftId == scheduledShift.Key); var shiftStartLocal = scheduledShift.First().StartsAt.UtcToPatrolLocal(patrol); if (!shiftWorkItems.Any()) { //create the work item var workItem = new WorkItem() { AdminGroupId = recurringWorkItem.AdminGroupId, CreatedAt = now, CreatedByUserId = userId, CompletionMode = recurringWorkItem.CompletionMode, DescriptionMarkup = recurringWorkItem.DescriptionMarkup, Location = recurringWorkItem.Location, Name = recurringWorkItem.Name, PatrolId = recurringWorkItem.PatrolId, RecurringWorkItemId = recurringWorkItem.Id, ScheduledShiftId = scheduledShift.Key, ScheduledAt = new DateTime(shiftStartLocal.Year, shiftStartLocal.Month, shiftStartLocal.Day, shift.ScheduledAtHour, shift.ScheduledAtMinute, 0).UtcFromPatrolLocal(patrol) }; await _workItemRepository.InsertWorkItem(workItem); } else { //realistically should only ever be 1 foreach (var workItem in shiftWorkItems) { if (!workItem.CompletedAt.HasValue && !workItem.CanceledAt.HasValue) { workItem.CompletionMode = recurringWorkItem.CompletionMode; workItem.DescriptionMarkup = recurringWorkItem.DescriptionMarkup; workItem.Location = recurringWorkItem.Location; workItem.Name = recurringWorkItem.Name; workItem.ScheduledAt = new DateTime(shiftStartLocal.Year, shiftStartLocal.Month, shiftStartLocal.Day, shift.ScheduledAtHour, shift.ScheduledAtMinute, 0).UtcFromPatrolLocal(patrol); workItem.AdminGroupId = recurringWorkItem.AdminGroupId; await _workItemRepository.UpdateWorkItem(workItem); } } } } } if (populateWorkitemAssignments) { await RecalculateShiftWorkItemAssignments(allScheduledShiftAssignments); } }
public async Task SaveRecurringWorkItem(RecurringWorkItemDto recurringWorkItem, int userId, bool populateWorkItems = true, bool populateWorkItemAssignments = true, DateTime?overrideNow = null) { var now = overrideNow ?? _clock.UtcNow.UtcDateTime; var patrol = await _patrolRepository.GetPatrol(recurringWorkItem.PatrolId); //save the recurring work item RecurringWorkItem item = null; List <ShiftRecurringWorkItem> shifts = new List <ShiftRecurringWorkItem>(); if (recurringWorkItem.Id != default(int)) { item = await _workItemRepository.GetRecurringWorkItem(recurringWorkItem.Id); shifts = (await _workItemRepository.GetShiftRecurringWorkItems(recurringWorkItem.Id)).ToList(); } else { item = new RecurringWorkItem(); item.PatrolId = recurringWorkItem.PatrolId; item.CreatedAt = now; item.CreatedByUserId = userId; } item.AdminGroupId = recurringWorkItem.AdminGroupId; item.CompletionMode = recurringWorkItem.CompletionMode; item.DescriptionMarkup = SanitizeHtml(recurringWorkItem.DescriptionMarkup); item.Location = recurringWorkItem.Location; item.Name = recurringWorkItem.Name; if (recurringWorkItem.Shifts != null && recurringWorkItem.Shifts.Any()) { item.MaximumRandomCount = recurringWorkItem.MaximumRandomCount; item.RecurEnd = null; item.RecurIntervalCount = null; item.RecurInterval = null; item.RecurStart = null; } else { item.MaximumRandomCount = null; item.RecurEnd = recurringWorkItem.RecurEnd; item.RecurInterval = recurringWorkItem.RecurInterval; item.RecurIntervalCount = recurringWorkItem.RecurIntervalCount; item.RecurStart = recurringWorkItem.RecurStart; } if (item.Id == default(int)) { await _workItemRepository.InsertRecurringWorkItem(item); recurringWorkItem.Id = item.Id; } else { await _workItemRepository.UpdateRecurringWorkItem(item); } if (recurringWorkItem.Shifts != null && recurringWorkItem.Shifts.Any()) { await shifts.DifferenceWith(recurringWorkItem.Shifts, (wi, dto) => wi.Id == dto.Id, dto => _workItemRepository.InsertShiftRecurringWorkItem(new ShiftRecurringWorkItem() { RecurringWorkItemId = item.Id, ScheduledAtHour = dto.ScheduledAtHour, ScheduledAtMinute = dto.ScheduledAtMinute, ShiftId = dto.ShiftId, ShiftAssignmentMode = dto.ShiftAssignmentMode }), wi => _workItemRepository.DeleteShiftRecurringWorkItem(wi), (wi, dto) => { wi.ScheduledAtHour = dto.ScheduledAtHour; wi.ScheduledAtMinute = dto.ScheduledAtMinute; wi.ShiftId = dto.ShiftId; wi.ShiftAssignmentMode = dto.ShiftAssignmentMode; return(_workItemRepository.UpdateShiftRecurringWorkItem(wi)); } ); } else { foreach (var shift in shifts) { await _workItemRepository.DeleteShiftRecurringWorkItem(shift); } } if (populateWorkItems) { //save shift recurring work items if (recurringWorkItem.Shifts != null && recurringWorkItem.Shifts.Any()) { await this.PopulateShiftWorkItemOccurences(recurringWorkItem, now, userId, patrol, populateWorkItemAssignments); } else if (recurringWorkItem.RecurStart.HasValue && recurringWorkItem.RecurEnd.HasValue && recurringWorkItem.RecurInterval.HasValue && recurringWorkItem.RecurIntervalCount.HasValue) { await this.PopulateTimedWorkItemOccurences(recurringWorkItem, userId, recurringWorkItem.NextOccurenceUsers != null?recurringWorkItem.NextOccurenceUsers.Select(x => x.Id).ToList() : null, now, populateWorkItemAssignments); } else { throw new InvalidOperationException("Invalid recurrence specification"); } } }
public async Task CanCreateWorkItemAssignmentsForRecurringWorkitem() { var dto = new RecurringWorkItemDto(); int userId = 1; var shift = new Shift() { Name = "Shift", Id = 60, StartHour = 9, EndHour = 17 }; dto.CompletionMode = CompletionMode.AnyAssigned; dto.DescriptionMarkup = "Description"; dto.Location = "Location"; dto.Name = "Name"; dto.PatrolId = 1; dto.Shifts = new List <ShiftRecurringWorkItemDto>(); var shiftRecurringWorkItem = new ShiftRecurringWorkItemDto() { ScheduledAtHour = 10, ScheduledAtMinute = 0, ShiftAssignmentMode = ShiftAssignmentMode.Auto, ShiftId = shift.Id }; dto.Shifts.Add(shiftRecurringWorkItem); var now = new DateTimeOffset(2001, 1, 1, 0, 0, 0, new TimeSpan()); _systemClockMock.Setup(x => x.UtcNow).Returns(now); var assignments = new List <ScheduledShiftAssignmentDto>(); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 1, AssignedUser = new UserIdentifier() { Id = 1, FirstName = "1" }, StartsAt = new DateTime(2001, 1, 1, 9, 0, 0), EndsAt = new DateTime(2001, 1, 1, 17, 0, 0), ScheduledShiftId = 1, Shift = shift }); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 2, AssignedUser = new UserIdentifier() { Id = 2, FirstName = "2" }, StartsAt = new DateTime(2001, 1, 1, 9, 0, 0), EndsAt = new DateTime(2001, 1, 1, 17, 0, 0), ScheduledShiftId = 1, Shift = shift }); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 3, AssignedUser = new UserIdentifier() { Id = 1, FirstName = "1" }, StartsAt = new DateTime(2001, 1, 2, 9, 0, 0), EndsAt = new DateTime(2001, 1, 2, 17, 0, 0), ScheduledShiftId = 2, Shift = shift }); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 4, AssignedUser = new UserIdentifier() { Id = 2, FirstName = "2" }, StartsAt = new DateTime(2001, 1, 2, 9, 0, 0), EndsAt = new DateTime(2001, 1, 2, 17, 0, 0), ScheduledShiftId = 2, Shift = shift }); //_shiftRepositoryMock.Setup(x => x.GetScheduledShiftAssignments(dto.PatrolId, null, now.UtcDateTime, null, null, null, null, dto.Shifts.First().ShiftId)) // .Returns(Task.FromResult(assignments.AsEnumerable())) // .Verifiable(); _workItemRepository.Setup(x => x.GetWorkItemsForShifts(It.Is <List <int> >(x => assignments.Select(x => x.ScheduledShiftId).Distinct().ToArray().SequenceEqual(x.ToArray())))) .Returns(Task.FromResult(new List <WorkItem>() { new WorkItem() { Id = 1, ScheduledShiftId = 1, RecurringWorkItemId = 1, CompletionMode = dto.CompletionMode, DescriptionMarkup = dto.DescriptionMarkup, Name = dto.Name, Location = dto.Location, ScheduledAt = new DateTime(2001, 1, 1, 9, 0, 0) }, new WorkItem() { Id = 2, ScheduledShiftId = 2, RecurringWorkItemId = 1, CompletionMode = dto.CompletionMode, DescriptionMarkup = dto.DescriptionMarkup, Name = dto.Name, Location = dto.Location, ScheduledAt = new DateTime(2001, 1, 2, 9, 0, 0) } }.AsEnumerable())) .Verifiable(); _workItemRepository.Setup(x => x.GetWorkItemAssignmentsForShifts(It.Is <List <int> >(x => assignments.Select(x => x.ScheduledShiftId).Distinct().ToArray().SequenceEqual(x.ToArray())))) .Returns(Task.FromResult(new List <WorkItemAssignment>().AsEnumerable())) .Verifiable(); _workItemRepository.Setup(x => x.GetRecurringWorkItemsForShifts(It.Is <List <int> >(x => assignments.Select(x => x.ScheduledShiftId).Distinct().ToArray().SequenceEqual(x.ToArray())))) .Returns(Task.FromResult(new List <RecurringWorkItem>() { new RecurringWorkItem() { CompletionMode = dto.CompletionMode, DescriptionMarkup = dto.DescriptionMarkup, Id = 1, Location = dto.Location, Name = dto.Name, PatrolId = dto.PatrolId, } }.AsEnumerable())) .Verifiable(); _workItemRepository.Setup(x => x.GetShiftRecurringWorkItemsForShifts(It.Is <List <int> >(x => assignments.Select(x => x.ScheduledShiftId).Distinct().ToArray().SequenceEqual(x.ToArray())))) .Returns(Task.FromResult(new List <ShiftRecurringWorkItem>() { new ShiftRecurringWorkItem() { Id = 1, RecurringWorkItemId = 1, ScheduledAtHour = shiftRecurringWorkItem.ScheduledAtHour, ScheduledAtMinute = shiftRecurringWorkItem.ScheduledAtMinute, ShiftAssignmentMode = shiftRecurringWorkItem.ShiftAssignmentMode, ShiftId = shift.Id } }.AsEnumerable())) .Verifiable(); _workItemRepository.Setup(x => x.InsertWorkItemAssignment(It.Is <WorkItemAssignment>(y => y.UserId == 1))) .Verifiable(); _workItemRepository.Setup(x => x.InsertWorkItemAssignment(It.Is <WorkItemAssignment>(y => y.UserId == 2))) .Verifiable(); await _workItemService.RecalculateShiftWorkItemAssignments(assignments); _workItemRepository.Verify(); }
public async Task CanCreateWorkItemsFromShiftRecurringWorkitem() { var dto = new RecurringWorkItemDto(); int userId = 1; var shift = new Shift() { Name = "Shift", Id = 60, StartHour = 9, EndHour = 17 }; dto.CompletionMode = CompletionMode.AnyAssigned; dto.DescriptionMarkup = "Description"; dto.Location = "Location"; dto.Name = "Name"; dto.PatrolId = 1; dto.Shifts = new List <ShiftRecurringWorkItemDto>(); var shiftRecurringWorkItem = new ShiftRecurringWorkItemDto() { ScheduledAtHour = 10, ScheduledAtMinute = 0, ShiftAssignmentMode = ShiftAssignmentMode.Auto, ShiftId = shift.Id }; dto.Shifts.Add(shiftRecurringWorkItem); var patrol = new Api.Models.Patrol() { Id = 1, Name = "Patrol", TimeZone = TimeZoneInfo.Local.Id }; _workItemRepository.Setup(x => x.GetShiftRecurringWorkItems(It.IsAny <int>())) .Returns(Task.FromResult(new List <ShiftRecurringWorkItem>() { new ShiftRecurringWorkItem() { RecurringWorkItemId = 0, ScheduledAtHour = 9, ScheduledAtMinute = 0, ShiftAssignmentMode = ShiftAssignmentMode.Auto, ShiftId = shift.Id } }.AsEnumerable())) .Verifiable(); var now = new DateTimeOffset(2001, 1, 1, 0, 0, 0, new TimeSpan()); _systemClockMock.Setup(x => x.UtcNow).Returns(now); _workItemRepository.Setup(x => x.GetWorkItems(It.IsAny <int>(), now.UtcDateTime)) .Returns(Task.FromResult(new List <WorkItem>() { }.AsEnumerable())) .Verifiable(); var assignments = new List <ScheduledShiftAssignmentDto>(); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 1, AssignedUser = new UserIdentifier() { Id = 1, FirstName = "1" }, StartsAt = new DateTime(2001, 1, 1, 9, 0, 0), EndsAt = new DateTime(2001, 1, 1, 17, 0, 0), ScheduledShiftId = 1, Shift = shift }); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 2, AssignedUser = new UserIdentifier() { Id = 2, FirstName = "2" }, StartsAt = new DateTime(2001, 1, 1, 9, 0, 0), EndsAt = new DateTime(2001, 1, 1, 17, 0, 0), ScheduledShiftId = 1, Shift = shift }); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 3, AssignedUser = new UserIdentifier() { Id = 1, FirstName = "1" }, StartsAt = new DateTime(2001, 1, 2, 9, 0, 0), EndsAt = new DateTime(2001, 1, 2, 17, 0, 0), ScheduledShiftId = 2, Shift = shift }); assignments.Add(new ScheduledShiftAssignmentDto() { Id = 4, AssignedUser = new UserIdentifier() { Id = 2, FirstName = "2" }, StartsAt = new DateTime(2001, 1, 2, 9, 0, 0), EndsAt = new DateTime(2001, 1, 2, 17, 0, 0), ScheduledShiftId = 2, Shift = shift }); _shiftRepositoryMock.Setup(x => x.GetScheduledShiftAssignments(dto.PatrolId, null, now.UtcDateTime, null, null, null, null, dto.Shifts.First().ShiftId)) .Returns(Task.FromResult(assignments.AsEnumerable())) .Verifiable(); _workItemRepository.Setup(x => x.InsertWorkItem(It.Is <WorkItem>(y => y.ScheduledShiftId == 1))) .Verifiable(); _workItemRepository.Setup(x => x.InsertWorkItem(It.Is <WorkItem>(y => y.ScheduledShiftId == 2))) .Verifiable(); await _workItemService.PopulateShiftWorkItemOccurences(dto, now.UtcDateTime, userId, patrol, false); _workItemRepository.Verify(); _shiftRepositoryMock.Verify(); }