Product units

Some products are sold by the kilo, some are sold in pairs, and others are sold in boxes.

In Dynamicweb, you can create product units – like kilo, pair, and box - and use them both to render the correct term for a particular product (like a pair of glasses) and to make multiple product units available for one product and let customers choose between ordering e.g. a pack, a box and a pallet of pencils.

You can select a default unit for a product using the stock settings.

To create a product unit:

  • Go to Settings > Ecommerce > Product Catalog > Product units
  • Click New product unit in the toolbar
  • Provide a name for the product unit
  • Save

You can only create new product units when your default language is selected in the toolbar.

Once a product unit has been created, you can create language-specific version of it by changing the language and saving the product unit in the new language.

If you don’t, no unit category label will be rendered in the frontend for that language. Read more about localization in Dynamicweb.

There are several ways to use product units:

  • You can set a default unit for products which are customarily sold as e.g. pairs of trousers, glasses, gloves etc.
  • You can make a product available in several product units, and price them accordingly using the price matrix

To set a default unit on a product, go to the product and select the default unit under advanced configuration. It is then available from your product list template using the StockUnits loop, and from the product details template using the Units loop.

To use several units for a single product:

  • Open the stock matrix
  • Create a row per unit you want to make available (Figure 2.1)
  • Save

The units are now available from your product templates.

Figure 2.1 Making more that one unit available for a product

Adding a unit selector to the Add to cart form in the Product details template:

<select name="unitID"> @foreach(LoopItem stocklocation in GetLoop("Units")){ <option value="@stocklocation.GetValue("Ecom:VariantOption.ID")">@stocklocation.GetValue("Ecom:VariantOption.Name")</option> } </select>

Adding a unit selector to the Add to cart form in the Product List template:

<select name="UnitID" class="form-control"> @foreach(LoopItem unit in product.GetLoop("StockUnits")){ if(GetString("Ecom:Product.DefaultUnitID") == @unit.GetString("Ecom:StockUnit.UnitID") ){ <option value="@unit.GetValue("Ecom:StockUnit.UnitID")" selected>@unit.GetValue("Ecom:StockUnit.Unit")</option> } else{ <option value="@unit.GetValue("Ecom:StockUnit.UnitID")">@unit.GetValue("Ecom:StockUnit.Unit")</option> } } </select>

Different product units usually mean different prices per unit – you usually want a box of items to be more expensive than a single item.

To make that possible, open the price matrix and create one price per product unit (Figure 3.1) – if you can’t select any of your units, it’s because you haven’t added them to the stock matrix for the product as outlined above.

Figure 3.1 Creating prices based on stock units

You now have access to product unit prices from the Units loop in the product details template:

@foreach (LoopItem unit in GetLoop("Units")) @unit.GetValue("Ecom:VariantOption.Price.Price") }

To add a product (from product details page) to the shopping cart with the correct unit and price, you simply use cartcmd in the standard manner but include a unitID:

<form method="post" action=""> <div class="col-md-4 col-xs-4"> <select name="unitID"> @foreach (LoopItem stocklocation in GetLoop("Units")) { if (GetString("Ecom:Product.DefaultUnitID") == stocklocation.GetString("Ecom:VariantOption.ID")) { <option id="@stocklocation.GetValue("Ecom:VariantOption.ID")" value="@stocklocation.GetValue("Ecom:VariantOption.ID")">@stocklocation.GetValue("Ecom:VariantOption.Name")</option> } else { <option id="@stocklocation.GetValue("Ecom:VariantOption.ID")" value="@stocklocation.GetValue("Ecom:VariantOption.ID")">@stocklocation.GetValue("Ecom:VariantOption.Name")</option> } } </select> </div> <input type="hidden" name="Redirect" value="false" /> <input type="hidden" name="CartCmd" value="add" /> <input type="hidden" name="ProductID" value="@GetString("Ecom:Product.ID")" /> <input type="hidden" name="VariantID" value="@GetString("Ecom:Product.VariantID")" /> <input type="number" name="Quantity" value="1> <button type="submit" name="submit" >@Translate("Add to cart", "Add to cart")</button> </form>

You can use Javascript to change the price in frontend according to price, or show different units in table with the unit price, and add to cart buttons.

Please note, that orders in the backend do not show the unit for an order, but you can use an order line field to show the correct UnitID. Read more about order line fields here.

To do so add an order line field to add to cart command (if you have more than one order line field remember an if statement to use the right one):

@foreach (LoopItem orderline in GetLoop("Product.OrderLineFields")) { <input type="hidden" id="unitfield" name="@orderline.GetValue("Ecom:Product.OrderLineField.InputTextFieldName")" value="@GetString("Ecom:Product.DefaultUnitID")" /> }

Be aware!

Please be aware that using the Ecom:Product.Form.Clean tag to generate the hidden-fields automatically, the default unitID will always be used as the unitID.

So instead of using the tag simply create and submit the hidden-fields manually. An example of the hidden-fields you need to create can be seen in Figure 4.3 – the minimum requirements being product ID, variant ID, unit ID, and cartcmd=add

Figure 4.3 To ensure that you add the right unitID to cart, you must submit the fields usually rendered by Ecom:Product.Form.Clean manually

Database

These are the database tables associated with units and stock in Dynamicweb.

EcomStockGroups

Contains setup date for stock states as defined in Settings -> Ecommerce -> Orders -> Stock state.

Field name Data type Length
StockGroupId nvarchar 50
StockGroupName nvarchar 255
StockGroupAutoId int 4

EcomStockStatusLanguageValue

Contains translated (StockStatusLanguageValueLanguageId) data for individual stock states.

Field name Data type Length
StockStatusLanguageValueId nvarchar 50
StockStatusLanguageValueLinesId nvarchar 50
StockStatusLanguageValueLanguageId nvarchar 50
StockStatusLanguageValueText nvarchar 255
StockStatusLanguageValueDeliveryValue nvarchar 255
StockStatusLanguageValueDeliveryText nvarchar 255
StockStatusLanguageValueAutoId int 4

EcomStockLocation

Contains setup data for stock locations as defined in Settings -> Ecommerce -> Product catalog -> Stock location.

Field name Data type Length
StockLocationId int 4
StockLocationName nvarchar 255
StockLocationDescription nvarchar Max
StockLocationLanguageId nvarchar 50
StockSortOrder int 4
StockLocationGroupId bigint 8

EcomStockStatusLine

Links stock states from EcomStockStatusLanguageValue (StockStatusLinesId) to stock groups from EcomStockGroups (StockStatusLinesGroupId).

Field name Data type Length
StockStatusLinesId nvarchar 50
StockStatusLinesGroupId nvarchar 50
StockStatusLinesRate float 8
StockStatusLinesDefinition nvarchar 50
StockStatusLinesIcon nvarchar 255
StockStatusLineAutoId int 4

EcomStockUnit

Keeps track of stock quantity (StockUnitQuantity) in different units (StockUnitId) for products (StockUnitProductId, StockUnitVariantId) across various locations (StockUnitLocationId).

Field name Data type Length
StockUnitProductId nvarchar 30
StockUnitVariantId nvarchar 255
StockUnitId nvarchar 50
StockUnitQuantity float 8
StockUnitWeight float 8
StockUnitVolume float 8
StockUnitStockLocationId bigint 8
Id int 4
StockUnitDescription nvarchar 255
StockUnitProductNumber nvarchar 255