diff --git a/PlanB.Butler.Bot/BotConfig.cs b/PlanB.Butler.Bot/BotConfig.cs
index a59c3df..03a577f 100644
--- a/PlanB.Butler.Bot/BotConfig.cs
+++ b/PlanB.Butler.Bot/BotConfig.cs
@@ -8,6 +8,22 @@ namespace PlanB.Butler.Bot
///
public class BotConfig
{
+ ///
+ /// Gets or sets the butler service URL.
+ ///
+ ///
+ /// The butler service URL.
+ ///
+ public string ButlerServiceUrl { get; set; }
+
+ ///
+ /// Gets or sets the butler service key.
+ ///
+ ///
+ /// The butler service key.
+ ///
+ public string ButlerServiceKey { get; set; }
+
///
/// Gets or sets the storage account URL.
///
diff --git a/PlanB.Butler.Bot/Constants.cs b/PlanB.Butler.Bot/Constants.cs
new file mode 100644
index 0000000..6b08d02
--- /dev/null
+++ b/PlanB.Butler.Bot/Constants.cs
@@ -0,0 +1,26 @@
+// Copyright (c) PlanB. GmbH. All Rights Reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+namespace PlanB.Butler.Bot
+{
+ ///
+ /// Constants.
+ ///
+ internal static class Constants
+ {
+ ///
+ /// The butler correlation trace name.
+ ///
+ internal const string ButlerCorrelationTraceName = "Butler-Correlation-Id";
+
+ ///
+ /// The butler correlation trace header.
+ ///
+ internal const string ButlerCorrelationTraceHeader = "ButlerCorrelationId";
+
+ ///
+ /// The functions key header.
+ ///
+ internal const string FunctionsKeyHeader = "x-functions-key";
+ }
+}
\ No newline at end of file
diff --git a/PlanB.Butler.Bot/Dialogs/CreditDialog.cs b/PlanB.Butler.Bot/Dialogs/CreditDialog.cs
index 7b70063..79d89d0 100644
--- a/PlanB.Butler.Bot/Dialogs/CreditDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/CreditDialog.cs
@@ -15,7 +15,7 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
public class CreditDialog : ComponentDialog
{
diff --git a/PlanB.Butler.Bot/Dialogs/DailyCreditDialog.cs b/PlanB.Butler.Bot/Dialogs/DailyCreditDialog.cs
index 7c17721..4e780d2 100644
--- a/PlanB.Butler.Bot/Dialogs/DailyCreditDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/DailyCreditDialog.cs
@@ -13,7 +13,7 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
///
/// DailyCreditDialog.
diff --git a/PlanB.Butler.Bot/Dialogs/DeletOrderDialog.cs b/PlanB.Butler.Bot/Dialogs/DeleteOrderDialog.cs
similarity index 93%
rename from PlanB.Butler.Bot/Dialogs/DeletOrderDialog.cs
rename to PlanB.Butler.Bot/Dialogs/DeleteOrderDialog.cs
index 6a18756..b88cf39 100644
--- a/PlanB.Butler.Bot/Dialogs/DeletOrderDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/DeleteOrderDialog.cs
@@ -1,6 +1,9 @@
-using System;
+// Copyright (c) PlanB. GmbH. All Rights Reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using System;
using System.Collections.Generic;
-using System.Net;
+using System.Net.Http;
using System.Reflection;
using System.Resources;
using System.Threading;
@@ -13,9 +16,8 @@
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using PlanB.Butler.Bot;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
///
/// DeleteOrderDialog.
@@ -23,34 +25,35 @@ namespace PlanB.Butler.Bot
///
public class DeleteOrderDialog : ComponentDialog
{
+ ///
+ /// The client factory.
+ ///
+ private readonly IHttpClientFactory clientFactory;
+
+ ///
+ /// The bot configuration.
+ ///
+ private readonly IOptions botConfig;
+
static Plan plan = new Plan();
static Plan orderedfood = new Plan();
static int valueDay;
const double grand = 3.30;
static string dayName;
+ [Obsolete("Why is this still in use?")]
static string[] weekDays = { "Montag", "Dienstag", "Mitwoch", "Donnerstag", "Freitag" };
+ [Obsolete("Why is this still in use?")]
static string[] weekDaysEN = { "monday", "tuesday", "wednesday", "thursday", "friday" };
static int indexer = 0;
+ [Obsolete("Why is this still in use?")]
static string[] companyStatus = { "intern", "extern", "internship" };
+ [Obsolete("Why is this still in use?")]
static string[] companyStatusD = { "Für mich", "Kunde", "Praktikant" };
+ [Obsolete("Naming Conventions!")]
static Order obj = new Order();
- ///
- /// DeletDialogTimePrompt.
- /// DeletDialogWhoPrompt
- /// NextOrderDialogMyself
- /// NextOrderDialolTrainee
- /// NextOrderDialogCostumer
- /// DeletDialogNoOrder
- /// DeletDialogDeleteSucess
- /// DeletDialogDeletePrompt
- /// DeletDialogYes
- /// DeletDialogNo
- /// OtherDayDialogError2.
- ///
-
private static string deletDialogTimePrompt = string.Empty;
- private static string deletDialogWhoPrompt = string.Empty;
+ private static string deletDialogWhoPrompt = string.Empty;
private static string nextOrderDialogMyself = string.Empty;
private static string nextOrderDialogTrainee = string.Empty;
private static string nextOrderDialogCostumer = string.Empty;
@@ -61,20 +64,18 @@ public class DeleteOrderDialog : ComponentDialog
private static string deletDialogNo = string.Empty;
private static string otherDayDialogError2 = string.Empty;
-
- ///
- /// The bot configuration.
- ///
- private readonly IOptions botConfig;
-
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The configuration.
- public DeleteOrderDialog(IOptions config, IBotTelemetryClient telemetryClient)
+ /// The telemetry client.
+ /// The HTTP client factory.
+ public DeleteOrderDialog(IOptions config, IBotTelemetryClient telemetryClient, IHttpClientFactory httpClientFactory)
: base(nameof(DeleteOrderDialog))
{
ResourceManager rm = new ResourceManager("PlanB.Butler.Bot.Dictionary.Dialogs", Assembly.GetExecutingAssembly());
+ this.clientFactory = httpClientFactory;
+ this.botConfig = config;
deletDialogTimePrompt = rm.GetString("DeletDialog_TimePrompt");
deletDialogWhoPrompt = rm.GetString("DeletDialog_WhoPrompt");
@@ -88,15 +89,10 @@ public DeleteOrderDialog(IOptions config, IBotTelemetryClient telemet
deletDialogNo = rm.GetString("no");
otherDayDialogError2 = rm.GetString("OtherDayDialog_Error2");
+ //// Get the Plan
+ //string food = BotMethods.GetDocument("eatingplan", "ButlerOverview.json", this.botConfig.Value.StorageAccountUrl, this.botConfig.Value.StorageAccountKey);
-
-
- this.botConfig = config;
-
- // Get the Plan
- string food = BotMethods.GetDocument("eatingplan", "ButlerOverview.json", this.botConfig.Value.StorageAccountUrl, this.botConfig.Value.StorageAccountKey);
-
- plan = JsonConvert.DeserializeObject(food);
+ //plan = JsonConvert.DeserializeObject(food);
// This array defines how the Waterfall will execute.
var waterfallSteps = new WaterfallStep[]
{
diff --git a/PlanB.Butler.Bot/Dialogs/ExcellDialog.cs b/PlanB.Butler.Bot/Dialogs/ExcellDialog.cs
index ece386c..d6d6494 100644
--- a/PlanB.Butler.Bot/Dialogs/ExcellDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/ExcellDialog.cs
@@ -8,7 +8,7 @@
using Microsoft.Bot.Builder.Dialogs.Choices;
using Microsoft.Extensions.Options;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
///
/// ExcellDialog.
@@ -16,6 +16,7 @@ namespace PlanB.Butler.Bot
///
public class ExcellDialog : ComponentDialog
{
+ [Obsolete("This has to be replaced")]
private static string[] months = { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember" };
private static string indexer = "0";
diff --git a/PlanB.Butler.Bot/Dialogs/InterruptDialog.cs b/PlanB.Butler.Bot/Dialogs/InterruptDialog.cs
index 17b2a9e..7adc456 100644
--- a/PlanB.Butler.Bot/Dialogs/InterruptDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/InterruptDialog.cs
@@ -17,7 +17,7 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
///
/// InterruptDialog.
@@ -35,14 +35,14 @@ public class InterruptDialog : ComponentDialog
private static Plan plan = new Plan();
private readonly IOptions botConfig;
- public InterruptDialog(string v, IOptions config, IBotTelemetryClient telemetryClient)
+ public InterruptDialog(string v, IOptions config, IBotTelemetryClient telemetryClient, IHttpClientFactory clientFactory)
: base(nameof(InterruptDialog))
{
ResourceManager rm = new ResourceManager("PlanB.Butler.Bot.Dictionary.Dialogs", Assembly.GetExecutingAssembly());
interruptDialogHelpText = rm.GetString("InterruptDialog_HelpText");
this.botConfig = config;
- this.AddDialog(new OverviewDialog(config, telemetryClient));
+ this.AddDialog(new OverviewDialog(config, telemetryClient, clientFactory));
this.AddDialog(new ExcellDialog(config, telemetryClient));
}
diff --git a/PlanB.Butler.Bot/Dialogs/MainDialog.cs b/PlanB.Butler.Bot/Dialogs/MainDialog.cs
index 1c2d9d5..bacc88d 100644
--- a/PlanB.Butler.Bot/Dialogs/MainDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/MainDialog.cs
@@ -1,25 +1,46 @@
-namespace PlanB.Butler.Bot
-{
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- using AdaptiveCards;
- using Microsoft.Bot.Builder;
- using Microsoft.Bot.Builder.Dialogs;
- using Microsoft.Bot.Builder.Dialogs.Choices;
- using Microsoft.Bot.Schema;
- using Microsoft.Extensions.Options;
- using Newtonsoft.Json.Linq;
- using PlanB.Butler.Bot;
+// Copyright (c) PlanB. GmbH. All Rights Reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+
+using AdaptiveCards;
+using Microsoft.Bot.Builder;
+using Microsoft.Bot.Builder.Dialogs;
+using Microsoft.Bot.Builder.Dialogs.Choices;
+using Microsoft.Bot.Schema;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json.Linq;
+using PlanB.Butler.Bot;
+namespace PlanB.Butler.Bot.Dialogs
+{
+ ///
+ /// MainDialog.
+ ///
+ ///
public class MainDialog : InterruptDialog
{
- public MainDialog(IBotTelemetryClient telemetryClient, IOptions config)
- : base(nameof(MainDialog), config,telemetryClient)
+ ///
+ /// The client factory.
+ ///
+ private readonly IHttpClientFactory clientFactory;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The telemetry client.
+ /// The configuration.
+ /// The HTTP client factory.
+ public MainDialog(IBotTelemetryClient telemetryClient, IOptions config, IHttpClientFactory httpClientFactory)
+ : base(nameof(MainDialog), config, telemetryClient, httpClientFactory)
{
// Set the telemetry client for this and all child dialogs.
this.TelemetryClient = telemetryClient;
+ this.clientFactory = httpClientFactory;
// This array defines how the Waterfall will execute.
var waterfallSteps = new WaterfallStep[]
diff --git a/PlanB.Butler.Bot/Dialogs/NextOrder.cs b/PlanB.Butler.Bot/Dialogs/NextOrder.cs
index 2bb11ad..b1239a2 100644
--- a/PlanB.Butler.Bot/Dialogs/NextOrder.cs
+++ b/PlanB.Butler.Bot/Dialogs/NextOrder.cs
@@ -18,7 +18,7 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
///
/// NextOrder.
diff --git a/PlanB.Butler.Bot/Dialogs/OrderDialog.cs b/PlanB.Butler.Bot/Dialogs/OrderDialog.cs
index d02aa24..9ce5e7f 100644
--- a/PlanB.Butler.Bot/Dialogs/OrderDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/OrderDialog.cs
@@ -1,18 +1,18 @@
-namespace PlanB.Butler.Bot
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+
+using BotLibraryV2;
+using Microsoft.Bot.Builder;
+using Microsoft.Bot.Builder.Dialogs;
+using Microsoft.Bot.Builder.Dialogs.Choices;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+
+namespace PlanB.Butler.Bot.Dialogs
{
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Threading;
- using System.Threading.Tasks;
- using BotLibraryV2;
- using Microsoft.Bot.Builder;
- using Microsoft.Bot.Builder.Dialogs;
- using Microsoft.Bot.Builder.Dialogs.Choices;
- using Microsoft.Bot.Schema;
- using Microsoft.Extensions.Options;
- using Newtonsoft.Json;
-
public class OrderDialog : ComponentDialog
{
private static Plan plan = new Plan();
diff --git a/PlanB.Butler.Bot/Dialogs/OrderForOtherDayDialog.cs b/PlanB.Butler.Bot/Dialogs/OrderForOtherDayDialog.cs
index caaa352..9d8d832 100644
--- a/PlanB.Butler.Bot/Dialogs/OrderForOtherDayDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/OrderForOtherDayDialog.cs
@@ -18,7 +18,7 @@
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
///
/// OrderForOtherDayDialog.
diff --git a/PlanB.Butler.Bot/Dialogs/OverviewDialog.cs b/PlanB.Butler.Bot/Dialogs/OverviewDialog.cs
index 0ae0476..0dcd507 100644
--- a/PlanB.Butler.Bot/Dialogs/OverviewDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/OverviewDialog.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Net.Http;
using System.Reflection;
using System.Resources;
using System.Threading;
@@ -15,9 +16,9 @@
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
-using PlanB.Butler.Bot;
+using PlanB.Butler.Bot.Services;
-namespace PlanB.Butler.Bot
+namespace PlanB.Butler.Bot.Dialogs
{
///
/// OverviewDialog.
@@ -25,13 +26,18 @@ namespace PlanB.Butler.Bot
///
public class OverviewDialog : ComponentDialog
{
+ ///
+ /// The client factory.
+ ///
+ private readonly IHttpClientFactory clientFactory;
+
private static Plan plan = new Plan();
private static int dayId;
+ [Obsolete("Why is this still in use?")]
private static string[] weekDaysEN = { "monday", "tuesday", "wednesday", "thursday", "friday" };
private static int indexer = 0;
private static bool valid;
- private static ComponentDialog[] dialogs;
///
/// OverviewDialogHelp.
/// OverviewDialogOrderFood
@@ -42,6 +48,7 @@ public class OverviewDialog : ComponentDialog
/// OverviewDialogWhatNow
/// OverviewDialogError.
///
+ private static ComponentDialog[] dialogs;
private static string overviewDialogHelp = string.Empty;
private static string overviewDialogOrderFood = string.Empty;
@@ -55,19 +62,24 @@ public class OverviewDialog : ComponentDialog
// In this Array you can Easy modify your choice List.
private static string[] choices;
-
+
///
/// The bot configuration.
///
private readonly IOptions botConfig;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The configuration.
- public OverviewDialog(IOptions config, IBotTelemetryClient telemetryClient)
+ /// The telemetry client.
+ /// The HTTP client factory.
+ public OverviewDialog(IOptions config, IBotTelemetryClient telemetryClient, IHttpClientFactory httpClientFactory)
: base(nameof(OverviewDialog))
{
+ this.botConfig = config;
+ this.clientFactory = httpClientFactory;
+
ResourceManager rm = new ResourceManager("PlanB.Butler.Bot.Dictionary.Dialogs", Assembly.GetExecutingAssembly());
overviewDialogHelp = rm.GetString("OverviewDialog_Help");
@@ -80,15 +92,13 @@ public OverviewDialog(IOptions config, IBotTelemetryClient telemetryC
overviewDialogError = rm.GetString("OtherDayDialog_Error2");
otherDayDialogOrder = rm.GetString("OtherDayDialog_Order");
- this.botConfig = config;
-
- choices = new string[]{ overviewDialogOrderFood, overviewDialogOtherDay, overviewDialogDeleteOrder, overviewDialogShowDepts, overviewDialogDaysOrder };
+ choices = new string[] { overviewDialogOrderFood, overviewDialogOtherDay, overviewDialogDeleteOrder, overviewDialogShowDepts, overviewDialogDaysOrder };
OrderDialog orderDialog = new OrderDialog(config, telemetryClient);
NextOrder nextorderDialog = new NextOrder(config, telemetryClient);
PlanDialog planDialog = new PlanDialog(config, telemetryClient);
CreditDialog creditDialog = new CreditDialog(config, telemetryClient);
OrderForOtherDayDialog orderForAnotherDay = new OrderForOtherDayDialog(config, telemetryClient);
- DeleteOrderDialog deleteOrderDialog = new DeleteOrderDialog(config, telemetryClient);
+ DeleteOrderDialog deleteOrderDialog = new DeleteOrderDialog(config, telemetryClient, this.clientFactory);
List dialogsList = new List();
DailyCreditDialog dailyCreditDialog = new DailyCreditDialog(config, telemetryClient);
ExcellDialog excellDialog = new ExcellDialog(config, telemetryClient);
@@ -117,7 +127,7 @@ public OverviewDialog(IOptions config, IBotTelemetryClient telemetryC
this.AddDialog(new CreditDialog(config, telemetryClient));
this.AddDialog(new PlanDialog(config, telemetryClient));
this.AddDialog(new OrderForOtherDayDialog(config, telemetryClient));
- this.AddDialog(new DeleteOrderDialog(config, telemetryClient));
+ this.AddDialog(new DeleteOrderDialog(config, telemetryClient, this.clientFactory));
this.AddDialog(new NextOrder(config, telemetryClient));
this.AddDialog(new DailyCreditDialog(config, telemetryClient));
this.AddDialog(new ExcellDialog(config, telemetryClient));
@@ -166,32 +176,50 @@ private async Task InitialStepAsync(WaterfallStepContext stepC
valid = false;
}
- List choise = new List();
- var day = plan.Planday[dayId];
- if (day.Restaurant1 != null)
+ IMealService mealService = new MealService(this.clientFactory.CreateClient(), this.botConfig.Value);
+ var meals = await mealService.GetMeals(string.Empty, string.Empty);
+ var mealEnumerator = meals.GetEnumerator();
+ PlanDay day = new PlanDay();
+ while (mealEnumerator.MoveNext())
{
- choise.Add(day.Restaurant1);
- }
+ if (string.IsNullOrEmpty(day.Restaurant1))
+ {
+ day.Restaurant1 = mealEnumerator.Current.Restaurant;
+ }
- if (day.Restaurant2 != null)
- {
- choise.Add(day.Restaurant2);
+ if (string.IsNullOrEmpty(day.Restaurant2) && day.Restaurant1 != mealEnumerator.Current.Restaurant)
+ {
+ day.Restaurant2 = mealEnumerator.Current.Restaurant;
+ }
}
+ List restaurants = new List();
+ //var day = plan.Planday[dayId];
+ //if (day.Restaurant1 != null)
+ //{
+ // restaurants.Add(day.Restaurant1);
+ //}
+
+ //if (day.Restaurant2 != null)
+ //{
+ // restaurants.Add(day.Restaurant2);
+ //}
+
string msg = string.Empty;
- bool temp = false;;
- foreach (var item in choise)
+ bool temp = false;
+
+ // TODO: What is the idea of this?
+ foreach (var restaurant in restaurants)
{
if (temp == false)
{
- var otherDayDialog_Order1 = MessageFactory.Text(string.Format(otherDayDialogOrder, item));
+ var otherDayDialog_Order1 = MessageFactory.Text(string.Format(otherDayDialogOrder, restaurant));
msg = $" {otherDayDialog_Order1}";
temp = true;
}
else
{
-
-
+ // TODO: ??
}
}
diff --git a/PlanB.Butler.Bot/Dialogs/PlanDialog.cs b/PlanB.Butler.Bot/Dialogs/PlanDialog.cs
index b087dd1..e9cd93a 100644
--- a/PlanB.Butler.Bot/Dialogs/PlanDialog.cs
+++ b/PlanB.Butler.Bot/Dialogs/PlanDialog.cs
@@ -1,20 +1,24 @@
-namespace PlanB.Butler.Bot
-{
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Resources;
- using System.Threading;
- using System.Threading.Tasks;
- using BotLibraryV2;
- using Microsoft.Bot.Builder;
- using Microsoft.Bot.Builder.Dialogs;
- using Microsoft.Bot.Builder.Dialogs.Choices;
- using Microsoft.Bot.Schema;
- using Microsoft.Extensions.Localization;
- using Microsoft.Extensions.Options;
- using Newtonsoft.Json;
+// Copyright (c) PlanB. GmbH. All Rights Reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Resources;
+using System.Threading;
+using System.Threading.Tasks;
+using BotLibraryV2;
+using Microsoft.Bot.Builder;
+using Microsoft.Bot.Builder.Dialogs;
+using Microsoft.Bot.Builder.Dialogs.Choices;
+using Microsoft.Bot.Schema;
+using Microsoft.Extensions.Localization;
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+
+namespace PlanB.Butler.Bot.Dialogs
+{
public class PlanDialog : ComponentDialog
{
///
diff --git a/PlanB.Butler.Bot/Models/MealModel.cs b/PlanB.Butler.Bot/Models/MealModel.cs
new file mode 100644
index 0000000..736fac3
--- /dev/null
+++ b/PlanB.Butler.Bot/Models/MealModel.cs
@@ -0,0 +1,68 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace PlanB.Butler.Bot.Models
+{
+ ///
+ /// MealModel.
+ ///
+ public class MealModel
+ {
+ ///
+ /// Gets or sets the identifier.
+ ///
+ ///
+ /// The identifier.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// Gets or sets the correlation identifier.
+ ///
+ ///
+ /// The correlation identifier.
+ ///
+ [JsonProperty("correlationId")]
+ public Guid? CorrelationId { get; set; }
+
+ ///
+ /// Gets or sets the date.
+ ///
+ ///
+ /// The date.
+ ///
+ [JsonProperty("date")]
+ public DateTime Date { get; set; }
+
+ ///
+ /// Gets or sets the price.
+ ///
+ ///
+ /// The price.
+ ///
+ [JsonProperty("price")]
+ public double Price { get; set; }
+
+ ///
+ /// Gets or sets the name.
+ ///
+ ///
+ /// The name.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the restaurant.
+ ///
+ ///
+ /// The restaurant.
+ ///
+ [JsonProperty("restaurant")]
+ public string Restaurant { get; set; }
+ }
+}
diff --git a/PlanB.Butler.Bot/Services/MealService.cs b/PlanB.Butler.Bot/Services/MealService.cs
new file mode 100644
index 0000000..e2764a1
--- /dev/null
+++ b/PlanB.Butler.Bot/Services/MealService.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Threading.Tasks;
+
+using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using PlanB.Butler.Bot.Models;
+
+namespace PlanB.Butler.Bot.Services
+{
+ ///
+ /// MealService.
+ ///
+ ///
+ public class MealService : IMealService
+ {
+ ///
+ /// The HTTP client.
+ ///
+ private readonly HttpClient httpClient;
+
+ ///
+ /// The configuration.
+ ///
+ private readonly BotConfig config;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The HTTP client.
+ /// The bot configuration.
+ public MealService(HttpClient httpClient, BotConfig botConfig)
+ {
+ this.httpClient = httpClient;
+ this.config = botConfig;
+ }
+
+ ///
+ /// Gets the meals.
+ ///
+ /// The start date.
+ /// The end date.
+ ///
+ /// Meals.
+ ///
+ public async Task> GetMeals(string startDate, string endDate)
+ {
+ var uri = this.config.ButlerServiceUrl;
+ this.httpClient.DefaultRequestHeaders.Add(Constants.FunctionsKeyHeader, "8NL2rP9nV8agFOGWmwTrlpcrEsIyr7rJINX3qpbZb4WEfyWgzTWH0Q==");
+ var responseString = this.httpClient.GetStringAsync(uri).Result;
+
+ var meals = JsonConvert.DeserializeObject>(responseString);
+ return meals;
+ }
+ }
+
+ ///
+ /// IMealService.
+ ///
+ public interface IMealService
+ {
+ ///
+ /// Gets the meals.
+ ///
+ /// The start date.
+ /// The end date.
+ /// List of Meals.
+ Task> GetMeals(string startDate, string endDate);
+ }
+}
diff --git a/PlanB.Butler.Bot/Startup.cs b/PlanB.Butler.Bot/Startup.cs
index 2c9c8fa..4f35afd 100644
--- a/PlanB.Butler.Bot/Startup.cs
+++ b/PlanB.Butler.Bot/Startup.cs
@@ -21,6 +21,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
+using PlanB.Butler.Bot.Dialogs;
namespace PlanB.Butler.Bot
{
@@ -56,6 +57,13 @@ public void ConfigureServices(IServiceCollection services)
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
+
+ // The Bot needs an HttpClient to download and upload files.
+ //services.AddHttpClient();
+ services.AddHttpClient()
+ .SetHandlerLifetime(TimeSpan.FromMinutes(5));
+
+
// Create the Bot Framework Adapter with error handling enabled.
services.AddSingleton();
diff --git a/PlanB.Butler.Library/PlanB.Butler.Library/BotModels/Plan.cs b/PlanB.Butler.Library/PlanB.Butler.Library/BotModels/Plan.cs
index c622240..ac3d3b9 100644
--- a/PlanB.Butler.Library/PlanB.Butler.Library/BotModels/Plan.cs
+++ b/PlanB.Butler.Library/PlanB.Butler.Library/BotModels/Plan.cs
@@ -27,10 +27,12 @@ public class PlanDay
{
public string Name { get; set; }
+ [Obsolete("Replace Restaurant1 with List")]
public string Restaurant1 { get; set; }
public List Meal1 { get; set; }
+ [Obsolete("Replace Restaurant2 with List")]
public string Restaurant2 { get; set; }
public List Meal2 { get; set; }
diff --git a/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/MealService.cs b/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/MealService.cs
index 01bdb4e..5cd0511 100644
--- a/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/MealService.cs
+++ b/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/MealService.cs
@@ -293,7 +293,7 @@ public static async Task UpdateMealById(
Details = e.StackTrace,
Message = e.Message,
};
- actionResult = new BadRequestObjectResult(mealModel);
+ actionResult = new BadRequestObjectResult(errorModel);
}
finally
{
@@ -480,7 +480,7 @@ public static IActionResult GetMealById(
Details = e.StackTrace,
Message = e.Message,
};
- actionResult = new BadRequestObjectResult(mealModel);
+ actionResult = new BadRequestObjectResult(errorModel);
}
finally
{
diff --git a/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/OrderService.cs b/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/OrderService.cs
index 8dda202..43ca78e 100644
--- a/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/OrderService.cs
+++ b/PlanB.Butler.Services/PlanB.Butler.Services/Controllers/OrderService.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Net.Mime;
using System.Reflection;
@@ -140,78 +141,6 @@ public static async Task GetOrder(
return actionResult;
}
- ///
- /// Posts the document order.
- ///
- /// The message header.
- /// The BLOB.
- /// The log.
- /// The context.
- [Singleton]
- [ProducesResponseType(typeof(List), StatusCodes.Status200OK)]
- [Consumes(MediaTypeNames.Application.Json)]
- [ProducesResponseType(typeof(ErrorModel), StatusCodes.Status400BadRequest)]
- [FunctionName(nameof(PostDocumentOrder))]
- public static async void PostDocumentOrder(
- [ServiceBusTrigger("q.planbutlerupdateorder", Connection = "butlerSend")]Message messageHeader,
- [Blob("orders/{Label}", FileAccess.ReadWrite, Connection = "StorageSend")]CloudBlockBlob blob,
- ILogger log,
- ExecutionContext context)
- {
- if (context is null)
- {
- throw new ArgumentNullException(nameof(context));
- }
-
- Guid correlationId = new Guid(messageHeader.CorrelationId);
- var methodName = MethodBase.GetCurrentMethod().Name;
- var trace = new Dictionary();
- EventId eventId = new EventId(correlationId.GetHashCode(), Constants.ButlerCorrelationTraceName);
- try
- {
- string payload = Encoding.Default.GetString(messageHeader.Body);
- OrdersModel orderBlob = new OrdersModel
- {
- Orders = new List(),
- };
- orderBlob = JsonConvert.DeserializeObject(payload);
- string name = string.Empty;
- DateTime date = DateTime.Now;
- foreach (var item in orderBlob.Orders)
- {
- name = item.Name;
- date = item.Date;
- break;
- }
-
- var stringDate = date.ToString("yyyy-MM-dd");
-
- log.LogInformation(correlationId, $"'{methodName}' - success", trace);
-
- blob.Metadata.Add("user", name);
- blob.Metadata.Add("date", stringDate);
- blob.Metadata.Add(Constants.ButlerCorrelationTraceName, correlationId.ToString().Replace("-", string.Empty));
- await blob.UploadTextAsync(payload);
- await blob.SetMetadataAsync();
- trace.Add("data", payload);
- trace.Add("date", date.ToString());
- trace.Add("name", name);
- trace.Add("requestbody", messageHeader.Body.ToString());
- }
- catch (Exception e)
- {
- trace.Add(string.Format("{0} - {1}", methodName, "rejected"), e.Message);
- trace.Add(string.Format("{0} - {1} - StackTrace", methodName, "rejected"), e.StackTrace);
- log.LogInformation(correlationId, $"'{methodName}' - rejected", trace);
- log.LogError(correlationId, $"'{methodName}' - rejected", trace);
- }
- finally
- {
- log.LogTrace(eventId, $"'{methodName}' - finished");
- log.LogInformation(correlationId, $"'{methodName}' - finished", trace);
- }
- }
-
///
/// Creates the order.
///
@@ -285,5 +214,68 @@ public static IActionResult CreateOrder(
return actionResult;
}
+
+ ///
+ /// Gets the order by identifier.
+ ///
+ /// The req.
+ /// The identifier.
+ /// The BLOB.
+ /// The log.
+ /// The context.
+ /// Order.
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ [ProducesResponseType(typeof(ErrorModel), StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(typeof(OrderModel), StatusCodes.Status200OK)]
+ [FunctionName("GetOrderById")]
+ public static IActionResult GetOrderById(
+ [HttpTrigger(AuthorizationLevel.Function, "get", Route = "orders/{id}")] HttpRequest req,
+ string id,
+ [Blob("orders/{id}.json", FileAccess.ReadWrite, Connection = "StorageSend")] string blob,
+ ILogger log,
+ ExecutionContext context)
+ {
+ Guid correlationId = Util.ReadCorrelationId(req.Headers);
+ var methodName = MethodBase.GetCurrentMethod().Name;
+ var trace = new Dictionary();
+ EventId eventId = new EventId(correlationId.GetHashCode(), Constants.ButlerCorrelationTraceName);
+ IActionResult actionResult = null;
+
+ OrderModel orderModel = null;
+ using (log.BeginScope("Method:{methodName} CorrelationId:{CorrelationId} Label:{Label}", methodName, correlationId.ToString(), context.InvocationId.ToString()))
+ {
+ try
+ {
+ trace.Add(Constants.ButlerCorrelationTraceName, correlationId.ToString());
+ trace.Add("id", id);
+ orderModel = JsonConvert.DeserializeObject(blob);
+
+ log.LogInformation(correlationId, $"'{methodName}' - success", trace);
+ actionResult = new OkObjectResult(orderModel);
+ }
+ catch (Exception e)
+ {
+ trace.Add(string.Format("{0} - {1}", methodName, "rejected"), e.Message);
+ trace.Add(string.Format("{0} - {1} - StackTrace", methodName, "rejected"), e.StackTrace);
+ log.LogInformation(correlationId, $"'{methodName}' - rejected", trace);
+ log.LogError(correlationId, $"'{methodName}' - rejected", trace);
+
+ ErrorModel errorModel = new ErrorModel()
+ {
+ CorrelationId = correlationId,
+ Details = e.StackTrace,
+ Message = e.Message,
+ };
+ actionResult = new BadRequestObjectResult(errorModel);
+ }
+ finally
+ {
+ log.LogTrace(eventId, $"'{methodName}' - finished");
+ log.LogInformation(correlationId, $"'{methodName}' - finished", trace);
+ }
+ }
+
+ return actionResult;
+ }
}
}
diff --git a/PlanB.Butler.Services/PlanB.Butler.Services/ServiceBus/ButlerBus.cs b/PlanB.Butler.Services/PlanB.Butler.Services/ServiceBus/ButlerBus.cs
new file mode 100644
index 0000000..3796c51
--- /dev/null
+++ b/PlanB.Butler.Services/PlanB.Butler.Services/ServiceBus/ButlerBus.cs
@@ -0,0 +1,108 @@
+// Copyright (c) PlanB. GmbH. All Rights Reserved.
+// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+using Microsoft.Azure.ServiceBus;
+using Microsoft.Azure.WebJobs;
+using Microsoft.Extensions.Logging;
+using Microsoft.WindowsAzure.Storage.Blob;
+using Newtonsoft.Json;
+using PlanB.Butler.Services.Extensions;
+using PlanB.Butler.Services.Models;
+
+namespace PlanB.Butler.Services.ServiceBus
+{
+ ///
+ /// ButlerBus.
+ ///
+ public static class ButlerBus
+ {
+ ///
+ /// The meta date.
+ ///
+ private const string MetaDate = "date";
+
+ ///
+ /// The meta user.
+ ///
+ private const string MetaUser = "user";
+
+ ///
+ /// Saves the order.
+ ///
+ /// The message header.
+ /// The BLOB.
+ /// The log.
+ /// The context.
+ [Singleton]
+ [FunctionName(nameof(PushOrder))]
+ public static void PushOrder(
+ [ServiceBusTrigger("q.planbutlerupdateorder", Connection = "butlerSend")]Message messageHeader,
+ [Blob("orders/{Label}", FileAccess.ReadWrite, Connection = "StorageSend")]CloudBlockBlob blob,
+ ILogger log,
+ ExecutionContext context)
+ {
+ Guid correlationId = new Guid(messageHeader.CorrelationId);
+ var methodName = MethodBase.GetCurrentMethod().Name;
+ var trace = new Dictionary();
+ EventId eventId = new EventId(correlationId.GetHashCode(), Constants.ButlerCorrelationTraceName);
+ using (log.BeginScope("Method:{methodName} CorrelationId:{CorrelationId} Label:{Label}", methodName, correlationId.ToString(), context.InvocationId.ToString()))
+ {
+ try
+ {
+ trace.Add(Constants.ButlerCorrelationTraceHeader, correlationId.ToString());
+ string payload = Encoding.Default.GetString(messageHeader.Body);
+ trace.Add("payload", payload);
+ OrdersModel ordersModel = new OrdersModel
+ {
+ Orders = new List(),
+ };
+ ordersModel = JsonConvert.DeserializeObject(payload);
+
+ trace.Add("ordersModel.LoginName", ordersModel.LoginName);
+ string name = System.Web.HttpUtility.UrlEncode(ordersModel.LoginName);
+ trace.Add("name", name);
+
+ DateTime date = ordersModel.Date;
+ var formatedDate = date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
+ trace.Add("formatedDate", formatedDate);
+
+ log.LogInformation(correlationId, $"'{methodName}' - success", trace);
+
+ blob.Metadata.Add(MetaUser, name);
+ blob.Metadata.Add(MetaDate, formatedDate);
+ blob.Metadata.Add(Constants.ButlerCorrelationTraceName, correlationId.ToString().Replace("-", string.Empty));
+
+ Task upload = blob.UploadTextAsync(payload);
+ upload.Wait();
+ trace.Add("upload", "success");
+
+ Task metaData = blob.SetMetadataAsync();
+ metaData.Wait();
+ trace.Add("metaData", "success");
+
+ log.LogInformation(correlationId, $"'{methodName}' - success", trace);
+ }
+ catch (Exception e)
+ {
+ trace.Add(string.Format("{0} - {1}", methodName, "rejected"), e.Message);
+ trace.Add(string.Format("{0} - {1} - StackTrace", methodName, "rejected"), e.StackTrace);
+ log.LogInformation(correlationId, $"'{methodName}' - rejected", trace);
+ log.LogError(correlationId, $"'{methodName}' - rejected", trace);
+ }
+ finally
+ {
+ log.LogTrace(eventId, $"'{methodName}' - finished");
+ log.LogInformation(correlationId, $"'{methodName}' - finished", trace);
+ }
+ }
+ }
+ }
+}