コード例 #1
0
        public async Task <IActionResult> CreateScheduledShift(ScheduledShiftUpdateDto dto)
        {
            var now = _clock.UtcNow.UtcDateTime;

            if (User.RoleInPatrol(dto.PatrolId).CanMaintainSchedule() &&
                (
                    (dto.Day.HasValue && dto.Day.Value > now) ||
                    (dto.StartsAt.HasValue && dto.StartsAt.Value > now)
                ))
            {
                var shift = await _scheduleService.ScheduleShift(dto);

                return(Ok(shift));
            }
            else
            {
                return(Forbid());
            }
        }
コード例 #2
0
        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));
        }