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();
        }
示例#2
0
        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);
        }
示例#3
0
        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();
        }
示例#5
0
        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);
            }
        }
示例#6
0
        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();
        }