private async Task <DialogTurnResult> DropOffDateStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var reservationDetails = (CarReservationDetails)stepContext.Options; reservationDetails.PickUpTime = (string)stepContext.Result; reservationDetails.PickUpTimeValue = TimexHelpers.DateFromTimex(new TimexProperty(reservationDetails.PickUpTime)); if (reservationDetails.DropOffTime == null || IsAmbiguous(reservationDetails.DropOffTime)) { return(await stepContext.BeginDialogAsync(nameof(DropOffDateResolverDialog), reservationDetails, cancellationToken)); } var dropOff = TimexHelpers.DateFromTimex(new TimexProperty(reservationDetails.PickUpTime)); if (dropOff.Date < DateTime.Now.AddDays(1).Date) { return(await stepContext.BeginDialogAsync(nameof(DropOffDateResolverDialog), reservationDetails, cancellationToken)); } int days = (dropOff.Date - reservationDetails.PickUpTimeValue.Date).Days; if (days < 1) { return(await stepContext.BeginDialogAsync(nameof(DropOffDateResolverDialog), reservationDetails, cancellationToken)); } return(await stepContext.NextAsync(reservationDetails.DropOffTime, cancellationToken)); }
public void DataTypes_Helpers_TimeFromTimex() { var timex = new TimexProperty("T00:05:00"); var time = TimexHelpers.TimeFromTimex(timex); Assert.AreEqual(new Time(0, 5, 0).GetTime(), time.GetTime()); }
public void DataTypes_Helpers_DateFromTimex() { var timex = new TimexProperty("2017-09-27"); var date = TimexHelpers.DateFromTimex(timex); Assert.AreEqual(new System.DateTime(2017, 9, 27), date); }
private async Task <DialogTurnResult> GetDateAndConfirmAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { DateTime reservationDate = default(DateTime); if (stepContext.Result is IList <DateTimeResolution> datetimes) { reservationDate = TimexHelpers.DateFromTimex(new TimexProperty(datetimes.First().Timex)); } var tbleReservation = new TableReservationModel() { ReservedBy = stepContext.Values[ReservedBy].ToString(), TotalOccupants = (int)stepContext.Values[TotalOccupants], ReservationDate = reservationDate }; stepContext.Values.Clear(); stepContext.Values["tbleReservationModel"] = tbleReservation; return(await stepContext.PromptAsync(ConfirmBooking, new PromptOptions() { Prompt = MessageFactory.Text($"Alright {tbleReservation.ReservedBy}, I am reservaing for {tbleReservation.TotalOccupants} on {reservationDate.ToString("MMM/dd/yyyy hh:mm tt")}, could you please confirm booking?"), Choices = ChoiceFactory.ToChoices(new List <string> { "Yes", "No" }) }, cancellationToken)); }
private static Task <bool> DateTimePromptValidator(PromptValidatorContext <IList <DateTimeResolution> > promptContext, CancellationToken cancellationToken) { if (promptContext.Recognized.Succeeded) { // This value will be a TIMEX. And we are only interested in a Date so grab the first result and drop the Time part. // TIMEX is a format that represents DateTime expressions that include some ambiguity. e.g. missing a Year. var timex = promptContext.Recognized.Value[0].Timex.Split('T')[0]; // If this is a definite Date including year, month and day we are good otherwise reprompt. // A better solution might be to let the user know what part is actually missing. var isDefinite = new TimexProperty(timex).Types.Contains(Constants.TimexTypes.Definite); var reservationDetails = (CarReservationDetails)promptContext.Options.Validations; if (isDefinite) { var date = TimexHelpers.DateFromTimex(new TimexProperty(timex)); if (date.Date < DateTime.Now.AddDays(1).Date) { return(Task.FromResult(false)); } int days = (date.Date - reservationDetails.PickUpTimeValue.Date).Days; if (days < 1) { return(Task.FromResult(false)); } } return(Task.FromResult(isDefinite)); } return(Task.FromResult(false)); }
private async Task <DialogTurnResult> TimeOfReservationStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var tableReservation = await _accessors.TableReservationState.GetAsync(stepContext.Context, () => new TableReservation(), cancellationToken); if (stepContext.Result is IList <DateTimeResolution> datetimes) { var time = TimexHelpers.DateFromTimex(new TimexProperty(datetimes.First().Timex)); tableReservation.ReservationOn = tableReservation.ReservationOn.Add(new TimeSpan(time.Hour, time.Minute, 0)); // Create the PromptOptions which contain the prompt and re-prompt messages. // PromptOptions also contains the list of choices available to the user. var options = new PromptOptions() { Prompt = MessageFactory.Text($"Confirming the reservation in the name of {tableReservation.ReservedBy} for total occupants {tableReservation.TotalOccupants} on {tableReservation.ReservationOn.ToString("yyyy MMMMM dd hh:mm tt")}"), RetryPrompt = MessageFactory.Text("That was not a valid choice"), Choices = new List <Choice>() { new Choice("Yes"), new Choice("Cancel") }, }; // Prompt the user with the configured PromptOptions. return(await stepContext.PromptAsync("confirmReservation", options, cancellationToken)); } else { return(await stepContext.PromptAsync("reservationTime", new PromptOptions { Prompt = MessageFactory.Text("Invalid Time!!!") }, cancellationToken)); } }
public void DataTypes_Helpers_ExpandDateTimeRange_Long() { var timex = new TimexProperty("(2006-01-01,2008-06-01,P882D)"); var range = TimexHelpers.ExpandDateTimeRange(timex); Assert.AreEqual("2006-01-01", range.Start.TimexValue); Assert.AreEqual("2008-06-01", range.End.TimexValue); }
public static string GenerateCompoundDurationTimex(Dictionary <string, string> unitToTimexComponents, IImmutableDictionary <string, long> unitValueMap) { var unitList = new List <string>(unitToTimexComponents.Keys); unitList.Sort((x, y) => (unitValueMap[x] < unitValueMap[y] ? 1 : -1)); unitList = unitList.Select(t => unitToTimexComponents[t]).ToList(); return(TimexHelpers.GenerateCompoundDurationTimex(unitList)); }
public void DataTypes_Helpers_TimeRangeFromTimex() { var timex = new TimexProperty("(T14,T16,PT2H)"); var range = TimexHelpers.TimeRangeFromTimex(timex); Assert.AreEqual(new Time(14, 0, 0).GetTime(), range.Start.GetTime()); Assert.AreEqual(new Time(16, 0, 0).GetTime(), range.End.GetTime()); }
public void DataTypes_Helpers_DateRangeFromTimex_Week23() { var timex = new TimexProperty("2020-W23"); var range = TimexHelpers.DateRangeFromTimex(timex); Assert.AreEqual(new System.DateTime(2020, 6, 1), range.Start); Assert.AreEqual(new System.DateTime(2020, 6, 8), range.End); }
public void DataTypes_Helpers_ExpandTimeRange() { var timex = new TimexProperty("(T14,T16,PT2H)"); var range = TimexHelpers.ExpandTimeRange(timex); Assert.AreEqual("T14", range.Start.TimexValue); Assert.AreEqual("T16", range.End.TimexValue); }
public void DataTypes_Helpers_DateRangeFromTimex() { var timex = new TimexProperty("(2017-09-27,2017-09-29,P2D)"); var range = TimexHelpers.DateRangeFromTimex(timex); Assert.AreEqual(new System.DateTime(2017, 9, 27), range.Start); Assert.AreEqual(new System.DateTime(2017, 9, 29), range.End); }
public void DataTypes_Helpers_ExpandDateTimeRange_Month() { var timex = new TimexProperty("2017-05"); var range = TimexHelpers.ExpandDateTimeRange(timex); Assert.AreEqual("2017-05-01", range.Start.TimexValue); Assert.AreEqual("2017-06-01", range.End.TimexValue); }
public void DataTypes_Helpers_ExpandDateTimeRange_Year() { var timex = new TimexProperty("1999"); var range = TimexHelpers.ExpandDateTimeRange(timex); Assert.AreEqual("1999-01-01", range.Start.TimexValue); Assert.AreEqual("2000-01-01", range.End.TimexValue); }
public void DataTypes_Helpers_ExpandDateTimeRange_Include_Time() { var timex = new TimexProperty("(2017-10-10T16:02:04,2017-10-10T16:07:04,PT5M)"); var range = TimexHelpers.ExpandDateTimeRange(timex); Assert.AreEqual("2017-10-10T16:02:04", range.Start.TimexValue); Assert.AreEqual("2017-10-10T16:07:04", range.End.TimexValue); }
public void DataTypes_Helpers_ExpandDateTimeRange_Short() { var timex = new TimexProperty("(2017-09-27,2017-09-29,P2D)"); var range = TimexHelpers.ExpandDateTimeRange(timex); Assert.AreEqual("2017-09-27", range.Start.TimexValue); Assert.AreEqual("2017-09-29", range.End.TimexValue); }
public static string Format(TimexProperty timex) { var types = timex.Types.Count != 0 ? timex.Types : TimexInference.Infer(timex); if (types.Contains(Constants.TimexTypes.Present)) { return("PRESENT_REF"); } if ((types.Contains(Constants.TimexTypes.DateTimeRange) || types.Contains(Constants.TimexTypes.DateRange) || types.Contains(Constants.TimexTypes.TimeRange)) && types.Contains(Constants.TimexTypes.Duration)) { var range = TimexHelpers.ExpandDateTimeRange(timex); return($"({Format(range.Start)},{Format(range.End)},{Format(range.Duration)})"); } if (types.Contains(Constants.TimexTypes.DateTimeRange)) { return($"{FormatDate(timex)}{FormatTimeRange(timex)}"); } if (types.Contains(Constants.TimexTypes.DateRange)) { return($"{FormatDateRange(timex)}"); } if (types.Contains(Constants.TimexTypes.TimeRange)) { return($"{FormatTimeRange(timex)}"); } if (types.Contains(Constants.TimexTypes.DateTime)) { return($"{FormatDate(timex)}{FormatTime(timex)}"); } if (types.Contains(Constants.TimexTypes.Duration)) { return($"{FormatDuration(timex)}"); } if (types.Contains(Constants.TimexTypes.Date)) { return($"{FormatDate(timex)}"); } if (types.Contains(Constants.TimexTypes.Time)) { return($"{FormatTime(timex)}"); } return(string.Empty); }
private async Task <DialogTurnResult> ConfirmStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var reservationDetails = (CarReservationDetails)stepContext.Options; reservationDetails.DropOffTime = (string)stepContext.Result; reservationDetails.DropOffTimeValue = TimexHelpers.DateFromTimex(new TimexProperty(reservationDetails.DropOffTime)); var messageText = $"Please confirm, I have your reservation question details pick-up: {reservationDetails.PickUpTime} dropoff: {reservationDetails.DropOffTime} vehicle model: {reservationDetails.VehicleModelName}. Is this correct?"; var promptMessage = MessageFactory.Text(messageText, messageText, InputHints.ExpectingInput); return(await stepContext.PromptAsync(nameof(ConfirmPrompt), new PromptOptions { Prompt = promptMessage }, cancellationToken)); }
// </AddEventSnippet> // Generate a DateTime from the list of // DateTimeResolutions provided by the DateTimePrompt private static DateTime GetDateTimeFromResolutions(IList <DateTimeResolution> resolutions) { var timex = new TimexProperty(resolutions[0].Timex); // Handle the "now" case if (timex.Now ?? false) { return(DateTime.Now); } // Otherwise generate a DateTime return(TimexHelpers.DateFromTimex(timex)); }
private async Task <DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var reservationDetails = (CarReservationDetails)stepContext.Options; var promptMessage = MessageFactory.Text(PickUpMsgText, PickUpMsgText, InputHints.ExpectingInput); var repromptMessage = MessageFactory.Text(RepromptMsgText, RepromptMsgText, InputHints.ExpectingInput); var validDateMessage = MessageFactory.Text(ValidDateMsgText, ValidDateMsgText, InputHints.ExpectingInput); if (reservationDetails.PickUpTime == null) { // We were not given any date at all so prompt the user. return(await stepContext.PromptAsync(nameof(DateTimePrompt), new PromptOptions { Prompt = promptMessage, RetryPrompt = repromptMessage }, cancellationToken)); } // We have a Date we just need to check it is unambiguous. var timexProperty = new TimexProperty(reservationDetails.PickUpTime); if (!timexProperty.Types.Contains(Constants.TimexTypes.Definite)) { // This is essentially a "reprompt" of the data we were given up front. return(await stepContext.PromptAsync(nameof(DateTimePrompt), new PromptOptions { Prompt = repromptMessage, RetryPrompt = repromptMessage }, cancellationToken)); } var date = TimexHelpers.DateFromTimex(timexProperty); if (date.Date < DateTime.Now.AddDays(1).Date) { return(await stepContext.PromptAsync(nameof(DateTimePrompt), new PromptOptions { Prompt = validDateMessage, RetryPrompt = repromptMessage }, cancellationToken)); } return(await stepContext.NextAsync(new List <DateTimeResolution> { new DateTimeResolution { Timex = reservationDetails.PickUpTime } }, cancellationToken)); }
private async Task <DialogTurnResult> DateOfReservationStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var tableReservation = await _accessors.TableReservationState.GetAsync(stepContext.Context, () => new TableReservation(), cancellationToken); if (stepContext.Result is IList <DateTimeResolution> datetimes) { var date = TimexHelpers.DateFromTimex(new TimexProperty(datetimes.First().Timex)); tableReservation.ReservationOn = date; return(await stepContext.PromptAsync("reservationTime", new PromptOptions { Prompt = MessageFactory.Text("What would be the time preference?") }, cancellationToken)); } else { return(await stepContext.PromptAsync("reservationDate", new PromptOptions { Prompt = MessageFactory.Text("Doesn't seems to be valid date") }, cancellationToken)); } }
private async Task <DialogTurnResult> PickUpDateStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { var reservationDetails = (CarReservationDetails)stepContext.Options; reservationDetails.VehicleModelName = (string)stepContext.Result; if (reservationDetails.PickUpTime == null || IsAmbiguous(reservationDetails.PickUpTime)) { return(await stepContext.BeginDialogAsync(nameof(PickUpDateResolverDialog), reservationDetails, cancellationToken)); } var pickUp = TimexHelpers.DateFromTimex(new TimexProperty(reservationDetails.PickUpTime)); if (pickUp.Date < DateTime.Now.AddDays(1).Date) { return(await stepContext.BeginDialogAsync(nameof(PickUpDateResolverDialog), reservationDetails, cancellationToken)); } return(await stepContext.NextAsync(reservationDetails.PickUpTime, cancellationToken)); }
private async Task <DialogTurnResult> ActStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) { if (!_luisRecognizer.IsConfigured) { // LUIS is not configured, we just run the BookingDialog path with an empty BookingDetailsInstance. return(await stepContext.BeginDialogAsync(nameof(ReservationDialog), new ReservationDialog(), cancellationToken)); } // Call LUIS and gather any potential booking details. (Note the TurnContext has the response to the prompt.) var luisResult = await _luisRecognizer.RecognizeAsync <CarReservation>(stepContext.Context, cancellationToken); switch (luisResult.TopIntent().intent) { case CarReservation.Intent.CarReservation: var carReservationDetails = new CarReservationDetails { VehicleModelName = luisResult.Model, PickUpTime = luisResult.PickUp, DropOffTime = luisResult.DropOff }; if (luisResult.PickUp != null) { var timexPickUp = new TimexProperty(luisResult.PickUp); var isDefinite = timexPickUp.Types.Contains(Constants.TimexTypes.Definite); if (isDefinite) { var start = TimexHelpers.DateFromTimex(timexPickUp); carReservationDetails.PickUpTimeValue = start; } } if (luisResult.DropOff != null) { var timexDropOff = new TimexProperty(luisResult.DropOff); var isDefinite = timexDropOff.Types.Contains(Constants.TimexTypes.Definite); if (isDefinite) { var end = TimexHelpers.DateFromTimex(timexDropOff); carReservationDetails.DropOffTimeValue = end; } } // Run the BookingDialog giving it whatever details we have from the LUIS call, it will fill out the remainder. return(await stepContext.BeginDialogAsync(nameof(ReservationDialog), carReservationDetails, cancellationToken)); case CarReservation.Intent.GetAddresses: var addresses = await _botService.GetAddresses(); var addressesMessageText = $"The vehicles can be picked up and dropped off at the following rental places:"; foreach (var address in addresses) { addressesMessageText += $" {address.FullAddress},"; } addressesMessageText += "."; var addressesMessage = MessageFactory.Text(addressesMessageText, addressesMessageText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(addressesMessage, cancellationToken); break; case CarReservation.Intent.GetFreeVehicle: var vehicles = await _botService.GetFreeVehicles(); var freeVehicleMessageText = $"The currently available models are: "; foreach (var vehicle in vehicles) { freeVehicleMessageText += $" {vehicle.VehicleType},"; } var freeVehicleMessage = MessageFactory.Text(freeVehicleMessageText, freeVehicleMessageText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(freeVehicleMessage, cancellationToken); break; case CarReservation.Intent.None: var noneMessageText = $"Sorry, I didn't get that. Please try asking in a different way."; var noneMessage = MessageFactory.Text(noneMessageText, noneMessageText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(noneMessage, cancellationToken); break; default: // Catch all for unhandled intents var didntUnderstandMessageText = $"Sorry, I didn't get that. Please try asking in a different way."; var didntUnderstandMessage = MessageFactory.Text(didntUnderstandMessageText, didntUnderstandMessageText, InputHints.IgnoringInput); await stepContext.Context.SendActivityAsync(didntUnderstandMessage, cancellationToken); break; } return(await stepContext.NextAsync(null, cancellationToken)); }