From b2341a2120ab9c879c4b376cf3cb7a11a412390d Mon Sep 17 00:00:00 2001 From: Andreas Guldborg Hansen Date: Tue, 5 Mar 2024 19:29:51 +0100 Subject: [PATCH] Extend product manager with Menuitems (#25) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial menu item groundwork * Adds MenuItem service and repository * Adds menu items property to products * Small fix * Adding ComboBox for menuitems * Address breaking changes in products API * Convert voucher to filter on domain model * Update API specs * Revert ObservableCollection to IEnumerable * Remove ToString on domain models * Remove unused dict * Refactor lambda * Changes menuitem to record * Update API json --------- Co-authored-by: Frederik Petersen Co-authored-by: Andreas Trøstrup <8415722+Duckth@users.noreply.github.com> --- .../Generated/AnalogCoreV2/AnalogCoreV2.cs | 1000 ++++++++++++++--- Shifty.App/Components/MenuItems.razor | 28 + Shifty.App/Components/ProductManager.razor | 130 +-- Shifty.App/Components/Voucher.razor | 13 +- Shifty.App/DomainModels/MenuItem.cs | 36 + Shifty.App/DomainModels/Product.cs | 61 + Shifty.App/Pages/MenuItem.razor | 24 + Shifty.App/Program.cs | 4 + .../Repositories/IMenuItemRepository.cs | 15 + Shifty.App/Repositories/IProductRepository.cs | 4 +- Shifty.App/Repositories/MenuItemRepository.cs | 38 + Shifty.App/Repositories/ProductRepository.cs | 6 +- Shifty.App/Services/IMenuItemService.cs | 34 + Shifty.App/Services/IProductService.cs | 7 +- Shifty.App/Services/MenuItemService.cs | 48 + Shifty.App/Services/ProductService.cs | 27 +- Shifty.App/Shared/NavMenu.razor | 3 +- Shifty.App/Shifty.App.csproj | 1 + Shifty.App/wwwroot/index.html | 2 + .../OpenApiSpecs/AnalogCoreV2.json | 833 ++++++++++---- 20 files changed, 1872 insertions(+), 442 deletions(-) create mode 100644 Shifty.App/Components/MenuItems.razor create mode 100644 Shifty.App/DomainModels/MenuItem.cs create mode 100644 Shifty.App/DomainModels/Product.cs create mode 100644 Shifty.App/Pages/MenuItem.razor create mode 100644 Shifty.App/Repositories/IMenuItemRepository.cs create mode 100644 Shifty.App/Repositories/MenuItemRepository.cs create mode 100644 Shifty.App/Services/IMenuItemService.cs create mode 100644 Shifty.App/Services/MenuItemService.cs diff --git a/Shifty.Api/Generated/AnalogCoreV2/AnalogCoreV2.cs b/Shifty.Api/Generated/AnalogCoreV2/AnalogCoreV2.cs index a2a7048..31efa3f 100644 --- a/Shifty.Api/Generated/AnalogCoreV2/AnalogCoreV2.cs +++ b/Shifty.Api/Generated/AnalogCoreV2/AnalogCoreV2.cs @@ -1270,6 +1270,270 @@ public virtual async System.Threading.Tasks.Task ApiV2Leaderbo } } + /// + /// Returns a list of all menu items + /// + /// Successful request + /// A server side error occurred. + public virtual System.Threading.Tasks.Task> ApiV2MenuitemsGetAsync() + { + return ApiV2MenuitemsGetAsync(System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Returns a list of all menu items + /// + /// Successful request + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task> ApiV2MenuitemsGetAsync(System.Threading.CancellationToken cancellationToken) + { + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append("api/v2/menuitems"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + request_.Method = new System.Net.Http.HttpMethod("GET"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// + /// Adds a menu item + /// + /// Menu item to add + /// Menu item successfully added + /// A server side error occurred. + public virtual System.Threading.Tasks.Task ApiV2MenuitemsPostAsync(AddMenuItemRequest menuItem) + { + return ApiV2MenuitemsPostAsync(menuItem, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Adds a menu item + /// + /// Menu item to add + /// Menu item successfully added + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ApiV2MenuitemsPostAsync(AddMenuItemRequest menuItem, System.Threading.CancellationToken cancellationToken) + { + if (menuItem == null) + throw new System.ArgumentNullException("menuItem"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append("api/v2/menuitems"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(menuItem, _settings.Value); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 201) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// + /// Updates a menu item + /// + /// Menu item id to update + /// Menu item to update + /// Menu item successfully updated + /// A server side error occurred. + public virtual System.Threading.Tasks.Task ApiV2MenuitemsPutAsync(int id, UpdateMenuItemRequest menuItem) + { + return ApiV2MenuitemsPutAsync(id, menuItem, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Updates a menu item + /// + /// Menu item id to update + /// Menu item to update + /// Menu item successfully updated + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ApiV2MenuitemsPutAsync(int id, UpdateMenuItemRequest menuItem, System.Threading.CancellationToken cancellationToken) + { + if (id == null) + throw new System.ArgumentNullException("id"); + + if (menuItem == null) + throw new System.ArgumentNullException("menuItem"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append("api/v2/menuitems/{id}"); + urlBuilder_.Replace("{id}", System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(menuItem, _settings.Value); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("PUT"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + /// /// Webhook to be invoked by MobilePay backend /// @@ -1290,13 +1554,109 @@ public virtual System.Threading.Tasks.Task ApiV2MobilepayWebhookAsync(string mpS /// Webhook request /// Webhook processed /// A server side error occurred. - public virtual async System.Threading.Tasks.Task ApiV2MobilepayWebhookAsync(string mpSignatureHeader, MobilePayWebhook request, System.Threading.CancellationToken cancellationToken) + public virtual async System.Threading.Tasks.Task ApiV2MobilepayWebhookAsync(string mpSignatureHeader, MobilePayWebhook request, System.Threading.CancellationToken cancellationToken) + { + if (request == null) + throw new System.ArgumentNullException("request"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append("api/v2/mobilepay/webhook"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + + if (mpSignatureHeader != null) + request_.Headers.TryAddWithoutValidation("x-mobilepay-signature", ConvertToString(mpSignatureHeader, System.Globalization.CultureInfo.InvariantCulture)); + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(request, _settings.Value); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 204) + { + return; + } + else + if (status_ == 400) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Signature is not valid", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("A server side error occurred.", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// + /// Adds a new product + /// + /// The request containing the details of the product to be added and allowed user groups + /// The newly added product + /// A server side error occurred. + public virtual System.Threading.Tasks.Task ApiV2ProductsPostAsync(AddProductRequest addProductRequest) + { + return ApiV2ProductsPostAsync(addProductRequest, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Adds a new product + /// + /// The request containing the details of the product to be added and allowed user groups + /// The newly added product + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ApiV2ProductsPostAsync(AddProductRequest addProductRequest, System.Threading.CancellationToken cancellationToken) { - if (request == null) - throw new System.ArgumentNullException("request"); + if (addProductRequest == null) + throw new System.ArgumentNullException("addProductRequest"); var urlBuilder_ = new System.Text.StringBuilder(); - urlBuilder_.Append("api/v2/mobilepay/webhook"); + urlBuilder_.Append("api/v2/products"); var client_ = _httpClient; var disposeClient_ = false; @@ -1304,14 +1664,12 @@ public virtual async System.Threading.Tasks.Task ApiV2MobilepayWebhookAsync(stri { using (var request_ = new System.Net.Http.HttpRequestMessage()) { - - if (mpSignatureHeader != null) - request_.Headers.TryAddWithoutValidation("x-mobilepay-signature", ConvertToString(mpSignatureHeader, System.Globalization.CultureInfo.InvariantCulture)); - var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(request, _settings.Value); + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(addProductRequest, _settings.Value); var content_ = new System.Net.Http.StringContent(json_); content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); request_.Content = content_; request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); PrepareRequest(client_, request_, urlBuilder_); @@ -1334,24 +1692,19 @@ public virtual async System.Threading.Tasks.Task ApiV2MobilepayWebhookAsync(stri ProcessResponse(client_, response_); var status_ = (int)response_.StatusCode; - if (status_ == 204) - { - return; - } - else - if (status_ == 400) + if (status_ == 201) { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); if (objectResponse_.Object == null) { throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); } - throw new ApiException("Signature is not valid", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + return objectResponse_.Object; } else { var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ApiException("A server side error occurred.", status_, responseData_, headers_, null); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); } } finally @@ -1369,28 +1722,23 @@ public virtual async System.Threading.Tasks.Task ApiV2MobilepayWebhookAsync(stri } /// - /// Adds a new product to the database. + /// Returns a list of available products based on a account's user group. /// - /// The request containing the details of the product to be added and allowed user groups. - /// The request was successful, and the product was added. + /// Successful request /// A server side error occurred. - public virtual System.Threading.Tasks.Task ApiV2ProductsPostAsync(AddProductRequest addProductRequest) + public virtual System.Threading.Tasks.Task> ApiV2ProductsGetAsync() { - return ApiV2ProductsPostAsync(addProductRequest, System.Threading.CancellationToken.None); + return ApiV2ProductsGetAsync(System.Threading.CancellationToken.None); } /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// - /// Adds a new product to the database. + /// Returns a list of available products based on a account's user group. /// - /// The request containing the details of the product to be added and allowed user groups. - /// The request was successful, and the product was added. + /// Successful request /// A server side error occurred. - public virtual async System.Threading.Tasks.Task ApiV2ProductsPostAsync(AddProductRequest addProductRequest, System.Threading.CancellationToken cancellationToken) + public virtual async System.Threading.Tasks.Task> ApiV2ProductsGetAsync(System.Threading.CancellationToken cancellationToken) { - if (addProductRequest == null) - throw new System.ArgumentNullException("addProductRequest"); - var urlBuilder_ = new System.Text.StringBuilder(); urlBuilder_.Append("api/v2/products"); @@ -1400,11 +1748,7 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr { using (var request_ = new System.Net.Http.HttpRequestMessage()) { - var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(addProductRequest, _settings.Value); - var content_ = new System.Net.Http.StringContent(json_); - content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); - request_.Content = content_; - request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Method = new System.Net.Http.HttpMethod("GET"); request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); PrepareRequest(client_, request_, urlBuilder_); @@ -1430,7 +1774,7 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr var status_ = (int)response_.StatusCode; if (status_ == 200) { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); if (objectResponse_.Object == null) { throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); @@ -1438,6 +1782,12 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr return objectResponse_.Object; } else + if (status_ == 401) + { + string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Invalid credentials", status_, responseText_, headers_, null); + } + else { var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); @@ -1460,28 +1810,34 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr /// /// Updates a product with the specified changes. /// - /// The request containing the changes to be applied to the product. - /// The request was successful, and the product was updated. + /// Product Id + /// The request containing the changes to be applied to the product + /// The product was updated /// A server side error occurred. - public virtual System.Threading.Tasks.Task ApiV2ProductsPutAsync(UpdateProductRequest product) + public virtual System.Threading.Tasks.Task ApiV2ProductsPutAsync(int productId, UpdateProductRequest product) { - return ApiV2ProductsPutAsync(product, System.Threading.CancellationToken.None); + return ApiV2ProductsPutAsync(productId, product, System.Threading.CancellationToken.None); } /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// /// Updates a product with the specified changes. /// - /// The request containing the changes to be applied to the product. - /// The request was successful, and the product was updated. + /// Product Id + /// The request containing the changes to be applied to the product + /// The product was updated /// A server side error occurred. - public virtual async System.Threading.Tasks.Task ApiV2ProductsPutAsync(UpdateProductRequest product, System.Threading.CancellationToken cancellationToken) + public virtual async System.Threading.Tasks.Task ApiV2ProductsPutAsync(int productId, UpdateProductRequest product, System.Threading.CancellationToken cancellationToken) { + if (productId == null) + throw new System.ArgumentNullException("productId"); + if (product == null) throw new System.ArgumentNullException("product"); var urlBuilder_ = new System.Text.StringBuilder(); - urlBuilder_.Append("api/v2/products"); + urlBuilder_.Append("api/v2/products/{id}"); + urlBuilder_.Replace("{id}", System.Uri.EscapeDataString(ConvertToString(productId, System.Globalization.CultureInfo.InvariantCulture))); var client_ = _httpClient; var disposeClient_ = false; @@ -1519,7 +1875,7 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr var status_ = (int)response_.StatusCode; if (status_ == 200) { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); if (objectResponse_.Object == null) { throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); @@ -1547,25 +1903,31 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr } /// - /// Returns a list of available products based on a account's user group. + /// Returns a product with the specified id /// + /// The id of the product to be returned /// Successful request /// A server side error occurred. - public virtual System.Threading.Tasks.Task> ApiV2ProductsGetAsync() + public virtual System.Threading.Tasks.Task ApiV2ProductsGetAsync(int productId) { - return ApiV2ProductsGetAsync(System.Threading.CancellationToken.None); + return ApiV2ProductsGetAsync(productId, System.Threading.CancellationToken.None); } /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// - /// Returns a list of available products based on a account's user group. + /// Returns a product with the specified id /// + /// The id of the product to be returned /// Successful request /// A server side error occurred. - public virtual async System.Threading.Tasks.Task> ApiV2ProductsGetAsync(System.Threading.CancellationToken cancellationToken) + public virtual async System.Threading.Tasks.Task ApiV2ProductsGetAsync(int productId, System.Threading.CancellationToken cancellationToken) { + if (productId == null) + throw new System.ArgumentNullException("productId"); + var urlBuilder_ = new System.Text.StringBuilder(); - urlBuilder_.Append("api/v2/products"); + urlBuilder_.Append("api/v2/products/{id}"); + urlBuilder_.Replace("{id}", System.Uri.EscapeDataString(ConvertToString(productId, System.Globalization.CultureInfo.InvariantCulture))); var client_ = _httpClient; var disposeClient_ = false; @@ -1599,7 +1961,7 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr var status_ = (int)response_.StatusCode; if (status_ == 200) { - var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); if (objectResponse_.Object == null) { throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); @@ -1613,6 +1975,16 @@ public virtual async System.Threading.Tasks.Task ApiV2Pr throw new ApiException("Invalid credentials", status_, responseText_, headers_, null); } else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("The product with the specified id could not be found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else { var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); @@ -2094,6 +2466,121 @@ public virtual async System.Threading.Tasks.Task ApiV2Pu } } + /// + /// Uses a ticket (for the given product) on the given menu item + /// + /// The product id and menu item id to use a ticket for + /// Successful request + /// A server side error occurred. + public virtual System.Threading.Tasks.Task ApiV2TicketsUseAsync(UseTicketRequest request) + { + return ApiV2TicketsUseAsync(request, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Uses a ticket (for the given product) on the given menu item + /// + /// The product id and menu item id to use a ticket for + /// Successful request + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ApiV2TicketsUseAsync(UseTicketRequest request, System.Threading.CancellationToken cancellationToken) + { + if (request == null) + throw new System.ArgumentNullException("request"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append("api/v2/tickets/use"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(request, _settings.Value); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("POST"); + request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 200) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + return objectResponse_.Object; + } + else + if (status_ == 401) + { + string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Invalid credentials", status_, responseText_, headers_, null); + } + else + if (status_ == 403) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("User has no tickets for the product or the menu item is not eligible for the ticket", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("The product or menu item could not be found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + /// /// Issue voucher codes, that can later be redeemed /// @@ -2287,14 +2774,109 @@ public virtual async System.Threading.Tasks.Task ApiV2Vo throw new ApiException("Invalid credentials", status_, responseText_, headers_, null); } else - if (status_ == 404) + if (status_ == 404) + { + var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); + if (objectResponse_.Object == null) + { + throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); + } + throw new ApiException("Voucher code not found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + } + else + { + var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); + } + } + finally + { + if (disposeResponse_) + response_.Dispose(); + } + } + } + finally + { + if (disposeClient_) + client_.Dispose(); + } + } + + /// + /// Update user groups in bulk + /// + /// The request containing the new user groups + /// The user groups were updated + /// A server side error occurred. + public virtual System.Threading.Tasks.Task ApiV2WebhooksAccountsUserGroupAsync(WebhookUpdateUserGroupRequest request) + { + return ApiV2WebhooksAccountsUserGroupAsync(request, System.Threading.CancellationToken.None); + } + + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. + /// + /// Update user groups in bulk + /// + /// The request containing the new user groups + /// The user groups were updated + /// A server side error occurred. + public virtual async System.Threading.Tasks.Task ApiV2WebhooksAccountsUserGroupAsync(WebhookUpdateUserGroupRequest request, System.Threading.CancellationToken cancellationToken) + { + if (request == null) + throw new System.ArgumentNullException("request"); + + var urlBuilder_ = new System.Text.StringBuilder(); + urlBuilder_.Append("api/v2/webhooks/accounts/user-group"); + + var client_ = _httpClient; + var disposeClient_ = false; + try + { + using (var request_ = new System.Net.Http.HttpRequestMessage()) + { + var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(request, _settings.Value); + var content_ = new System.Net.Http.StringContent(json_); + content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); + request_.Content = content_; + request_.Method = new System.Net.Http.HttpMethod("PUT"); + + PrepareRequest(client_, request_, urlBuilder_); + + var url_ = urlBuilder_.ToString(); + request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); + + PrepareRequest(client_, request_, url_); + + var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); + var disposeResponse_ = true; + try + { + var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); + if (response_.Content != null && response_.Content.Headers != null) + { + foreach (var item_ in response_.Content.Headers) + headers_[item_.Key] = item_.Value; + } + + ProcessResponse(client_, response_); + + var status_ = (int)response_.StatusCode; + if (status_ == 204) + { + return; + } + else + if (status_ == 401) + { + string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Invalid credentials", status_, responseText_, headers_, null); + } + else + if (status_ == 400) { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - throw new ApiException("Voucher code not found", status_, objectResponse_.Text, headers_, objectResponse_.Object, null); + string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); + throw new ApiException("Bad request. See explanation", status_, responseText_, headers_, null); } else { @@ -2471,7 +3053,7 @@ public partial class RegisterAccountRequest [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] public partial class ApiError { - [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string Message { get; set; } } @@ -2711,6 +3293,12 @@ public partial class ResendAccountVerificationEmailRequest [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] public partial class UserSearchResponse { + /// + /// The number of users that match the query + /// + [Newtonsoft.Json.JsonProperty("totalUsers", Required = Newtonsoft.Json.Required.Always)] + public int TotalUsers { get; set; } + /// /// The users that match the query /// @@ -2718,12 +3306,6 @@ public partial class UserSearchResponse [System.ComponentModel.DataAnnotations.Required] public System.Collections.Generic.ICollection Users { get; set; } = new System.Collections.ObjectModel.Collection(); - /// - /// The number of users that match the query - /// - [Newtonsoft.Json.JsonProperty("totalUsers", Required = Newtonsoft.Json.Required.Always)] - public int TotalUsers { get; set; } - } /// @@ -2882,6 +3464,69 @@ public enum LeaderboardPreset } + /// + /// Represents a menu item that can be redeemed with a ticket + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] + public partial class MenuItemResponse + { + /// + /// Id of menu item + /// + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] + public int Id { get; set; } + + /// + /// Name of menu item + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public string Name { get; set; } + + /// + /// Whether or not this menu item is active + /// + [Newtonsoft.Json.JsonProperty("active", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public bool Active { get; set; } + + } + + /// + /// Initiate a new menuitem add request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] + public partial class AddMenuItemRequest + { + /// + /// Gets or sets the name of the product. + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public string Name { get; set; } + + } + + /// + /// Initiate an update product request. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] + public partial class UpdateMenuItemRequest + { + /// + /// Gets or sets the updated name of the product. + /// + [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public string Name { get; set; } + + /// + /// Gets or sets the updated active status of the product. + /// + [Newtonsoft.Json.JsonProperty("active", Required = Newtonsoft.Json.Required.Always)] + public bool Active { get; set; } + + } + /// /// MobilePay webhook invocation request ///
Code documentation based on MobilePay Developer: Webhooks @@ -2949,52 +3594,68 @@ public partial class EventData } /// - /// Represents the product response. + /// Represents a purchasable product /// [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] - public partial class ChangedProductResponse + public partial class ProductResponse { /// - /// Gets or sets the price of the product. + /// Id of product + /// + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] + public int Id { get; set; } + + /// + /// Product price /// [Newtonsoft.Json.JsonProperty("price", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Range(0, 2147483647)] public int Price { get; set; } /// - /// Gets or sets the number of tickets associated with the product. + /// Number of tickets in product /// [Newtonsoft.Json.JsonProperty("numberOfTickets", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Range(0, 2147483647)] public int NumberOfTickets { get; set; } /// - /// Gets or sets the name of the product. + /// Name of product /// [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)] [System.ComponentModel.DataAnnotations.Required] public string Name { get; set; } /// - /// Gets or sets the description of the product. + /// Description of products /// [Newtonsoft.Json.JsonProperty("description", Required = Newtonsoft.Json.Required.Always)] [System.ComponentModel.DataAnnotations.Required] public string Description { get; set; } /// - /// Gets or sets the visibility of the product. + /// Eligible due to a user perk privilege + /// + [Newtonsoft.Json.JsonProperty("isPerk", Required = Newtonsoft.Json.Required.Always)] + public bool IsPerk { get; set; } + + /// + /// Visibility of products for users /// [Newtonsoft.Json.JsonProperty("visible", Required = Newtonsoft.Json.Required.Always)] public bool Visible { get; set; } /// - /// Gets or sets the user groups that can access the product. + /// Decides the user groups that can access the product. /// [Newtonsoft.Json.JsonProperty("allowedUserGroups", Required = Newtonsoft.Json.Required.Always, ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))] [System.ComponentModel.DataAnnotations.Required] public System.Collections.Generic.ICollection AllowedUserGroups { get; set; } = new System.Collections.ObjectModel.Collection(); + /// + /// The menu items that this product can be used on. + /// + [Newtonsoft.Json.JsonProperty("eligibleMenuItems", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public System.Collections.Generic.ICollection EligibleMenuItems { get; set; } + } /// @@ -3034,7 +3695,7 @@ public partial class AddProductRequest /// /// Gets or sets the visibility of the product. Default is true. /// - [Newtonsoft.Json.JsonProperty("visible", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [Newtonsoft.Json.JsonProperty("visible", Required = Newtonsoft.Json.Required.Always)] public bool Visible { get; set; } = true; /// @@ -3044,6 +3705,13 @@ public partial class AddProductRequest [System.ComponentModel.DataAnnotations.Required] public System.Collections.Generic.ICollection AllowedUserGroups { get; set; } = new System.Collections.ObjectModel.Collection(); + /// + /// Gets or sets the menu items that are eligible for the product. + /// + [Newtonsoft.Json.JsonProperty("menuItemIds", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection MenuItemIds { get; set; } = new System.Collections.ObjectModel.Collection(); + } /// @@ -3052,12 +3720,6 @@ public partial class AddProductRequest [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] public partial class UpdateProductRequest { - /// - /// Gets or sets the ID of the product to update. - /// - [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] - public int Id { get; set; } - /// /// Gets or sets the updated price of the product. /// @@ -3089,7 +3751,7 @@ public partial class UpdateProductRequest /// /// Gets or sets the updated visibility of the product. Default is true. /// - [Newtonsoft.Json.JsonProperty("visible", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + [Newtonsoft.Json.JsonProperty("visible", Required = Newtonsoft.Json.Required.Always)] public bool Visible { get; set; } = true; /// @@ -3099,64 +3761,12 @@ public partial class UpdateProductRequest [System.ComponentModel.DataAnnotations.Required] public System.Collections.Generic.ICollection AllowedUserGroups { get; set; } = new System.Collections.ObjectModel.Collection(); - } - - /// - /// Represents a purchasable product - /// - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] - public partial class ProductResponse - { - /// - /// Id of product - /// - [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] - public int Id { get; set; } - - /// - /// Product price - /// - [Newtonsoft.Json.JsonProperty("price", Required = Newtonsoft.Json.Required.Always)] - public int Price { get; set; } - - /// - /// Number of tickets in product - /// - [Newtonsoft.Json.JsonProperty("numberOfTickets", Required = Newtonsoft.Json.Required.Always)] - public int NumberOfTickets { get; set; } - - /// - /// Name of product - /// - [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public string Name { get; set; } - - /// - /// Description of products - /// - [Newtonsoft.Json.JsonProperty("description", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public string Description { get; set; } - - /// - /// Eligible due to a user perk privilege - /// - [Newtonsoft.Json.JsonProperty("isPerk", Required = Newtonsoft.Json.Required.Always)] - public bool IsPerk { get; set; } - - /// - /// Visibility of products for users - /// - [Newtonsoft.Json.JsonProperty("visible", Required = Newtonsoft.Json.Required.Always)] - public bool Visible { get; set; } - /// - /// Decides the user groups that can access the product. + /// Gets or sets the eligible menu items for the product. /// - [Newtonsoft.Json.JsonProperty("allowedUserGroups", Required = Newtonsoft.Json.Required.Always, ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + [Newtonsoft.Json.JsonProperty("menuItemIds", Required = Newtonsoft.Json.Required.Always)] [System.ComponentModel.DataAnnotations.Required] - public System.Collections.Generic.ICollection AllowedUserGroups { get; set; } = new System.Collections.ObjectModel.Collection(); + public System.Collections.Generic.ICollection MenuItemIds { get; set; } = new System.Collections.ObjectModel.Collection(); } @@ -3324,7 +3934,6 @@ public enum PaymentType /// /// MobilePay Payment details /// - [Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] public partial class MobilePayPaymentDetails : PaymentDetails { @@ -3342,18 +3951,11 @@ public partial class MobilePayPaymentDetails : PaymentDetails [System.ComponentModel.DataAnnotations.Required] public string PaymentId { get; set; } - /// - /// MobilePay state - /// - [Newtonsoft.Json.JsonProperty("state", Required = Newtonsoft.Json.Required.AllowNull)] - public string State { get; set; } - } /// /// Payment details for a free purchase /// - [Newtonsoft.Json.JsonConverter(typeof(JsonInheritanceConverter), "discriminator")] [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] public partial class FreePurchasePaymentDetails : PaymentDetails { @@ -3460,7 +4062,7 @@ public partial class TicketResponse /// /// Used date time for ticket in Utc format /// - [Newtonsoft.Json.JsonProperty("dateUsed", Required = Newtonsoft.Json.Required.AllowNull)] + [Newtonsoft.Json.JsonProperty("dateUsed", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public System.DateTimeOffset? DateUsed { get; set; } /// @@ -3476,6 +4078,73 @@ public partial class TicketResponse [System.ComponentModel.DataAnnotations.Required] public string ProductName { get; set; } + /// + /// The name of the menu item that this ticket was used on + /// + [Newtonsoft.Json.JsonProperty("usedOnMenuItemName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string UsedOnMenuItemName { get; set; } + + } + + /// + /// Representing a used ticket for a product + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] + public partial class UsedTicketResponse + { + /// + /// Ticket Id + /// + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] + public int Id { get; set; } + + /// + /// Issuing date time for ticket in Utc format + /// + [Newtonsoft.Json.JsonProperty("dateCreated", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.DateTimeOffset DateCreated { get; set; } + + /// + /// Used date time for ticket in Utc format + /// + [Newtonsoft.Json.JsonProperty("dateUsed", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.DateTimeOffset DateUsed { get; set; } + + /// + /// Name of product a ticket is for + /// + [Newtonsoft.Json.JsonProperty("productName", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public string ProductName { get; set; } + + /// + /// Name of the menu item that this ticket was used on + /// + [Newtonsoft.Json.JsonProperty("menuItemName", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string MenuItemName { get; set; } + + } + + /// + /// Represents a request to use a ticket. + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] + public partial class UseTicketRequest + { + /// + /// The id of the product the ticket is for. + /// + [Newtonsoft.Json.JsonProperty("productId", Required = Newtonsoft.Json.Required.Always)] + public int ProductId { get; set; } + + /// + /// The id of the menu item to use the ticket on. + /// + [Newtonsoft.Json.JsonProperty("menuItemId", Required = Newtonsoft.Json.Required.Always)] + public int MenuItemId { get; set; } + } /// @@ -3555,6 +4224,43 @@ public partial class IssueVoucherRequest } + /// + /// Represents a request to update user groups in bulk + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] + public partial class WebhookUpdateUserGroupRequest + { + /// + /// List of accounts and their new user groups + /// + [Newtonsoft.Json.JsonProperty("privilegedUsers", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required] + public System.Collections.Generic.ICollection PrivilegedUsers { get; set; } = new System.Collections.ObjectModel.Collection(); + + } + + /// + /// Represents an account user group update + /// + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] + public partial class AccountUserGroup + { + /// + /// The account id + /// + [Newtonsoft.Json.JsonProperty("accountId", Required = Newtonsoft.Json.Required.Always)] + public int AccountId { get; set; } + + /// + /// The user group + /// + [Newtonsoft.Json.JsonProperty("userGroup", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] + public UserGroup UserGroup { get; set; } + + } + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.18.0.0 (NJsonSchema v10.8.0.0 (Newtonsoft.Json v10.0.0.0))")] [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Interface, AllowMultiple = true)] internal class JsonInheritanceAttribute : System.Attribute diff --git a/Shifty.App/Components/MenuItems.razor b/Shifty.App/Components/MenuItems.razor new file mode 100644 index 0000000..a7c2ee5 --- /dev/null +++ b/Shifty.App/Components/MenuItems.razor @@ -0,0 +1,28 @@ +@namespace Components +@using System.ComponentModel.DataAnnotations +@using Shifty.App.Services +@using Shifty.Api.Generated.AnalogCoreV1 +@using Shifty.Api.Generated.AnalogCoreV2 +@using Shared +@using LanguageExt.UnsafeValueAccess +@using Shifty.App.Repositories +@inject ISnackbar Snackbar +@inject IJSRuntime JSRuntime + + + @if (_loading) + { + + + + } + + +@code +{ + private bool _loading = true; + + protected override async Task OnInitializedAsync() + { + } +} \ No newline at end of file diff --git a/Shifty.App/Components/ProductManager.razor b/Shifty.App/Components/ProductManager.razor index 4e2e9d3..43c8a7a 100644 --- a/Shifty.App/Components/ProductManager.razor +++ b/Shifty.App/Components/ProductManager.razor @@ -1,14 +1,18 @@ @namespace Components @using System.ComponentModel.DataAnnotations +@using MudExtensions @using Shifty.App.Services @using Shifty.Api.Generated.AnalogCoreV1 @using Shifty.Api.Generated.AnalogCoreV2 @using Shared @using LanguageExt.UnsafeValueAccess @using Components +@using Shifty.App.DomainModels +@using System.Collections.ObjectModel @inject ISnackbar Snackbar @inject IProductService ProductService @inject IJSRuntime JSRuntime +@inject IMenuItemService MenuItemService