Skip to content

Commit 55103db

Browse files
authored
Merge pull request #6706 from umbraco/commerce-guides
Adding missing Commerce guides to v14 and v15
2 parents 2b5f4e8 + b62fba0 commit 55103db

File tree

12 files changed

+1204
-18
lines changed

12 files changed

+1204
-18
lines changed

13/umbraco-commerce/how-to-guides/delete-item.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ description: Learn how to remove items added to the shopping cart.
55
# Delete item from cart
66

77
{% hint style="info" %}
8-
This guide builds on the guide on [update-cart.md). It is recommended to follow that guide before starting this one.
8+
This guide builds on the [Update Cart](update-cart.md) guide. It is recommended to follow that guide before starting this one.
99
{% endhint %}
1010

1111
This will teach you how to delete an item from the cart.
1212

13-
Your view for the `cart.cshtml` page will be similar the example below.
13+
Your view for the `cart.cshtml` page will be similar to the example below.
1414

1515
```csharp
1616
@inherits UmbracoViewPage
1717
@{
18-
var store = Model.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
19-
var currentOrder = CommerceApi.Instance.GetCurrentOrder(store!.Id);
20-
if (currentOrder == null) return;
18+
var store = Model.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
19+
var currentOrder = CommerceApi.Instance.GetCurrentOrder(store!.Id);
20+
if (currentOrder == null) return;
2121

2222
@using (Html.BeginUmbracoForm("UpdateCart", "CartSurface"))
2323
{
@@ -64,7 +64,7 @@ Create a new Controller called `CartSurfaceController.cs`
6464

6565
The namespaces used in this Controller are important and need to be included.
6666

67-
```
67+
```cs
6868
using Microsoft.AspNetCore.Mvc;
6969
using Umbraco.Cms.Core.Cache;
7070
using Umbraco.Cms.Core.Logging;
@@ -115,8 +115,6 @@ public class CartSurfaceController(IUmbracoContextAccessor umbracoContextAccesso
115115
}
116116
```
117117

118-
119-
120118
The `CartDto` is a class used to pass data to the Controller. In this instance, it passes over the `OrderLineId`.
121119

