Example #1
0
        public async Task CanGetMissingTimeEntries()
        {
            var now      = new DateTime(2001, 1, 1);
            int userId   = 1;
            int patrolId = 1;

            var scheduledShift = new ScheduledShift()
            {
                StartsAt        = now - new TimeSpan(1, 0, 0),
                EndsAt          = now + new TimeSpan(1, 0, 0),
                DurationSeconds = (int)(new TimeSpan(2, 0, 0)).TotalSeconds,
                PatrolId        = patrolId,
            };
            await _shiftRepository.InsertScheduledShift(scheduledShift);

            var scheduledShiftAssignment = new ScheduledShiftAssignment()
            {
                AssignedUserId   = userId,
                ScheduledShiftId = scheduledShift.Id,
                Status           = ShiftStatus.Assigned
            };
            await _shiftRepository.InsertScheduledShiftAssignment(scheduledShiftAssignment);


            var entries = await _timeEntryRepository.GetMissingTimeEntries(patrolId, now);


            Assert.AreEqual(1, entries.Count());
        }
        public async Task <ScheduledShiftAssignment> AddScheduledShiftAssignment(int scheduledShiftId, int?userId)
        {
            var scheduledShiftAssignment = new ScheduledShiftAssignment()
            {
                AssignedUserId         = userId,
                OriginalAssignedUserId = userId,
                ScheduledShiftId       = scheduledShiftId,
                Status = userId.HasValue ? ShiftStatus.Assigned : ShiftStatus.Released
            };
            await _shiftRepository.InsertScheduledShiftAssignment(scheduledShiftAssignment);

            //notify assignee
            if (userId.HasValue)
            {
                var shift = await _shiftRepository.GetScheduledShift(scheduledShiftId);

                var patrol = await _patrolRepository.GetPatrol(shift.PatrolId);

                var newAssignee = await _userRepository.GetUser(userId.Value);

                await _emailService.SendShiftAdded(new List <User>() { newAssignee }, patrol, shift);

                //allocate any work items for the shift to the new assignee
                await _shiftWorkItemService.AddWorkItemsToNewShiftOccurence(shift);
            }

            return(scheduledShiftAssignment);
        }
