private static List <string> FindNewAvailableSlots(InstructorSlots oldInstructorSlots, InstructorSlots newInstructorSlots) { if (newInstructorSlots == null) { throw new ArgumentNullException("newInstructorSlots"); } if (oldInstructorSlots == null) { oldInstructorSlots = new InstructorSlots { InstructorInitials = newInstructorSlots.InstructorInitials, Slots = new List <Slot>() }; } if (oldInstructorSlots.InstructorInitials != newInstructorSlots.InstructorInitials) { throw new InstructorScanException($"Old instructor slot initials '{oldInstructorSlots.InstructorInitials}' does not match new instructor slot initials '{newInstructorSlots.InstructorInitials}'"); } var messages = new List <string>(); var newFeeSlots = newInstructorSlots.Slots.Where(s => s.Availability == AvailabilityNames.Free).ToList(); foreach (var newFreeSlot in newFeeSlots) { var matchedOldLSlot = oldInstructorSlots.Slots.SingleOrDefault(s => s.Time == newFreeSlot.Time); if (matchedOldLSlot == null || (matchedOldLSlot.Availability != newFreeSlot.Availability)) { messages.Add($"{newFreeSlot.Time} is available"); } } return(messages); }
public async Task <CalendarDay> GetBookings(DateTime date, List <Instructor> instructors) { if (_httpClient == null) { await InitHttpClientAsync(); } var bookingPageUrl = new Uri(_rootUrl, $"{_appSettings.BookingPage}?dt={date.ToString("dd/MM/yyyy")}"); var bookingPageResponse = await _httpClient.GetAsync(bookingPageUrl); bookingPageResponse.EnsureSuccessStatusCode(); var bookingPageContents = await bookingPageResponse.Content.ReadAsStringAsync(); var bookingPageParser = new HtmlDocument(); bookingPageParser.LoadHtml(bookingPageContents); var tableBookings = bookingPageParser.DocumentNode.SelectSingleNode("//table[@id='tblBookings']"); if (tableBookings == null) { throw new InstructorScanException("Could not find table with an id of 'tblBookings'"); } var times = new List <string>(); var timesTDNodes = tableBookings.SelectNodes(".//td[@class='TimeHeaderHalf']"); foreach (var td in timesTDNodes) { var time = td.GetDirectInnerText(); times.Add(time); times.Add($"{time}:30"); } //- Find row where tr / td innerText = 'Instructor Name' var instructorSlotsList = new List <InstructorSlots>(); foreach (var instctr in instructors) { var instructorSlots = new InstructorSlots { InstructorInitials = instctr.Initials, Slots = new List <Slot>() }; var instructorRowNode = tableBookings.SelectSingleNode($".//tr[td='{instctr.Name}']"); if (instructorRowNode != null) { _logger.LogInformation("Found instructor row"); var originalBookingTds = instructorRowNode.SelectNodes(".//td[not(@class='HeaderCellAc')]"); var bookings = new List <string>(); foreach (var tdNode in originalBookingTds) { var status = BookingStatus(tdNode); var statusCount = GetColSpanValue(tdNode); for (var i = 0; i < statusCount; i++) { bookings.Add(status); } } if (times.Count != bookings.Count) { throw new InstructorScanException("Eeek!! Time slot count doesn't match bookings count!"); } for (var i = 0; i < bookings.Count; i++) { instructorSlots.Slots.Add(new Slot { Availability = bookings[i], Time = times[i] }); } } instructorSlotsList.Add(instructorSlots); } var calendarDay = new CalendarDay { InstructorSlots = instructorSlotsList }; calendarDay.SetDate(date); return(calendarDay); }