public async Task <AppointmentAvailabilityResponse> IsAvailableAsync(AppointmentRequest appointmentRequest) { AppointmentAvailabilityResponse response = new AppointmentAvailabilityResponse(); var dateTimeToCheck = appointmentRequest.StartDateTime.Add(minimumTimeBeforeClose); DateTime nowDateTime = DateTime.UtcNow.AddHours(ShopHours.UTC_to_PST_Hours); // convert to PST. await Hours.LoadAsync(this, nowDateTime.Date); // today's hours // check holidays // is it in the past? if (dateTimeToCheck < nowDateTime) { response.ValidationResults.Add(new ValidationResult() { Message = "Appointments can't be scheduled before right now. " }); return(response); } // is the store open? await Hours.LoadAsync(this, dateTimeToCheck); if (!Hours.Exists) { response.ValidationResults.Add(new ValidationResult() { Message = "The shop isn't open that day. " }); return(response); } // is it between hours bool isWithinHours = Hours.IsWithinHours(appointmentRequest.StartDateTime); // does it meet the minimum window? bool meetsMinimum = Hours.IsWithinHours(dateTimeToCheck); if (isWithinHours && meetsMinimum) { response.IsAvailable = true; } else if (!isWithinHours) { response.ValidationResults.Add(new ValidationResult() { Message = $"The appointment isn't between store hours of {Hours.FormattedDayHours()}. " }); } else if (!meetsMinimum) { response.ValidationResults.Add(new ValidationResult() { Message = $"The appointment needs to be at least {minimumTimeBeforeClose} minutes before closing. Hours are {Hours.FormattedDayHours()}. " }); } return(response); }
public async Task <AppointmentAvailabilityResponse> IsAvailableAsync() { DateTime nowDateTime = DateTime.UtcNow.AddHours(ShopHours.UTC_to_PST_Hours); if (StartDateTime < nowDateTime) { var response = new AppointmentAvailabilityResponse() { IsAvailable = false }; response.ValidationResults.Add(new ValidationResult() { Message = "That date and time is in the past." }); return(response); } StartDateTime = await roundingRules.RoundDateTimeAsync(StartDateTime); TimeSpan difference = nowDateTime - StartDateTime; // we need to adjust the rounding for any rounding to a few minutes in the past. while (StartDateTime < nowDateTime && difference < TimeSpan.FromMinutes(1)) { StartDateTime = await roundingRules.RoundDateTimeAsync(StartDateTime.AddMinutes(5)); } var shopResponse = await Shop.IsAvailableAsync(this); BarberAvailabilityResponse barberResponse = await RequestedBarber.IsAvailableAsync(this); if (RequestedBarber != barberResponse.Barber) { // this happens if the user requests "Anyone" RequestedBarber = barberResponse.Barber; } if (shopResponse.IsAvailable && barberResponse.IsAvailable) { return(new AppointmentAvailabilityResponse() { IsAvailable = true, SuggestedRequest = this }); } else if (shopResponse.IsAvailable && !barberResponse.IsAvailable) { // barber is not available // we could either suggest the next available barber's time // and we could find when the barber is available next AppointmentRequest suggestedRequest = await RequestedBarber.NextAvailableRequestAsync(this); var response = new AppointmentAvailabilityResponse() { IsAvailable = false, SuggestedRequest = suggestedRequest }; response.ValidationResults.AddRange(barberResponse.ValidationResults); return(response); } else { // shop is not available // show the hours for the week and suggest the next available appointment AppointmentRequest nextRequest = null; AppointmentAvailabilityResponse response = new AppointmentAvailabilityResponse() { IsAvailable = false }; if (!shopResponse.IsAvailable) { nextRequest = new AppointmentRequest(Shop); nextRequest.CopyFrom(this); if (nextRequest.StartDateTime < nowDateTime) { int attempts = 0; while (!await Shop.CanAcceptCustomersAsync(nextRequest.StartDateTime) && attempts < 5) { nextRequest.StartDateTime = nextRequest.StartDateTime.AddDays(1); nextRequest.StartDateTime = await Shop.OpeningDateTimeAsync(nextRequest.StartDateTime); attempts++; } } nextRequest = await Shop.NextAvailableBarberAsync(nextRequest); response.ValidationResults.AddRange(shopResponse.ValidationResults); } else if (!barberResponse.IsAvailable) { nextRequest = new AppointmentRequest(Shop); nextRequest.CopyFrom(this); if (nextRequest.StartDateTime < nowDateTime) { int attempts = 0; nextRequest.StartDateTime = nextRequest.StartDateTime.AddDays(1); await RequestedBarber.Hours.LoadAsync(RequestedBarber, nextRequest.StartDateTime); while (!await Shop.IsOpenAsync(nextRequest.StartDateTime) && !RequestedBarber.Hours.IsWithinHours(nextRequest.StartDateTime) && attempts < 5) { nextRequest.StartDateTime = nextRequest.StartDateTime.AddDays(1); nextRequest.StartDateTime = await Shop.OpeningDateTimeAsync(nextRequest.StartDateTime); attempts++; } } nextRequest = await RequestedBarber.NextAvailableRequestAsync(nextRequest); response.ValidationResults.AddRange(barberResponse.ValidationResults); } response.SuggestedRequest = nextRequest; return(response); } }