Example #3
0
        public async Task CanUpdateTimeEntryScheduledShiftAssignment()
        {
            var now      = new DateTime(2001, 1, 1);
            int userId   = 1;
            int patrolId = 1;

            var entry = new TimeEntry()
            {
                ClockIn  = now,
                PatrolId = patrolId,
                UserId   = userId
            };
            await _timeEntryRepository.InsertTimeEntry(entry);

            var scheduledShift = new ScheduledShift()
            {
                StartsAt        = now,
                EndsAt          = now + new TimeSpan(1, 0, 0),
                DurationSeconds = (int)(new TimeSpan(1, 0, 0)).TotalSeconds,
                PatrolId        = patrolId,
            };
            await _shiftRepository.InsertScheduledShift(scheduledShift);

            var scheduledShiftAssignment = new ScheduledShiftAssignment()
            {
                AssignedUserId   = userId,
                ScheduledShiftId = scheduledShift.Id,
                Status           = ShiftStatus.Assigned
            };
            await _shiftRepository.InsertScheduledShiftAssignment(scheduledShiftAssignment);

            var timeEntryScheduledShiftAssignment = new TimeEntryScheduledShiftAssignment()
            {
                ScheduledShiftAssignmentId = scheduledShiftAssignment.Id,
                TimeEntryId = entry.Id
            };
            await _timeEntryRepository.InsertTimeEntryScheduledShiftAssignment(timeEntryScheduledShiftAssignment);

            timeEntryScheduledShiftAssignment.DurationSeconds = 1000;
            await _timeEntryRepository.UpdateTimeEntryScheduledShiftAssignment(timeEntryScheduledShiftAssignment);

            var after = await _timeEntryRepository.GetTimeEntryScheduledShiftAssignment(timeEntryScheduledShiftAssignment.Id);


            Assert.AreEqual(1000, after.DurationSeconds);
        }
        public async Task CanDeleteScheduledShiftAssignment()
        {
            var before = new ScheduledShiftAssignment()
            {
                AssignedUserId         = 1,
                OriginalAssignedUserId = 1,
                ScheduledShiftId       = 1,
                Status = ShiftStatus.Assigned,
            };

            await _shiftRepository.InsertScheduledShiftAssignment(before);

            await _shiftRepository.DeleteScheduledShiftAssignment(before);

            var after = await _shiftRepository.GetScheduledShiftAssignment(before.Id);

            Assert.IsNull(after);
        }
        public async Task CanInsertScheduledShiftAssignment()
        {
            var before = new ScheduledShiftAssignment()
            {
                AssignedUserId         = 1,
                OriginalAssignedUserId = 1,
                ScheduledShiftId       = 1,
                Status = ShiftStatus.Assigned,
            };

            await _shiftRepository.InsertScheduledShiftAssignment(before);

            var after = await _shiftRepository.GetScheduledShiftAssignment(before.Id);

            Assert.AreEqual(before.AssignedUserId, after.AssignedUserId);
            Assert.AreEqual(before.OriginalAssignedUserId, after.OriginalAssignedUserId);
            Assert.AreEqual(before.ScheduledShiftId, after.ScheduledShiftId);
            Assert.AreEqual(before.Status, after.Status);
        }
        public async Task <ScheduledShift> ScheduleShift(ScheduledShiftUpdateDto dto)
        {
            var patrol = await _patrolRepository.GetPatrol(dto.PatrolId);

            Group        group        = null;
            IList <User> groupMembers = null;

            if (dto.GroupId.HasValue)
            {
                group = await _groupRepository.GetGroup(dto.GroupId.Value);

                groupMembers = (await _groupRepository.GetUsersInGroup(dto.GroupId.Value)).ToList();
            }

            Shift shift = null;

            if (dto.StartsAt.HasValue && dto.EndsAt.HasValue && !dto.ShiftId.HasValue)
            {
                var localizedStart = dto.StartsAt.Value.UtcToPatrolLocal(patrol);
                var localizedEnd   = dto.EndsAt.Value.UtcToPatrolLocal(patrol);
                var shifts         = await _shiftRepository.GetShifts(dto.PatrolId, localizedStart.Hour, localizedStart.Minute, localizedEnd.Hour, localizedEnd.Minute);

                if (shifts.Any())
                {
                    shift       = shifts.First();
                    dto.ShiftId = shift.Id;
                }
            }
            else if (dto.ShiftId.HasValue && dto.Day.HasValue)
            {
                shift = await _shiftRepository.GetShift(dto.ShiftId.Value);

                if (!dto.StartsAt.HasValue)
                {
                    var start = new DateTime(dto.Day.Value.Year, dto.Day.Value.Month, dto.Day.Value.Day, shift.StartHour, shift.StartMinute, 0, 0, DateTimeKind.Unspecified);
                    dto.StartsAt = start.UtcFromPatrolLocal(patrol);
                }
                if (!dto.EndsAt.HasValue)
                {
                    var end = new DateTime(dto.Day.Value.Year, dto.Day.Value.Month, dto.Day.Value.Day, shift.EndHour, shift.EndMinute, 0, 0, DateTimeKind.Unspecified);
                    dto.EndsAt = end.UtcFromPatrolLocal(patrol);
                }
            }
            else
            {
                throw new InvalidOperationException("Scheduled shift must provide either start+end or day+shift");
            }

            //by this point we should have filled in the dto as best we can and can now persist

            ScheduledShift scheduledShift = null;
            List <ScheduledShiftAssignment> assignments    = null;
            List <ScheduledShiftAssignment> newAssignments = new List <ScheduledShiftAssignment>();

            if (dto.Id != default(int))
            {
                scheduledShift = await _shiftRepository.GetScheduledShift(dto.Id);

                scheduledShift.StartsAt        = dto.StartsAt.Value;
                scheduledShift.EndsAt          = dto.EndsAt.Value;
                scheduledShift.GroupId         = group != null ? (int?)group.Id : null;
                scheduledShift.ShiftId         = shift != null ? (int?)shift.Id : null;
                scheduledShift.DurationSeconds = (int)(scheduledShift.EndsAt - scheduledShift.StartsAt).TotalSeconds;
                await _shiftRepository.UpdateScheduledShift(scheduledShift);

                assignments = (await _shiftRepository.GetScheduledShiftAssignmentsForScheduledShift(dto.Id)).ToList();
            }
            else
            {
                //make sure there's not an existing shift with the same start/end
                var existing = await _shiftRepository.GetScheduledShifts(dto.PatrolId, dto.StartsAt.Value, dto.EndsAt.Value);

                if (existing.Any())
                {
                    scheduledShift = existing.First();
                    dto.Id         = scheduledShift.Id;

                    bool updated = false;
                    if (!scheduledShift.GroupId.HasValue && group != null)
                    {
                        scheduledShift.GroupId = group.Id;
                        updated = true;
                    }
                    if (!scheduledShift.ShiftId.HasValue && shift != null)
                    {
                        scheduledShift.ShiftId = shift.Id;
                        updated = true;
                    }
                    if (updated)
                    {
                        scheduledShift.DurationSeconds = (int)(scheduledShift.EndsAt - scheduledShift.StartsAt).TotalSeconds;
                        await _shiftRepository.UpdateScheduledShift(scheduledShift);
                    }

                    assignments = (await _shiftRepository.GetScheduledShiftAssignmentsForScheduledShift(dto.Id)).ToList();
                }
                else
                {
                    scheduledShift = new ScheduledShift()
                    {
                        PatrolId = dto.PatrolId,
                        GroupId  = group != null ? (int?)group.Id : null,
                        ShiftId  = shift != null ? (int?)shift.Id : null,
                        StartsAt = dto.StartsAt.Value,
                        EndsAt   = dto.EndsAt.Value
                    };
                    scheduledShift.DurationSeconds = (int)(scheduledShift.EndsAt - scheduledShift.StartsAt).TotalSeconds;
                    await _shiftRepository.InsertScheduledShift(scheduledShift);

                    assignments = new List <ScheduledShiftAssignment>();

                    //populate with work items if necassary
                    await _shiftWorkItemService.AddWorkItemsToNewShiftOccurence(scheduledShift);
                }
            }

            if (group != null)
            {
                foreach (var groupMember in groupMembers)
                {
                    var existing = assignments.FirstOrDefault(x => x.OriginalAssignedUserId == groupMember.Id || x.AssignedUserId == groupMember.Id || x.ClaimedByUserId == groupMember.Id);
                    if (existing == null)
                    {
                        var ssa = new ScheduledShiftAssignment()
                        {
                            Status                 = ShiftStatus.Assigned,
                            AssignedUserId         = groupMember.Id,
                            OriginalAssignedUserId = groupMember.Id,
                            ScheduledShiftId       = scheduledShift.Id
                        };
                        assignments.Add(ssa);
                        await _shiftRepository.InsertScheduledShiftAssignment(ssa);

                        newAssignments.Add(ssa);
                    }
                    else if (existing.Status == ShiftStatus.Claimed && existing.ClaimedByUserId == groupMember.Id)
                    {
                        existing.AssignedUserId = existing.ClaimedByUserId.Value;
                        existing.Status         = ShiftStatus.Assigned;
                        await _shiftRepository.UpdateScheduledShiftAssignment(existing);
                    }
                }
            }

            if (dto.AssignUserIds != null)
            {
                foreach (var id in dto.AssignUserIds)
                {
                    var existing = assignments.FirstOrDefault(x => x.OriginalAssignedUserId == id || x.AssignedUserId == id || x.ClaimedByUserId == id);
                    if (existing == null || !id.HasValue)
                    {
                        var ssa = new ScheduledShiftAssignment()
                        {
                            Status                 = id.HasValue ? ShiftStatus.Assigned : ShiftStatus.Released,
                            AssignedUserId         = id,
                            OriginalAssignedUserId = id,
                            ScheduledShiftId       = scheduledShift.Id
                        };
                        assignments.Add(ssa);
                        await _shiftRepository.InsertScheduledShiftAssignment(ssa);

                        newAssignments.Add(ssa);
                    }
                    else if (existing.Status == ShiftStatus.Claimed && existing.ClaimedByUserId == id)
                    {
                        existing.AssignedUserId = existing.ClaimedByUserId.Value;
                        existing.Status         = ShiftStatus.Assigned;
                        await _shiftRepository.UpdateScheduledShiftAssignment(existing);
                    }
                }
            }

            var assigneeUserIds = newAssignments.Where(x => x.AssignedUserId.HasValue).Select(x => x.AssignedUserId.Value).Distinct().ToList();

            if (assigneeUserIds.Count > 0)
            {
                var newAssignees = await _userRepository.GetUsers(assigneeUserIds);

                await _emailService.SendShiftAdded(newAssignees.ToList(), patrol, scheduledShift);
            }

            //todo: delete things that aren't there?  seems risky if we found the shift by time not id etc

            return(await _shiftRepository.GetScheduledShift(scheduledShift.Id));
        }
 public Task DeleteScheduledShiftAssignment(ScheduledShiftAssignment shift)
 {
     return(_connection.DeleteAsync(shift));
 }
        public async Task InsertScheduledShiftAssignment(ScheduledShiftAssignment shift)
        {
            var id = (int)await _connection.InsertAsync(shift);

            shift.Id = id;
        }