Skip to content

Commit 3ec8908

Browse files
Create add-item article
Original article for adding an item to a cart when using Umbraco Commerce
1 parent 2986dc5 commit 3ec8908

File tree

1 file changed

+182
-0
lines changed
  • 13/umbraco-commerce/how-to-guides

1 file changed

+182
-0
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
description: How-To Guide to add an item to your cart.
3+
---
4+
5+
To add an item to the cart, you first need to setup Umbraco with a store and add the relevant properties (i.e. Price and Stock see https://docs.umbraco.com/umbraco-commerce/10.commerce.latest/key-concepts/umbraco-properties) to allow the store to interact with Umbraco.
6+
7+
## Add a product to the Cart
8+
You will need the Frontend to be setup to add allow an item to be added to the cart. This can be done by adding a button to the frontend that will call the Action to add the item to the cart.
9+
10+
Create a new View, we will call it product.cshtml with the below code
11+
12+
```csharp
13+
@{
14+
var store = Model.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
15+
var product = CommerceApi.Instance.GetProduct(store.Id, Model.Key.ToString(), "en-GB");
16+
var price = product.TryCalculatePrice();
17+
}
18+
```
19+
20+
- You will need to access the store so you have access to the relevant properties for your product such as price. The store has a fallback property allowing you to traverse up the tree to find the store.
21+
- We retrieve the product based on the store and a reference for the product (the 'productReference' in this instance is coming from the Model which is a single product).
22+
- The Product is returned as a ProductSnapshot which is Umbraco Commerce obtaining the page ID and carrying out necessary processes to bring in the data which it can use for further processing.
23+
- Finally we need to calculate the price which is then displayed without VAT (although can be also displayed with VAT)
24+
25+
To display this we need to add some markup or at least amend it to include a button to add an item. In the same file add the below
26+
27+
```csharp
28+
@using (Html.BeginUmbracoForm("AddToCart", "CartSurface"))
29+
{
30+
@Html.Hidden("productReference", Model.Key.ToString())
31+
<h1>@Model.ProductTitle</h1>
32+
<h2>@Model.ProductDescription</h2>
33+
34+
<p>Our price excluding VAT <strong>@price.Result?.WithoutTax.ToString("C0") </strong></p>
35+
36+
if (@Model.Stock == 0)
37+
{
38+
<p>Sorry, out of stock</p>
39+
}
40+
else
41+
{
42+
<button type="submit">Add to Basket</button>
43+
}
44+
45+
@await Html.PartialAsync("...../Feedback.cshtml")
46+
}
47+
```
48+
49+
The hidden field is using the productReference to be passed across to the Controller.
50+
51+
{% hint style="warning" %}
52+
53+
ModelsBuilder is used to access the properties of the page.
54+
If you are not using ModelsBuilder then you will need to use the following code to access the properties
55+
56+
Model.Value<IPublishedContent>("nameOfProperty")
57+
58+
{% endhint %}
59+
60+
## Adding the Controller
61+
62+
Create a new Controller called CartSurfaceController.cs
63+
64+
{% hint style="warning" %}
65+
66+
The namespaces used in this Controller are important and need to be included.
67+
68+
using Microsoft.AspNetCore.Mvc;
69+
using Umbraco.Cms.Core.Cache;
70+
using Umbraco.Cms.Core.Logging;
71+
using Umbraco.Cms.Core.Models.PublishedContent;
72+
using Umbraco.Cms.Core.Routing;
73+
using Umbraco.Cms.Core.Services;
74+
using Umbraco.Cms.Core.Web;
75+
using Umbraco.Cms.Infrastructure.Persistence;
76+
using Umbraco.Cms.Web.Website.Controllers;
77+
using Umbraco.Commerce.Common.Validation;
78+
using Umbraco.Commerce.Core.Api;
79+
using Umbraco.Commerce.Core.Models;
80+
using Umbraco.Commerce.Extensions;
81+
using Umbraco.Extensions;
82+
83+
{% endhint %}
84+
85+
```csharp
86+
public class CartSurfaceController : SurfaceController
87+
{
88+
public CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IUmbracoCommerceApi commerceApi) : base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
89+
{
90+
_commerceApi = commerceApi;
91+
}
92+
}
93+
```
94+
95+
The equivalent code for having this as a Primary Constructor
96+
97+
```csharp
98+
public class CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider) : SurfaceController(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
99+
{
100+
}
101+
```
102+
103+
104+
105+
The CartDto is a class that is used to pass the productReference across to the Controller. This is a simple class that has a property for the productReference.
106+
107+
```csharp
108+
public class CartDto
109+
{
110+
public string ProductReference { get; set; }
111+
}
112+
```
113+
114+
We now need to add the Action in order to add the item to the cart. This will be called when the button is clicked.
115+
116+
```csharp
117+
[HttpPost]
118+
public IActionResult AddToBasket(CartDto cart)
119+
{
120+
commerceApi.Uow.Execute(uow =>
121+
{
122+
var store = CurrentPage.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
123+
124+
if (store == null) return;
125+
126+
try
127+
{
128+
var order = commerceApi.GetOrCreateCurrentOrder(store.Id)
129+
.AsWritable(uow)
130+
.AddProduct(cart.ProductReference, 1);
131+
132+
commerceApi.SaveOrder(order);
133+
134+
uow.Complete();
135+
136+
TempData["SuccessFeedback"] = "Product added to cart";
137+
return RedirectToCurrentUmbracoPage();
138+
}
139+
catch (ValidationException ve)
140+
{
141+
throw new ValidationException(ve.Errors);
142+
}
143+
catch (Exception ex)
144+
{
145+
logger.Error(ex, "An error occurred.");
146+
}
147+
});
148+
}
149+
150+
```
151+
152+
- store variable is used to access the store to get the store ID.
153+
- A try catch block is used to capture any errors that may occur when adding the item to the cart, including any validation errors.
154+
- order is used to retrieve the current order if one exists or create a new order against the store found. In the Commerce Api everything is read-only for performance so we need to make it writable in order to add the product.
155+
- AddProduct is called and the passed in productReference is passed across along with the quantity.
156+
- SaveOrder is called to save the order.
157+
- TempData is used to store a message to be displayed to the user if the product has been added to the cart.
158+
159+
{% hint style="warning" %}
160+
Umbraco Commerce uses the Unit of Work pattern in order to complete saviing 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.
161+
{% endhint %}
162+
163+
Finally, we need to add the TempData to display a message to the user that the product has been added to the cart.
164+
165+
## Add a partial view to display the message
166+
167+
Create a new partial view called Feedback.cshtml
168+
169+
```csharp
170+
@Html.ValidationSummary(true, "", new { @class = "danger" })
171+
172+
@{
173+
var success = TempData["SuccessFeedback"]?.ToString();
174+
175+
if (!string.IsNullOrWhiteSpace(success))
176+
{
177+
<div class="success">@success</div>
178+
}
179+
}
180+
```
181+
182+
Run the application, click the button and the product will be added to the cart with a message displayed to the user.

0 commit comments

Comments
 (0)