public IActionResult Get([FromQuery] SuggestionsQueryParams parameters) { if (ModelState.IsValid) { return(Ok(new { query = parameters, suggestions = _suggestionLogic.GetSuggestions(parameters) })); } return(BadRequest()); }
/// <summary> /// Returns a suggestions-list with all bookable times and dates /// </summary> public IList <SuggestionDto> GetSuggestions(SuggestionsQueryParams parameters) { var fromDate = DateTimeOffset.Parse($"{parameters.FromDate} {parameters.OfficehoursStart}"); var toDate = DateTimeOffset.Parse($"{parameters.ToDate} {parameters.OfficehoursEnd}"); var desiredSuggestions = InitializeSuggestions(parameters, fromDate, toDate); var availableSuggestions = GetAvailableSuggestions(desiredSuggestions, parameters, fromDate, toDate); return(availableSuggestions); }
/// <summary> /// Creates and returns a list with all desired time-bookings according to the inputs made by the user /// </summary> private List <SuggestionDto> InitializeSuggestions(SuggestionsQueryParams parameters, DateTimeOffset fromDate, DateTimeOffset toDate) { var suggestions = new List <SuggestionDto>(); while (fromDate <= toDate) { var suggestion = new SuggestionDto { Date = fromDate.GetShortDate() }; var officeHoursStart = DateTimeOffset.Parse($"{fromDate.GetShortDate()} {parameters.OfficehoursStart}"); var officeHoursEnds = DateTimeOffset.Parse($"{fromDate.GetShortDate()} {parameters.OfficehoursEnd}").AddMinutes(-parameters.MeetingLength); while (officeHoursStart <= officeHoursEnds) { suggestion.StartTimes.Add(officeHoursStart.GetTime()); officeHoursStart = officeHoursStart.AddMinutes(AppointmentTimeInterval); } suggestions.Add(suggestion); fromDate = fromDate.AddDays(1); } return(suggestions); }
/// <summary> /// Returns a list with all the times which are available for booking /// </summary> private List <SuggestionDto> GetAvailableSuggestions(List <SuggestionDto> suggestions, SuggestionsQueryParams parameters, DateTimeOffset fromDate, DateTimeOffset toDate) { var busyTimesForEmployees = _busyTimeRepository.GetBusyTimes(parameters.Employees) .Where(x => x.StartTime >= fromDate && x.EndTime <= toDate) .OrderBy(x => x.StartTime) .ToList(); var busyTimes = GetBusyTimesOrderedList(busyTimesForEmployees); foreach (var suggestion in suggestions) { // if there is no busy times on this particular date then skip it, i.e. keep desired times as is if (!busyTimesForEmployees.Any(x => x.StartTime.GetShortDate() == suggestion.Date)) { continue; } var availableStartTimes = new List <string>(); var officeHoursEnds = DateTimeOffset.Parse($"{suggestion.Date} {parameters.OfficehoursEnd}"); foreach (var startTime in suggestion.StartTimes) { var startTimeDate = DateTimeOffset.Parse($"{suggestion.Date} {startTime}"); var isAvailable = false; for (int i = 0; i < busyTimes.Count; i++) { // Check if current startTime, while considering meetingLength, is available when it's before earliest busyTime. if (i == 0 && busyTimes[i] >= startTimeDate.AddMinutes(parameters.MeetingLength)) { isAvailable = true; break; } // On the last busyTime we want to check if it's still within the office hour // while taking into consideration the meetinglength if (i == busyTimes.Count - 1) { if (busyTimes[i].AddMinutes(parameters.MeetingLength) <= officeHoursEnds && startTimeDate >= busyTimes[i]) { isAvailable = true; break; } } // Check if we have available time between the current and the next busyTimes else if ((busyTimes[i + 1] - busyTimes[i]).TotalMinutes != BusyTimeIdentifier && startTimeDate >= busyTimes[i] && startTimeDate.AddMinutes(parameters.MeetingLength) <= busyTimes[i + 1]) { isAvailable = true; break; } } if (isAvailable) { availableStartTimes.Add(startTimeDate.GetTime()); } } suggestion.StartTimes = availableStartTimes; } return(suggestions); }