public async Task <CurrentTimeEntryDto> ClockIn(int patrolId, int userId, DateTime?now = null) { if (!now.HasValue) { now = _systemClock.UtcNow.UtcDateTime; } var existingEntries = await _timeEntryRepository.GetActiveTimeEntries(patrolId, userId); //if there are existing entries we don't need to do anything if (!existingEntries.Any()) { var result = new CurrentTimeEntryDto(); var entry = new TimeEntry() { ClockIn = now.Value, PatrolId = patrolId, UserId = userId }; await _timeEntryRepository.InsertTimeEntry(entry); result.TimeEntry = entry; //if the patrol has schedulingenabled, try to find a shift to associate var patrol = await _patrolRepository.GetPatrol(patrolId); if (patrol.EnableScheduling) { //find shifts for the user that occur in the next day //TODO: does this range need to be configurable by patrol? eg: how early can you allow clocking in? var shifts = await _shiftRepository.GetScheduledShiftAssignments(patrolId, userId, entry.ClockIn, entry.ClockIn + new TimeSpan(1, 0, 0, 0), ShiftStatus.Assigned); shifts = shifts.OrderBy(x => x.StartsAt); if (shifts.Any()) { //if there is more than one match, associate the one that starts the earliest var shift = shifts.First(); var scheduledShift = await _shiftRepository.GetScheduledShift(shift.ScheduledShiftId); var timeEntryScheduledShiftAssignment = new TimeEntryScheduledShiftAssignment() { ScheduledShiftAssignmentId = shift.Id, TimeEntryId = entry.Id }; await _timeEntryRepository.InsertTimeEntryScheduledShiftAssignment(timeEntryScheduledShiftAssignment); result.TimeEntryScheduledShiftAssignment = timeEntryScheduledShiftAssignment; result.ScheduledShift = scheduledShift; if (scheduledShift.ShiftId.HasValue) { result.Shift = await _shiftRepository.GetShift(scheduledShift.ShiftId.Value); } if (scheduledShift.GroupId.HasValue) { result.Group = await _groupRepository.GetGroup(scheduledShift.GroupId.Value); } } } return(result); } else { var result = new CurrentTimeEntryDto(); var entry = existingEntries.Where(x => x.ClockIn < now).OrderBy(x => x.ClockIn).FirstOrDefault(); var timeEntryScheduledShiftAssignments = await _timeEntryRepository.GetScheduledShiftAssignmentsForTimeEntry(entry.Id); if (timeEntryScheduledShiftAssignments.Any()) { var tessa = timeEntryScheduledShiftAssignments.FirstOrDefault(); result.TimeEntryScheduledShiftAssignment = tessa; var assignment = await _shiftRepository.GetScheduledShiftAssignment(tessa.ScheduledShiftAssignmentId); result.ScheduledShift = await _shiftRepository.GetScheduledShift(assignment.ScheduledShiftId); if (result.ScheduledShift.ShiftId.HasValue) { result.Shift = await _shiftRepository.GetShift(result.ScheduledShift.ShiftId.Value); } if (result.ScheduledShift.GroupId.HasValue) { result.Group = await _groupRepository.GetGroup(result.ScheduledShift.GroupId.Value); } } return(result); } }