122120
```csharp

13/umbraco-commerce/how-to-guides/update-cart.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
description: Learn how to update your cart when one or more quantities have changed.
33
---
44

5-
# Update Card
5+
# Update Cart
66

77
Functionality is needed to update the cart once an item has been added. In this guide, you can learn how to add this functionality.
88

@@ -13,9 +13,9 @@ Create a new Document With a Template. Call it "Cart Page" and update the templa
1313
```csharp
1414
@inherits UmbracoViewPage
1515
@{
16-
var store = Model.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
17-
var currentOrder = CommerceApi.Instance.GetCurrentOrder(store!.Id);
18-
if (currentOrder == null) return;
16+
var store = Model.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
17+
var currentOrder = CommerceApi.Instance.GetCurrentOrder(store!.Id);
18+
if (currentOrder == null) return;
1919
}
2020
```
2121

@@ -77,7 +77,7 @@ This is setting the product reference in the cart/order so there is a way to dis
7777

7878
{% hint style="warning" %}
7979

80-
The `remove` button is added here but is not covered in this guide. Learn more in the [Remove from card](delete-item.md) article.
80+
The `remove` button is added here but is not covered in this guide. Learn more in the [Delete item from Cart](delete-item.md) article.
8181

8282
{% endhint %}
8383

@@ -91,7 +91,7 @@ Create a new Controller called `CartSurfaceController.cs`
9191

9292
The namespaces used in this Controller are important and need to be included.
9393

94-
```
94+
```cs
9595
using Microsoft.AspNetCore.Mvc;
9696
using Umbraco.Cms.Core.Cache;
9797
using Umbraco.Cms.Core.Logging;

14/umbraco-commerce/SUMMARY.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
* [Configure SQLite support](how-to-guides/configure-sqlite-support.md)
3434
* [Limit Order Line Quantity](how-to-guides/limit-orderline-quantity.md)
3535
* [Use an Alternative Database for Umbraco Commerce Tables](how-to-guides/use-an-alternative-database-for-umbraco-commerce-tables.md)
36+
* [Add item to Cart](how-to-guides/add-item.md)
37+
* [Update Cart](how-to-guides/update-cart.md)
38+
* [Delete item from Cart](how-to-guides/delete-item.md)
3639

3740
## Key Concepts
3841

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
---
2+
description: How-To Guide to add an item to your cart.
3+
---
4+
5+
# Add item to Cart
6+
7+
To add an item to the cart, configure Umbraco with a store and add the necessary properties for interaction. Learn more by following the [Getting started with Umbraco Commerce: The Backoffice tutorial](../tutorials/getting-started-with-commerce.md).
8+
9+
You will need the front end to be set up to allow an item to be added to the cart. This can be done by adding a button to the front end to call the Action to add the item to the cart.
10+
11+
Create a new Document Type with the template. Call it **Product Page** with the following property aliases: `productTitle`, `productDescription`, `price`, `stock`.
12+
13+
The following property editors are recommended to be used for the above:
14+
15+
* `productTitle`: TextString
16+
* `productDescription`: TextArea
17+
* `price`: Umbraco Commerce Price
18+
* `stock`: Umbraco Commerce Stock
19+
20+
The Product Page template can be implemented as shown below.
21+
22+
```csharp
23+
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ProductPage>
24+
@{
25+
var store = Model.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
26+
var product = CommerceApi.Instance.GetProduct(store.Id, Model.Key.ToString(), "en-GB");
27+
var price = product.TryCalculatePrice().ResultOrThrow("Unable to calculate product price");
28+
}
29+
```
30+
31+
The code above does the following:
32+
33+
- You need to access the store to access the relevant properties for your product, such as price. The store has a fallback property allowing you to traverse the tree to find the store.
34+
- You retrieve the product based on the store and a reference for the product. The 'productReference' comes from the Model which is a single product.
35+
- 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 for further processing.
36+
- Finally, you need to calculate the price which is then displayed without VAT. This can also be displayed with VAT.
37+
38+
To display this you need to add some markup or at least amend it to include a button to add an item. Add the following to the same file:
39+
40+
```csharp
41+
@using (Html.BeginUmbracoForm("AddToCart", "CartSurface"))
42+
{
43+
@Html.Hidden("productReference", Model.Key.ToString())
44+
<h1>@Model.Value<string>("productTitle")</h1>
45+
<h2>@Model.Value<string>("productDescription")</h2>
46+
47+
<p>Our price excluding VAT <strong>@price.WithoutTax.ToString("C0") </strong></p>
48+
49+
if (@Model.Value<int>("stock") == 0)
50+
{
51+
<p>Sorry, out of stock</p>
52+
}
53+
else
54+
{
55+
<button type="submit">Add to Basket</button>
56+
}
57+
58+
}
59+
```
60+
61+
The hidden field uses the `productReference` to be passed across to the Controller.
62+
63+
## Adding the Controller
64+
65+
For the button to work, you need to implement a controller. An example of this is shown below.
66+
67+
Create a new Controller called `CartSurfaceController.cs`.
68+
69+
{% hint style="warning" %}
70+
71+
The namespaces used in this Controller are important and need to be included.
72+
73+
```
74+
using Microsoft.AspNetCore.Mvc;
75+
using Umbraco.Cms.Core.Cache;
76+
using Umbraco.Cms.Core.Logging;
77+
using Umbraco.Cms.Core.Models.PublishedContent;
78+
using Umbraco.Cms.Core.Routing;
79+
using Umbraco.Cms.Core.Services;
80+
using Umbraco.Cms.Core.Web;
81+
using Umbraco.Cms.Infrastructure.Persistence;
82+
using Umbraco.Cms.Web.Website.Controllers;
83+
using Umbraco.Commerce.Common.Validation;
84+
using Umbraco.Commerce.Core.Api;
85+
using Umbraco.Commerce.Core.Models;
86+
using Umbraco.Commerce.Extensions;
87+
using Umbraco.Extensions;
88+
```
89+
90+
{% endhint %}
91+
92+
```csharp
93+
public class CartSurfaceController : SurfaceController
94+
{
95+
public CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor,
96+
IUmbracoDatabaseFactory databaseFactory,
97+
ServiceContext services, AppCaches appCaches,
98+
IProfilingLogger profilingLogger,
99+
IPublishedUrlProvider publishedUrlProvider,
100+
IUmbracoCommerceApi commerceApi)
101+
: base(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
102+
{
103+
_commerceApi = commerceApi;
104+
}
105+
}
106+
```
107+
108+
Below you can see the equivalent code for having this as a Primary Constructor:
109+
110+
```csharp
111+
public class CartSurfaceController(IUmbracoContextAccessor umbracoContextAccessor,
112+
IUmbracoDatabaseFactory databaseFactory,
113+
ServiceContext services, AppCaches appCaches,
114+
IProfilingLogger profilingLogger,
115+
IPublishedUrlProvider publishedUrlProvider)
116+
: SurfaceController(umbracoContextAccessor, databaseFactory, services, appCaches, profilingLogger, publishedUrlProvider)
117+
{
118+
}
119+
```
120+
121+
The CartDto class below is used to pass the `productReference` across to the Controller. This class has only one property for the `productReference`.
122+
123+
```csharp
124+
public class CartDto
125+
{
126+
public string ProductReference { get; set; }
127+
}
128+
```
129+
130+
We now need to add the Action to add the item to the cart. This action will be called when the button is clicked.
131+
132+
```csharp
133+
[HttpPost]
134+
public IActionResult AddToBasket(CartDto cart)
135+
{
136+
commerceApi.Uow.Execute(uow =>
137+
{
138+
var store = CurrentPage.Value<StoreReadOnly>("store", fallback: Fallback.ToAncestors);
139+
140+
if (store == null) return;
141+
142+
try
143+
{
144+
var order = commerceApi.GetOrCreateCurrentOrder(store.Id)
145+
.AsWritable(uow)
146+
.AddProduct(cart.ProductReference, 1);
147+
148+
commerceApi.SaveOrder(order);
149+
150+
uow.Complete();
151+
152+
TempData["SuccessFeedback"] = "Product added to cart";
153+
return RedirectToCurrentUmbracoPage();
154+
}
155+
catch (ValidationException ve)
156+
{
157+
throw new ValidationException(ve.Errors);
158+
}
159+
catch (Exception ex)
160+
{
161+
logger.Error(ex, "An error occurred.");
162+
}
163+
});
164+
}
165+
```
166+
167+
The code above does the following:
168+
169+
- The `store` variable is used to access the store to get the store ID.
170+
- A try-catch block captures any errors that may occur when adding the item to the cart, including any validation errors.
171+
- `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 you need to make it writable to add the product.
172+
- `AddProduct` is called and `productReference` is passed along with the quantity.
173+
- `SaveOrder` is called to save the order.
174+
- `TempData` stores a message to be displayed to the user if the product has been added to the cart.
175+
176+
{% hint style="warning" %}
177+
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.
178+
{% endhint %}
179+
180+
Finally, you need to add the `TempData` to tell the user that the product has been added to the cart.
181+
182+
## Add a partial view to display the message
183+
184+
Create a new partial view called `Feedback.cshtml`.
185+
186+
```csharp
187+
@Html.ValidationSummary(true, "", new { @class = "danger" })
188+
189+
@{
190+
var success = TempData["SuccessFeedback"]?.ToString();
191+
192+
if (!string.IsNullOrWhiteSpace(success))
193+
{
194+
<div class="success">@success</div>
195+
}
196+
}
197+
```
198+
199+
You can now run the application, click the button, and see the product added to the cart with a message displayed to the user.

0 commit comments

Comments
 (0)