From 1af65a86ea45ec3055003c152f4148d8a845e872 Mon Sep 17 00:00:00 2001 From: MrEssCee <67432920+MrEssCee@users.noreply.github.com> Date: Sat, 5 Oct 2024 15:48:11 +0100 Subject: [PATCH 1/3] Create delete-item.md Create a tutorial on how to delete an item from the cart --- .../how-to-guides/delete-item.md | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 13/umbraco-commerce/how-to-guides/delete-item.md diff --git a/13/umbraco-commerce/how-to-guides/delete-item.md b/13/umbraco-commerce/how-to-guides/delete-item.md new file mode 100644 index 00000000000..3ff910f2886 --- /dev/null +++ b/13/umbraco-commerce/how-to-guides/delete-item.md @@ -0,0 +1,151 @@ +## Delete item from cart +Following on from the previous guide on [updating an item in the cart](/umbraco-commerce/how-to-guides/update-cart.md), we will now look at how to delete an item from the cart. + +{% hint style="warning" %} +This tutorial focuses only on the delete functionality. Please see the other guides for more information for areas not covered here. +{% endhint %} + +Your view will be similar to the below for the `cart.cshtml` page. + +```csharp +@inherits UmbracoViewPage +@{ + var store = Model.Value("store", fallback: Fallback.ToAncestors); + var currentOrder = CommerceApi.Instance.GetCurrentOrder(store!.Id); + if (currentOrder == null) return; + + @using (Html.BeginUmbracoForm("UpdateCart", "CartSurface")) + { + @foreach (var item in currentOrder.OrderLines.Select((ol, i) => new + { + OrderLine = ol, + Index = i + })) + { +

+ @Html.Hidden($"orderLines[{item.Index}].Id", item.OrderLine.Id) + @item.OrderLine.Name @Html.Hidden($"orderLines[{item.Index}].Quantity", (int)item.OrderLine.Quantity, new { @type = "number" }) + @Html.Hidden($"orderLines[{item.Index}].ProductReference", item.OrderLine.ProductReference) + Remove Item +

