Skip to content

Commit

Permalink
OCC-189: Documentation: Parts and Fields (#364)
Browse files Browse the repository at this point in the history
* Testing

* Adding documentation page and images for InventoryPart

* Adding documentation page and images for ProductPart

* Adding documentation page and images for PricePart

* Adding documentation and images for PriceVariantsPart

* Adding documentation and images for TieredPricePart

* Adding documentation pages and images for product attributes

* Fixing typo

* Fixing links and improving formatting

* Adding improvements and clarifications

* Improving formatting

* Renaming

* Fixing links

* Fixing sentence
  • Loading branch information
porgabi authored Oct 11, 2023
1 parent 16b89e5 commit b63eae4
Show file tree
Hide file tree
Showing 41 changed files with 209 additions and 9 deletions.
8 changes: 8 additions & 0 deletions OrchardCore.Commerce.sln
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{BEBA1764-1
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "features", "features", "{9B2DB1CD-2B4A-4823-9762-CF4E90661404}"
ProjectSection(SolutionItems) = preProject
docs\features\boolean-product-attribute-field.md = docs\features\boolean-product-attribute-field.md
docs\features\inventory-part.md = docs\features\inventory-part.md
docs\features\inventory.md = docs\features\inventory.md
docs\features\numeric-product-attribute-field.md = docs\features\numeric-product-attribute-field.md
docs\features\price-part.md = docs\features\price-part.md
docs\features\price-variants-part.md = docs\features\price-variants-part.md
docs\features\product-part.md = docs\features\product-part.md
docs\features\products-and-prices.md = docs\features\products-and-prices.md
docs\features\promotions.md = docs\features\promotions.md
docs\features\stripe-payment.md = docs\features\stripe-payment.md
docs\features\taxation.md = docs\features\taxation.md
docs\features\text-product-attribute-field.md = docs\features\text-product-attribute-field.md
docs\features\tiered-price-part.md = docs\features\tiered-price-part.md
docs\features\user-features.md = docs\features\user-features.md
docs\features\workflows.md = docs\features\workflows.md
EndProjectSection
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions docs/features/boolean-product-attribute-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# BooleanProductAttributeField

Adds a checkbox so the buyer can communicate some kind of yes/no choice about their purchase. Currently this attribute is not supported for price variant creation.

## Fields and properties
- **Hint** (`string`): Sets the description text to display for this attribute on the product's page.
- **DefaultValue** (`T`): Sets the default value.
- **Label** (`string`): Sets the text associated to the checkbox for this attribute on the product page.

## Usage examples
New attribute fields can be added or existing fields can be edited in the relevant product content type's editor.
![image](../assets/images/boolean-product-attribute-field/content-type-editor-example.png)

![image](../assets/images/boolean-product-attribute-field/attribute-field-editor-example.png)

Attribute fields are displayed on the product's page.
![image](../assets/images/boolean-product-attribute-field/attribute-field-display-example.png)
34 changes: 34 additions & 0 deletions docs/features/inventory-part.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# InventoryPart

The `InventoryPart` adds basic inventory management capabilities to a product. Requires [`ProductPart`](product-part.md) to be present on the content type as well.

## Fields and properties
- **AllowsBackOrder** (`BooleanField`): When set to true, product can be ordered even when the Inventory field's value is below 1.
- **IgnoreInventory** (`BooleanField`): When set to true, all inventory checks (within [`InventoryShoppingCartEvents`](https://github.com/OrchardCMS/OrchardCore.Commerce/blob/main/src/Modules/OrchardCore.Commerce/Events/InventoryShoppingCartEvents.cs)) are bypassed.
- **Inventory** (`IDictionary<string, int>`): Sets the number of available products. Uses a `Dictionary<string, int>` object to keep track of multiple inventories (which is mostly relevant for products with a [`PriceVariantsPart`](price-variants-part.md) attached to them).
- **MaximumOrderQuantity** (`NumericField`): Determines the maximum amount of products that can be placed in an order. Also sets the upper limit for the _Quantity_ input on the product's page. This field is ignored if its value is set to 0 or below.
- **MinimumOrderQuantity** (`NumericField`): Determines the minimum amount of products that can be placed in an order. Also sets the lower limit for the _Quantity_ input on the product's page. This field is ignored if its value is set to 0 or below.
- **OutOfStockMessage** (`HtmlField`): Enables providing a specific message for an out of stock product. Defaults to "Out of Stock".

By default, the below fields' shapes are empty, so they do not show up on the user-facing part of the site:

- _AllowsBackOrder_
- _IgnoreInventory_
- _MaximumOrderQuantity_
- _MinimumOrderQuantity_

## Usage examples
All the inventory-related settings can be found in the product's editor.
![image](../assets/images/inventory-part/inventory-editor-example.png)

With a product's inventory set to a valid value, the current inventory count will appear on the product's page.
![image](../assets/images/inventory-part/inventory-value-example.png)

With a maximum order quantity specified, trying to add more products to the cart than allowed will result in a validation error.
![image](../assets/images/inventory-part/inventory-max-quantity-example.png)

With a minimum order quantity specified, trying to add fewer products to the cart than allowed will result in a validation error.
![image](../assets/images/inventory-part/inventory-min-quantity-example.png)

With a custom out of stock message provided, the message will show up on the product's page when its inventory is below 1 and back ordering is not allowed.
![image](../assets/images/inventory-part/inventory-out-of-stock-example.png)
2 changes: 1 addition & 1 deletion docs/features/inventory.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Inventory

The local inventory management can help your shop in preventing back orders or managing order quantities.
The local inventory management can help your shop in preventing back orders or managing order quantities. For more details on the `InventoryPart` itself, see its [documentation page](inventory-part.md).

1. Enable the _Orchard Core Commerce - Inventory_ feature.
2. Edit the product in the content item editor.
Expand Down
21 changes: 21 additions & 0 deletions docs/features/numeric-product-attribute-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# NumericProductAttributeField

Adds a numeric input field so the buyer can communicate some kind of additional numeric detail about their purchase. Currently this attribute is not supported for price variant creation.

## Fields and properties
- **Hint** (`string`): Sets the description text to display for this attribute on the product's page.
- **DefaultValue** (`T`): Sets the default value.
- **Required** (`bool`): Determines whether a value is required.
- **Placeholder** (`string`): Sets the hint to display when the input is empty.
- **DecimalPlaces** (`string`): Sets the number of digits possible after the decimal point.
- **Minimum** (`string`): Determines the minimum value allowed.
- **Maximum** (`string`): Determines the maximum value allowed.

## Usage examples
New attribute fields can be added or existing fields can be edited in the relevant product content type's editor.
![image](../assets/images/numeric-product-attribute-field/content-type-editor-example.png)

![image](../assets/images/numeric-product-attribute-field/attribute-field-editor-example.png)

Attribute fields are displayed on the product's page.
![image](../assets/images/numeric-product-attribute-field/attribute-field-display-example.png)
16 changes: 16 additions & 0 deletions docs/features/price-part.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# PricePart

Provides a single price to a product using a custom [`PriceField`](https://github.com/OrchardCMS/OrchardCore.Commerce/blob/main/src/Modules/OrchardCore.Commerce.ContentFields/Models/PriceField.cs).

## Fields and properties
- **PriceField** (`PriceField`): Sets the base price of a product using a decimal number and a currency. The final price of a product may differ based on other features that implement `IShoppingCartEvents`, like promotions and tax settings.

## Usage examples
The product's price can be set in the product's editor.
![image](../assets/images/price-part/price-editor-example.png)

The product's price appears on the product's page, showing the specified decimal value and currency.
![image](../assets/images/price-part/price-display-example.png)

Price is also shown in the cart once the product has been added.
![image](../assets/images/price-part/price-cart-example.png)
27 changes: 27 additions & 0 deletions docs/features/price-variants-part.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# PriceVariantsPart

Provides multiple prices to a product based on predefined attributes. This currently only supports [`TextProductAttributeField`](text-product-attribute-field.md)s that are restricted to predefined values.

If [`InventoryPart`](inventory-part.md) is present, there will be multiple separate inventories for the variants.

In case of multiple attribute fields on a content type, a price field will be created for each possible combination. Individual inventories can be created using a recipe, see the sample [Price Variant Product](https://github.com/OrchardCMS/OrchardCore.Commerce/blob/main/src/Modules/OrchardCore.Commerce/Recipes/OrchardCore.Commerce.Samples.Product.recipe.json#L145).

Adding or editing product attributes can be done in the content type's editor (see below).

## Fields and properties
- **Variants** (`IDictionary<string, Amount>`): This property stores each variant's SKU along with their price.

## Usage examples
New attribute fields can be added or existing fields can be edited in the content type's editor.
![image](../assets/images/price-variants-part/content-type-editor-example.png)

![image](../assets/images/price-variants-part/attribute-field-editor-example.png)

The prices of variants can be set in the content item's editor.
![image](../assets/images/price-variants-part/price-variants-editor-example.png)

With _InventoryPart_ present, the inventory of each variant can be set in the content item's editor.
![image](../assets/images/price-variants-part/price-variants-inventory-example.png)

On the product's page, a variant can be selected and added to the cart. If inventories exist, they are also displayed here.
![image](../assets/images/price-variants-part/price-variants-page-example.png)
15 changes: 15 additions & 0 deletions docs/features/product-part.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# ProductPart

A content item becomes a product if it has a `ProductPart` and a price providing part (e.g. [`PricePart`](price-part.md), [`PriceVariantsPart`](price-variants-part.md), or [`TieredPricePartPart`](tiered-price-part.md)).

## Fields and properties
- **SKU** (`string`): The product's stock keeping unit, used for identification purposes. Must be globally unique and cannot contain the hyphen (`-`) character.
- **CanBeBought** (`IDictionary<string, bool>`): Determines whether the product can currently be bought based on current inventory settings. If there is no [`InventoryPart`](inventory-part.md) on the product, it is unused. This is not editable in the product's editor.
- **ProductImage** (`MediaField`): Allows selecting an image from the Media Library that will be displayed on the product's page.

## Usage examples
The _SKU_ and the _Product Image_ properties can be set in the product's editor.
![image](../assets/images/product-part/product-editor-example.png)

If _Product Image_ is set, it will appear on the product's page.
![image](../assets/images/product-part/product-image-example.png)
15 changes: 8 additions & 7 deletions docs/features/products-and-prices.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

To create a content type that represents a sellable product, you must give it a _Product_ part and either _Price_ or _PriceVariant_ part as well. You may have multiple different content types that represent different classes of product but they all must follow this rule.

> ℹ Use the _Orchard Core Commerce - Content - Product_ recipe to set up fully featured Product content type.
> ℹ Use the _Orchard Core Commerce - Content - Product_ recipe to set up a fully featured Product content type.
- ProductPart: contains the product's stock keeping unit (SKU) which has to be globally unique.
- PricePart: contains a single price for the product.
- PriceVariantsPart: contains multiple prices. This part uses any _Text Product Attribute Field_ the content type has, where the _Restrict to predefined values_ checkbox is checked in the field's settings. If you have multiple such fields, it creates a price field for each possible combination. For example if you have Size (S; M; L) and Color (Red; Blue) then you can give separate prices for Small Red, Medium Blue, etc.
- [ProductPart](product-part.md): contains the product's stock keeping unit (SKU) which has to be globally unique.
- [PricePart](price-part.md): contains a single price for the product.
- [PriceVariantsPart](price-variants-part.md): contains multiple prices. This part uses any _Text Product Attribute Field_ the content type has, where the _Restrict to predefined values_ checkbox is checked in the field's settings. If you have multiple such fields, it creates a price field for each possible combination. For example if you have Size (S; M; L) and Color (Red; Blue) then you can give separate prices for Small Red, Medium Blue, etc.
- [TieredPricePart](tiered-price-part.md): contains multiple prices based on selected quantity.

You can add fields to a product content type, the buyer can use these to enter further details for their order:

- Boolean Product Attribute Field
- Numeric Product Attribute Field
- Text Product Attribute Field
- [Boolean Product Attribute Field](boolean-product-attribute-field.md)
- [Numeric Product Attribute Field](numeric-product-attribute-field.md)
- [Text Product Attribute Field](text-product-attribute-field.md)

There are more optional details regarding prices, see the [Taxation](taxation.md) and [Promotions](promotions.md) pages.
23 changes: 23 additions & 0 deletions docs/features/text-product-attribute-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# TextProductAttributeField

Allows adding further details to a product. By default it is displayed as a text input, but this is modified by some of the properties below. When used in combination with a [`PriceVariantsPart`](price-variants-part.md) and restricted to predefined values, it creates variants for the product.

When not restricted to predefined values, it can be used to provide a text or note to the merchant. For example, in a clothing store it may be used to supply custom text to be printed on the item.

## Fields and properties
- **Hint** (`string`): Sets the description text to display for this attribute on the product's page.
- **Required** (`bool`): Determines whether a value is required.
- **DefaultValue** (`T`): Sets the default value.
- **Placeholder** (`string`): Sets the hint to display when the input is empty.
- **PredefinedValues** (`IEnumerable<object>`): Holds the set of allowed values. These are also used to create variants with a `PriceVariantsPart`.
- **RestrictToPredefinedValues** (`bool`): Determines whether values should be restricted to the set of predefined values. When true, the field is displayed as a list of radio buttons. Note that this must be set to true for `PriceVariantsPart` to pick up the values.
- **MultipleValues** (`bool`): Determines whether multiple values can be selected. This only makes sense when _RestrictToPredefinedValues_ is true. If enabled, the predefined values are displayed as a list of checkboxes.

## Usage examples
New attribute fields can be added or existing fields can be edited in the relevant product content type's editor.
![image](../assets/images/text-product-attribute-field/content-type-editor-example.png)

![image](../assets/images/text-product-attribute-field/attribute-field-editor-example.png)

The predefined values of the attribute are displayed on the product's page.
![image](../assets/images/text-product-attribute-field/attribute-field-display-example.png)
16 changes: 16 additions & 0 deletions docs/features/tiered-price-part.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# TieredPricePart

Allows setting several prices for a product based on the quantity purchased at once.

## Fields and properties
- **DefaultPrice** (`Amount`): Sets the base price of the product, which will be applicable until the selected quantity reaches one of the specified tiers.
- **PriceTiers** (`IList<PriceTier>`): A list of [`PriceTiers`](https://github.com/OrchardCMS/OrchardCore.Commerce/blob/main/src/Modules/OrchardCore.Commerce/Models/PriceTier.cs) that determine which price to use at which quantity. The currency of these prices follows the currency set for the _DefaultPrice_ property. If there are no tiers specified, the _DefaultPrice_'s value is used in all cases.

## Usage examples
The price tiers can be set in the product's editor.
![image](../assets/images/tiered-price-part/tiered-price-part-editor-example.png)

The product's tiered prices appear on the product's page and modify the line price in the cart if applicable.
![image](../assets/images/tiered-price-part/tiered-price-display-example.png)

![image](../assets/images/tiered-price-part/tiered-price-cart-example.png)
11 changes: 11 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ nav:
- Taxation: features/taxation.md
- User Features: features/user-features.md
- Workflows: features/workflows.md
- Parts and Fields:
- Parts:
- ProductPart: features/product-part.md
- PricePart: features/price-part.md
- PriceVariantsPart: features/price-variants-part.md
- TieredPricePart: features/tiered-price-part.md
- InventoryPart: features/inventory-part.md
- Fields:
- TextProductAttributeField: features/text-product-attribute-field.md
- BooleanProductAttributeField: features/boolean-product-attribute-field.md
- NumericProductAttributeField: features/numeric-product-attribute-field.md
- Resources:
- Libraries: resources/libraries/README.md
- Releases: https://github.com/OrchardCMS/OrchardCore.Commerce/releases
11 changes: 11 additions & 0 deletions src/Modules/OrchardCore.Commerce/Models/ProductPart.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using OrchardCore.Commerce.Inventory.Models;
using OrchardCore.ContentManagement;
using OrchardCore.Media.Fields;
using System.Collections.Generic;
Expand All @@ -14,6 +15,16 @@ public class ProductPart : ContentPart
/// Gets or sets the product's SKU, which can also be used as an alias for the item.
/// </summary>
public string Sku { get; set; }

/// <summary>
/// Gets whether the product can currently be bought based on current inventory settings. If there is no
/// <see cref="InventoryPart">InventoryPart</see> on the product, it is unused. This is not editable in the
/// product's editor.
/// </summary>
public IDictionary<string, bool> CanBeBought { get; } = new Dictionary<string, bool>();

/// <summary>
/// Gets or sets the image associated with this product, which will be displayed on the product's page.
/// </summary>
public MediaField ProductImage { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "OrchardCore.Commerce.Content.Product",
"displayName": "Orchard Core Commerce - Content - Product",
"description": "Creates a Product content type with a Product Part and a Price Part.",
"description": "Creates various product content types by combining related content parts such as ProductPart, PricePart, InventoryPart, etc.",
"author": "The Orchard Team",
"website": "https://orchardproject.net",
"version": "2.0",
Expand Down

0 comments on commit b63eae4

Please sign in to comment.