From 292f6c9e2ccd6731a501034bd33e1521b5671fff Mon Sep 17 00:00:00 2001 From: Christine Date: Tue, 17 Mar 2020 14:10:37 +0100 Subject: [PATCH] #109 Restaurant Site activated --- PlanB.Butler.Admin/.editorconfig | 4 + PlanB.Butler.Admin/PlanB.Butler.Admin.sln | 5 + .../Contracts/IMealService.cs | 1 - .../Contracts/IRestaurantService.cs | 43 ++++++ .../Controllers/RestaurantController.cs | 89 ++++++++++- .../Models/RestaurantViewModel.cs | 29 ++-- .../PlanB.Butler.Admin.csproj | 4 + .../Services/RestaurantService.cs | 138 ++++++++++++++++++ .../PlanB.Butler.Admin/Startup.cs | 3 + .../PlanB.Butler.Admin/Views/Meal/Edit.cshtml | 10 -- .../Views/Restaurant/Create.cshtml | 61 ++++++++ .../Views/Restaurant/Edit.cshtml | 61 ++++++++ .../Views/Restaurant/Index.cshtml | 69 +++++++++ .../Views/Restaurant/View.cshtml | 68 +++++++++ 14 files changed, 560 insertions(+), 25 deletions(-) create mode 100644 PlanB.Butler.Admin/.editorconfig create mode 100644 PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IRestaurantService.cs create mode 100644 PlanB.Butler.Admin/PlanB.Butler.Admin/Services/RestaurantService.cs create mode 100644 PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Create.cshtml create mode 100644 PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Edit.cshtml create mode 100644 PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Index.cshtml create mode 100644 PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/View.cshtml diff --git a/PlanB.Butler.Admin/.editorconfig b/PlanB.Butler.Admin/.editorconfig new file mode 100644 index 0000000..17c130c --- /dev/null +++ b/PlanB.Butler.Admin/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# CS1591: Fehledes XML-Kommentar für öffentlich sichtbaren Typ oder Element +dotnet_diagnostic.CS1591.severity = none diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin.sln b/PlanB.Butler.Admin/PlanB.Butler.Admin.sln index b1fad79..55e4296 100644 --- a/PlanB.Butler.Admin/PlanB.Butler.Admin.sln +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin.sln @@ -5,6 +5,11 @@ VisualStudioVersion = 16.0.29814.53 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanB.Butler.Admin", "PlanB.Butler.Admin\PlanB.Butler.Admin.csproj", "{60E6CBA7-955D-475D-8F8E-08751CF09E3D}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{719DFCA4-453B-41D0-A305-98AE13BE8468}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IMealService.cs b/PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IMealService.cs index eb05bf5..600dbba 100644 --- a/PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IMealService.cs +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IMealService.cs @@ -39,6 +39,5 @@ public interface IMealService /// The identifier. /// Meal by Id. Task GetMeal(string id); - } } diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IRestaurantService.cs b/PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IRestaurantService.cs new file mode 100644 index 0000000..8d2009f --- /dev/null +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Contracts/IRestaurantService.cs @@ -0,0 +1,43 @@ +// 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.Threading.Tasks; + +using PlanB.Butler.Admin.Models; + +namespace PlanB.Butler.Admin.Contracts +{ + /// + /// IRestaurantService. + /// + public interface IRestaurantService + { + /// + /// Gets the restaurant. + /// + /// Restaurant. + Task> GetRestaurant(); + + /// + /// Creates the meal. + /// + /// The meal. + /// True or false. + Task CreateRestaurant(RestaurantViewModel restaurant); + + /// + /// Updates the restaurant. + /// + /// The restuarant. + /// Restaurant. + Task UpdateRestaurant(RestaurantViewModel restaurant); + + /// + /// Gets the restaurant. + /// + /// The identifier. + /// Restaurant by Id. + Task GetRestaurant(string id); + } +} diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Controllers/RestaurantController.cs b/PlanB.Butler.Admin/PlanB.Butler.Admin/Controllers/RestaurantController.cs index 8171987..d3657fe 100644 --- a/PlanB.Butler.Admin/PlanB.Butler.Admin/Controllers/RestaurantController.cs +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Controllers/RestaurantController.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using PlanB.Butler.Admin.Contracts; namespace PlanB.Butler.Admin.Controllers { @@ -16,15 +17,99 @@ namespace PlanB.Butler.Admin.Controllers /// public class RestaurantController : Controller { - // GET: // + /// GET: / + + private IRestaurantService restaurantService; + + /// + /// Initializes a new instance of the class. + /// + /// The restaurant SVC. + public RestaurantController(IRestaurantService restserv) => this.restaurantService = restserv; /// /// Indexes this instance. /// /// Index. public IActionResult Index() + { + var restaurant = this.restaurantService.GetRestaurant().Result; + return this.View(restaurant); + } + + /// + /// Creates this instance. + /// + /// IActionResult. + public IActionResult Create() { return this.View(); } - } + + /// + /// Creates the specified meal. + /// + /// The meal. + /// Meal. + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Create([Bind("Id,CorrelationId,Date,Price,Name,Restaurant")] Models.RestaurantViewModel restaurant) + { + if (this.ModelState.IsValid) + { + var result = await this.restaurantService.CreateRestaurant(restaurant); + return this.RedirectToAction("Index"); + } + + return this.View(restaurant); + } + + /// + /// Edits the specified identifier. + /// + /// The identifier. + /// The meal. + /// IActionResult. + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Edit(string id, [Bind("Id,CorrelationId,Date,Price,Name,Restaurant")] Models.RestaurantViewModel restaurant) + { + if (id != restaurant.Id) + { + return this.NotFound(); + } + + if (this.ModelState.IsValid) + { + var result = await this.restaurantService.UpdateRestaurant(restaurant); + return this.RedirectToAction(nameof(this.Index)); + } + + return this.View(restaurant); + } + + /// + /// Edits the specified identifier. + /// + /// The identifier. + /// Meal. + public async Task Edit(string? id) + { + if (string.IsNullOrEmpty(id)) + { + return this.NotFound(); + } + + var restaurant = await this.restaurantService.GetRestaurant(id); + + if (restaurant == null) + { + return this.NotFound(); + } + + return this.View(restaurant); + } + + + } } diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Models/RestaurantViewModel.cs b/PlanB.Butler.Admin/PlanB.Butler.Admin/Models/RestaurantViewModel.cs index e67f52e..5f635d0 100644 --- a/PlanB.Butler.Admin/PlanB.Butler.Admin/Models/RestaurantViewModel.cs +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Models/RestaurantViewModel.cs @@ -39,21 +39,14 @@ public string Id [JsonProperty("url")] public Uri Url { get; set; } - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// + + [JsonProperty("correlationid")] + public Guid? CorrelationId { get; set; } + + [JsonProperty("name")] public string Name { get; set; } - /// - /// Gets or sets the street. - /// - /// - /// The street. - /// [JsonProperty("street")] public string Street { get; set; } @@ -92,5 +85,17 @@ public string Id /// [JsonProperty("emailAddress")] public string EmailAddress { get; set; } + + /// + /// Gets or sets the date. + /// + /// + /// The date. + /// + [DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}")] + [DataType(DataType.Date)] + [JsonProperty("date")] + public DateTime Date { get; set; } + } } diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/PlanB.Butler.Admin.csproj b/PlanB.Butler.Admin/PlanB.Butler.Admin/PlanB.Butler.Admin.csproj index bbfff2f..6aafff1 100644 --- a/PlanB.Butler.Admin/PlanB.Butler.Admin/PlanB.Butler.Admin.csproj +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/PlanB.Butler.Admin.csproj @@ -33,6 +33,10 @@ + + + + diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Services/RestaurantService.cs b/PlanB.Butler.Admin/PlanB.Butler.Admin/Services/RestaurantService.cs new file mode 100644 index 0000000..9592bb7 --- /dev/null +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Services/RestaurantService.cs @@ -0,0 +1,138 @@ +// 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.Http; +using System.Threading.Tasks; + +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using PlanB.Butler.Admin.Contracts; +using PlanB.Butler.Admin.Models; + +namespace PlanB.Butler.Admin.Services +{ + /// + /// RestaurantService. + /// + /// + public class RestaurantService : IRestaurantService + { + /// + /// The HTTP client. + /// + private readonly HttpClient httpClient; + + /// + /// The configuration. + /// + private readonly IConfiguration config; + + /// + /// Initializes a new instance of the class. + /// + /// The HTTP client. + /// The configuration. + public RestaurantService(HttpClient httpClient, IConfiguration configuration) + { + this.httpClient = httpClient; + this.config = configuration; + } + + /// + /// Creates the meal. + /// + /// The restaurant. + /// + /// True or false. + /// + public async Task CreateRestaurant(RestaurantViewModel restaurant) + { + Guid correlationId = Guid.NewGuid(); + restaurant.CorrelationId = correlationId; + var json = JsonConvert.SerializeObject(restaurant); + StringContent content = Util.CreateStringContent(json, correlationId, null); + var uri = this.config["RestaurantUri"]; + + HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri) + { + Content = content, + }; + httpRequestMessage.Headers.Clear(); + Util.AddDefaultEsbHeaders(httpRequestMessage, correlationId, this.config["FunctionsKey"]); + var result = await this.httpClient.SendAsync(httpRequestMessage); + result.EnsureSuccessStatusCode(); + var success = result.IsSuccessStatusCode; + return success; + } + + /// + /// Gets the restaurant. + /// + /// The identifier. + /// + /// Restaurant by Id. + /// + public async Task GetRestaurant(string id) + { + Guid correlationId = Guid.NewGuid(); + var uri = this.config["RestaurantUri"].TrimEnd('/') + "/" + id; + HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, uri); + httpRequestMessage.Headers.Clear(); + Util.AddDefaultEsbHeaders(httpRequestMessage, correlationId, this.config["FunctionsKey"]); + var result = await this.httpClient.SendAsync(httpRequestMessage); + result.EnsureSuccessStatusCode(); + + var body = result.Content.ReadAsStringAsync().Result; + + var restaurant = JsonConvert.DeserializeObject(body); + return restaurant; + } + + /// + /// Gets the restaurant. + /// + /// + /// Restaurant. + /// + public async Task> GetRestaurant() + { + var uri = this.config["RestaurantUri"]; + this.httpClient.DefaultRequestHeaders.Add(Constants.FunctionsKeyHeader, this.config["FunctionsKey"]); + var responseString = await this.httpClient.GetStringAsync(uri); + + var restaurant = JsonConvert.DeserializeObject>(responseString); + return restaurant; + } + + /// + /// Updates the restaurant. + /// + /// The restaurant. + /// + /// Restaurant. + /// + public async Task UpdateRestaurant(RestaurantViewModel restaurant) + { + Guid correlationId = Guid.NewGuid(); + restaurant.CorrelationId = correlationId; + var json = JsonConvert.SerializeObject(restaurant); + StringContent content = Util.CreateStringContent(json, correlationId, null); + var uri = this.config["RestaurantUri"].TrimEnd('/') + "/" + restaurant.Id; + + HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Put, uri) + { + Content = content, + }; + httpRequestMessage.Headers.Clear(); + Util.AddDefaultEsbHeaders(httpRequestMessage, correlationId, this.config["FunctionsKey"]); + var result = await this.httpClient.SendAsync(httpRequestMessage); + result.EnsureSuccessStatusCode(); + var responseString = await result.Content.ReadAsStringAsync(); + + var updatedRestaurant = JsonConvert.DeserializeObject(responseString); + return updatedRestaurant; + } + } +} diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Startup.cs b/PlanB.Butler.Admin/PlanB.Butler.Admin/Startup.cs index aaa983c..f2cc8fe 100644 --- a/PlanB.Butler.Admin/PlanB.Butler.Admin/Startup.cs +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Startup.cs @@ -51,6 +51,9 @@ public void ConfigureServices(IServiceCollection services) services.AddControllersWithViews(); services.AddHttpClient() .SetHandlerLifetime(TimeSpan.FromMinutes(5)); + + services.AddHttpClient() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)); } /// diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Meal/Edit.cshtml b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Meal/Edit.cshtml index 1d35b16..7e59b50 100644 --- a/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Meal/Edit.cshtml +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Meal/Edit.cshtml @@ -12,16 +12,6 @@
-
- - - -
-
- - - -
diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Create.cshtml b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Create.cshtml new file mode 100644 index 0000000..d385257 --- /dev/null +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Create.cshtml @@ -0,0 +1,61 @@ +@model PlanB.Butler.Admin.Models.RestaurantViewModel + +@{ + ViewData["Title"] = "Create"; +} + +