+ + } + + + + var success = TempData["SuccessMessage"]?.ToString(); + + if (!string.IsNullOrWhiteSpace(success)) + { +
@success
+ } + } +} +``` + +- The below code allows the Umbraco `SurfaceAction` to call `RemoveFromCart` when the link is clicked as well as passing the `OrderLineId`. +```csharp +Remove +``` +## Adding the Controller + +Create a new Controller called `CartSurfaceController.cs` + +{% hint style="warning" %} + +The namespaces used in this Controller are important and need to be included. + + using Microsoft.AspNetCore.Mvc; + using Umbraco.Cms.Core.Cache; + using Umbraco.Cms.Core.Logging; + using Umbraco.Cms.Core.Models.PublishedContent; + using Umbraco.Cms.Core.Routing; + using Umbraco.Cms.Core.Services; + using Umbraco.Cms.Core.Web; + using Umbraco.Cms.Infrastructure.Persistence; + using Umbraco.Cms.Web.Website.Controllers; + using Umbraco.Commerce.Common.Validation; + using Umbraco.Commerce.Core.Api; + using Umbraco.Commerce.Core.Models; + using Umbraco.Commerce.Extensions; + using Umbraco.Extensions; + +{% endhint %} + +```csharp +public class CartSurfaceController : SurfaceController +{ + public CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IUmbracoCommerceApi commerceApi) : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) + { + _commerceApi = commerceApi; + } +} +``` + +The equivalent code for having this as a Primary Constructor + +```csharp +public class CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IUmbracoCommerceApi commerceApi) : SurfaceController(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) +{ +} +``` + + + +The `CartDto` is a class that is used to pass data to the Controller. In this instance it is passing over the OrderLineId. + +```csharp + public class CartDto + { + public Guid OrderLineId { get; set; } + } +``` + +We now need to add the `Action` in order to delete the item from the cart. This will be called when the button is clicked. + +```csharp + [HttpGet] + public IActionResult RemoveFromCart(CartDto cart) + { + try + { + _commerceApi.Uow.Execute(uow => + { + var store = CurrentPage?.Value("store", fallback: Fallback.ToAncestors); + + if (store == null) return; + + var order = _commerceApi.GetOrCreateCurrentOrder(store.Id) + .AsWritable(uow) + .RemoveOrderLine(cart.OrderLineId); + + _commerceApi.SaveOrder(order); + + uow.Complete(); + }); + } + catch (ValidationException) + { + ModelState.AddModelError(string.Empty, "Failed to remove product from cart"); + + return CurrentUmbracoPage(); + } + + TempData["SuccessMessage"] = "Item removed"; + + return RedirectToCurrentUmbracoPage(); + } +``` + +- A `try catch` block is used to capture any validation errors that may occur when updating items in the cart. +- `store` variable is used to access the store to retrieve the store ID. +- `order` is used to retrieve the current order. In the Commerce Api everything is read-only for performance so we need to make it writable in order to add the product. +- `SaveOrder` is called to save the order. +- If there are any validation errors, they are added to ModelState error and the user is redirected back to the current page. +- `TempData` is used to store a message to be displayed to the user if the product has been succesfully updated. + +{% hint style="warning" %} +Umbraco Commerce uses the Unit of Work pattern in order to complete saving the item (uow.Complete). When retrieving or saving data ideally you would want the entire transaction to be committed however if there is an error then nothing is changed on the database. +{% endhint %} + +If you have followed the 'Add item to cart' article then run the application, add an item to your cart and navigate to your cart.cshtml page. Clicking the `Remove Item` button would delete the the item in your cart and display a success message. From 661369a72c8b86ed80aa8d7e4302638086735165 Mon Sep 17 00:00:00 2001 From: sofietoft Date: Tue, 8 Oct 2024 10:38:58 +0200 Subject: [PATCH 2/3] Correct grammar and context --- .../how-to-guides/delete-item.md | 131 ++++++++++-------- 1 file changed, 76 insertions(+), 55 deletions(-) diff --git a/13/umbraco-commerce/how-to-guides/delete-item.md b/13/umbraco-commerce/how-to-guides/delete-item.md index 3ff910f2886..7932de9b48c 100644 --- a/13/umbraco-commerce/how-to-guides/delete-item.md +++ b/13/umbraco-commerce/how-to-guides/delete-item.md @@ -1,11 +1,12 @@ -## Delete item from cart -Following on from the previous guide on [updating an item in the cart](/umbraco-commerce/how-to-guides/update-cart.md), we will now look at how to delete an item from the cart. +# Delete item from cart -{% hint style="warning" %} -This tutorial focuses only on the delete functionality. Please see the other guides for more information for areas not covered here. +{% hint style="info" %} +This guide builds on the guide on [update-cart.md). It is recommended to follow that guide before starting this one. {% endhint %} -Your view will be similar to the below for the `cart.cshtml` page. +This will teach you how to delete an item from the cart. + +Your view for the `cart.cshtml` page will be similar the example below. ```csharp @inherits UmbracoViewPage @@ -43,56 +44,76 @@ Your view will be similar to the below for the `cart.cshtml` page. } ``` -- The below code allows the Umbraco `SurfaceAction` to call `RemoveFromCart` when the link is clicked as well as passing the `OrderLineId`. +The code below allows the Umbraco `SurfaceAction` to call `RemoveFromCart` when the link is clicked. It will also pass the `OrderLineId`. + ```csharp Remove ``` + ## Adding the Controller +For the button to work, you need to add some functionality via a Controller. + Create a new Controller called `CartSurfaceController.cs` {% hint style="warning" %} The namespaces used in this Controller are important and need to be included. - using Microsoft.AspNetCore.Mvc; - using Umbraco.Cms.Core.Cache; - using Umbraco.Cms.Core.Logging; - using Umbraco.Cms.Core.Models.PublishedContent; - using Umbraco.Cms.Core.Routing; - using Umbraco.Cms.Core.Services; - using Umbraco.Cms.Core.Web; - using Umbraco.Cms.Infrastructure.Persistence; - using Umbraco.Cms.Web.Website.Controllers; - using Umbraco.Commerce.Common.Validation; - using Umbraco.Commerce.Core.Api; - using Umbraco.Commerce.Core.Models; - using Umbraco.Commerce.Extensions; - using Umbraco.Extensions; +``` +using Microsoft.AspNetCore.Mvc; +using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.Logging; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Routing; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Web; +using Umbraco.Cms.Infrastructure.Persistence; +using Umbraco.Cms.Web.Website.Controllers; +using Umbraco.Commerce.Common.Validation; +using Umbraco.Commerce.Core.Api; +using Umbraco.Commerce.Core.Models; +using Umbraco.Commerce.Extensions; +using Umbraco.Extensions; +``` {% endhint %} ```csharp public class CartSurfaceController : SurfaceController { - public CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IUmbracoCommerceApi commerceApi) : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) + public CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, + IUmbracoDatabaseFactory databaseFactory, + ServiceContext services, + AppCaches appCaches, + IProfilingLogger profilingLogger, + IPublishedUrlProvider publishedUrlProvider, + IUmbracoCommerceApi commerceApi) + : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) { _commerceApi = commerceApi; } } ``` -The equivalent code for having this as a Primary Constructor +The example below is the equivalent code for having this as a Primary Constructor: ```csharp -public class CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IUmbracoCommerceApi commerceApi) : SurfaceController(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) +public class CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, + IUmbracoDatabaseFactory databaseFactory, + ServiceContext services, + AppCaches appCaches, + IProfilingLogger profilingLogger, + IPublishedUrlProvider publishedUrlProvider, + IUmbracoCommerceApi commerceApi) + : SurfaceController(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider) { } ``` -The `CartDto` is a class that is used to pass data to the Controller. In this instance it is passing over the OrderLineId. +The `CartDto` is a class used to pass data to the Controller. In this instance, it passes over the `OrderLineId`. ```csharp public class CartDto @@ -101,51 +122,51 @@ The `CartDto` is a class that is used to pass data to the Controller. In this in } ``` -We now need to add the `Action` in order to delete the item from the cart. This will be called when the button is clicked. +You need to add the `Action` to delete the item from the cart. This will be called when the button is clicked. ```csharp - [HttpGet] - public IActionResult RemoveFromCart(CartDto cart) +[HttpGet] +public IActionResult RemoveFromCart(CartDto cart) +{ + try + { + _commerceApi.Uow.Execute(uow => { - try - { - _commerceApi.Uow.Execute(uow => - { - var store = CurrentPage?.Value("store", fallback: Fallback.ToAncestors); + var store = CurrentPage?.Value("store", fallback: Fallback.ToAncestors); - if (store == null) return; + if (store == null) return; - var order = _commerceApi.GetOrCreateCurrentOrder(store.Id) - .AsWritable(uow) - .RemoveOrderLine(cart.OrderLineId); + var order = _commerceApi.GetOrCreateCurrentOrder(store.Id) + .AsWritable(uow) + .RemoveOrderLine(cart.OrderLineId); - _commerceApi.SaveOrder(order); + _commerceApi.SaveOrder(order); - uow.Complete(); - }); - } - catch (ValidationException) - { - ModelState.AddModelError(string.Empty, "Failed to remove product from cart"); + uow.Complete(); + }); + } + catch (ValidationException) + { + ModelState.AddModelError(string.Empty, "Failed to remove product from cart"); - return CurrentUmbracoPage(); - } + return CurrentUmbracoPage(); + } - TempData["SuccessMessage"] = "Item removed"; + TempData["SuccessMessage"] = "Item removed"; - return RedirectToCurrentUmbracoPage(); - } + return RedirectToCurrentUmbracoPage(); +} ``` -- A `try catch` block is used to capture any validation errors that may occur when updating items in the cart. -- `store` variable is used to access the store to retrieve the store ID. -- `order` is used to retrieve the current order. In the Commerce Api everything is read-only for performance so we need to make it writable in order to add the product. +- A `try-catch` block captures any validation errors that may occur when updating items in the cart. +- The `store` variable is used to access the store to retrieve the store ID. +- `order` is used to retrieve the current order. In the Commerce API, everything is read-only for performance so you need to make it writable to add the product. - `SaveOrder` is called to save the order. -- If there are any validation errors, they are added to ModelState error and the user is redirected back to the current page. -- `TempData` is used to store a message to be displayed to the user if the product has been succesfully updated. +- If there are any validation errors, they are added to a `ModelState` error, and the user is redirected back to the current page. +- `TempData` stores a message to be displayed to the user if the product has been successfully updated. {% hint style="warning" %} -Umbraco Commerce uses the Unit of Work pattern in order to complete saving the item (uow.Complete). When retrieving or saving data ideally you would want the entire transaction to be committed however if there is an error then nothing is changed on the database. +Umbraco Commerce uses the Unit of Work pattern to complete saving the item (`uow.Complete`). When retrieving or saving data ideally you would want the entire transaction to be committed. However, if there is an error nothing is changed on the database. {% endhint %} -If you have followed the 'Add item to cart' article then run the application, add an item to your cart and navigate to your cart.cshtml page. Clicking the `Remove Item` button would delete the the item in your cart and display a success message. +If you have followed the [Add item to cart](add-item.md) article, run the application, add an item to your cart, and navigate to your `cart.cshtml` page. Clicking the `Remove Item` button will delete the item in your cart and display a message. From d15c107fc95a856dcf59b83f5a2a15b3242babf6 Mon Sep 17 00:00:00 2001 From: sofietoft Date: Tue, 8 Oct 2024 13:32:40 +0200 Subject: [PATCH 3/3] Small change to trigger GitBook checks --- 13/umbraco-commerce/how-to-guides/delete-item.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/13/umbraco-commerce/how-to-guides/delete-item.md b/13/umbraco-commerce/how-to-guides/delete-item.md index 7932de9b48c..12b750e77b4 100644 --- a/13/umbraco-commerce/how-to-guides/delete-item.md +++ b/13/umbraco-commerce/how-to-guides/delete-item.md @@ -1,3 +1,7 @@ +--- +description: Learn how to remove items added to the shopping cart. +--- + # Delete item from cart {% hint style="info" %}