Example #1
0
 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);
        }