Create

+ +

RestaurantViewModel

+
+
+
+ +
+ +
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+ +
+
+ + + +@section Scripts{ + @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} + +} + diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Edit.cshtml b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Edit.cshtml new file mode 100644 index 0000000..801142f --- /dev/null +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Edit.cshtml @@ -0,0 +1,61 @@ +@model PlanB.Butler.Admin.Models.RestaurantViewModel + +@{ + ViewData["Title"] = "Edit"; +} + +

Edit

+ +

RestaurantViewModel

+
+
+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+
+
+ + + +@section Scripts { + @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } +} + + + diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Index.cshtml b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Index.cshtml new file mode 100644 index 0000000..f0d89ac --- /dev/null +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/Index.cshtml @@ -0,0 +1,69 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Index"; +} + +

Index

+

+ Create New +

+ + + + + + + + + + + + + + + + @foreach (var item in Model) + { + + + + + + + + + + } + +
+ @Html.DisplayNameFor(model => model.Name) + + @Html.DisplayNameFor(model => model.PhoneNumber) + + @Html.DisplayNameFor(model => model.Street) + + @Html.DisplayNameFor(model => model.City) + + @Html.DisplayNameFor(model => model.EmailAddress) + + @Html.DisplayNameFor(model => model.PostalCode) +
+ @Html.DisplayFor(modelItem => item.Name) + + @Html.DisplayFor(modelItem => item.PhoneNumber) + + @Html.DisplayFor(modelItem => item.Street) + + @Html.DisplayFor(modelItem => item.City) + + @Html.DisplayFor(modelItem => item.EmailAddress) + + @Html.DisplayNameFor(model => model.PostalCode) + + Edit + Details + Delete +
+ + diff --git a/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/View.cshtml b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/View.cshtml new file mode 100644 index 0000000..1e75a8f --- /dev/null +++ b/PlanB.Butler.Admin/PlanB.Butler.Admin/Views/Restaurant/View.cshtml @@ -0,0 +1,68 @@ +@model PlanB.Butler.Admin.Models.RestaurantViewModel + +@{ + ViewData["Title"] = "View"; +} + +

View

+ +

Are you sure you want to delete this?

+
+

RestaurantViewModel

+
+
+
+ @Html.DisplayNameFor(model => model.Id) +
+
+ @Html.DisplayFor(model => model.Id) +
+
+ @Html.DisplayNameFor(model => model.Name) +
+
+ @Html.DisplayFor(model => model.Name) +
+
+ @Html.DisplayNameFor(model => model.Street) +
+
+ @Html.DisplayFor(model => model.Street) +
+
+ @Html.DisplayNameFor(model => model.PhoneNumber) +
+
+ @Html.DisplayFor(model => model.PhoneNumber) +
+
+ @Html.DisplayNameFor(model => model.City) +
+
+ @Html.DisplayFor(model => model.City) +
+
+ @Html.DisplayNameFor(model => model.PostalCode) +
+
+ @Html.DisplayFor(model => model.PostalCode) +
+
+ @Html.DisplayNameFor(model => model.EmailAddress) +
+
+ @Html.DisplayFor(model => model.EmailAddress) +
+
+ @Html.DisplayNameFor(model => model.CorrelationId) +
+
+ @Html.DisplayFor(model => model.CorrelationId) +
+
+ +
+ | + Back to List +
+