- Menu
- Sitemap

https://support.intershop.com/kb/2535N6

This article is meant to give a rough overview of promotion actions. It is intended to discuss

- Wwhat actions are,
- What different kinds of actions have already been implemented,
- How the given actions are configured properly, and
- What effect different action configurations have on basket calculation.

For the implementation of a new action, please refer to the references section.

Now, from a customer's perspective the action represents the act of giving a discount or rebate, e.g., a gift, if the given basket meets the corresponding rule's condition. Without action a promotion would never have an effect on basket calculation. However, from a programmer's and Commerce Management application user's point of view an action not only comprises its execution but also its configuration. This configuration sometimes turns out to be quite complex.

As outlined in the Cookbook - Promotions (valid to 7.7), in order to introduce a new action to the system, a descriptor together with related configuration templates and an executor have to be implemented. Roughly speaking, the descriptor contains all properties, i.e., parameters that are used to describe, i.e., configure the action, whereas the executor mainly contains an `execute()`

method which is used to apply the action to a given basket whenever the conditions to do so are fulfilled. The action configuration is done in the Commerce Management application whereas action execution is triggered by basket calculation in the storefront.

Note

The promotion framework allows to create more complex promotions coming with a set of rules like, e.g., if step 1 is fullfilled, discount 1 will be granted and if step 2 is fullfilled, discount 2 will be granted, and so on.

The calculation algorithm to apply a promotion evaluates the rules top down and always takes the first rule that matches. Left over rules will not be evaluated.

Note

It is not possible to configure one promotion with multiple actions like, e.g., providing a item percentage off discount and a free shipping discount by entering one promotion code.

To configure such multiple actions multiple promotions need to be combined with each other.

Different actions or action types come along with different action descriptors. Each and every promotion action descriptor inherits from class `PromotionActionDescriptor`

. In this class the four configuration parameters that are common to all actions are defined and added to the list of configuration parameters of each action:

`HasMaxPrice`

: type`Boolean`

`MaxPriceValue`

: type`Money`

depending on`HasMaxPrice`

, constraint: value at least 0.01`HasMaxApplications`

: type`Boolean`

`MaxApplications`

: type`Integer`

depending on`HasMaxApplications`

, constraint: value at least 1

**MaxPrice** denotes an upper bound for the amount of money to be granted by execution of the action for a given basket/order. So, parameter `MaxPriceValue`

is used to specify the upper bound, and parameter `HasMaxPrice`

serves for activating this bound.

Example: Assume that `HasMaxPrice`

is `true`

and `MaxPriceValue`

is $20. Furthermore assume that the action is something like "50 per cent off on order total" and the given order total is $1000. Then execution of the action for this order will yield a discount of no more than $20 instead of $500.

**MaxApplications** denotes an upper bound for the number of times a discount or rebate is allowed to be applied to an order or to an item, depending on the action's application level being the whole order or single items.

Example: Assume that `HasMaxApplications`

is `true`

and `MaxApplications`

is 5.

- Let the discount be "$10 value off on order total" and the given order total be $100. Then you get $50 discount.
- Let the discount be "Item percentage off 10 per cent - applied to 1 cart item". Furthermore, let there be 7 items in the cart each of which costs exactly $100. Then the given discount is $50, too.

**Not in all cases the discount calculation with respect to MaxApplications is that simple. However, in order to understand the calculation in other cases, you just have to keep three rules in mind.**

**A cart item is discounted at most once.****"Percentage off on order total" is applied at most once.****The discount amount for an item/order is bounded by the item/order money value.**

In the Commerce Management application the four parameters are displayed as follows.

An explanation of which parameter can be found where is here:

**Item value off**

The decision how often an item value off discount is applied depends on multiple settings. If the discount is configured to be applied to all items, the setting of `MaxApplications`

is invalidated. In contrast to that, if the action is configured to be applied to 1 cart item, then exactly the amount of items is discounted which is defined with `MaxApplications`

**.**

**Item percentage off**

The same rules apply, when the discount is percentage off instead of value off.

**Order value off**

An order value off discount will be applied depending on the rebate condition and the setting of `MaxApplications`

. Let's say, we have a minimum order value condition of 50$. The discount is Order Value Off $ 5.00, the maximum number of applications per order is 4.Then the discount depends on your order value, from 50$ to 99,99$ it will be applied one time, from 100$ to 149,99$ two times and so on until the max application value is reached (in this case 4 times maximum). If there is no value for `MaxApplications`

` `

is configured the rule applies unlimited times.

**Order percentage off**

For an order percentage off discount always the above describe rule "Percentage off on order total is applied at most once." applies.

A discount that is not necessarily to be applied to the cart as a whole but rather to a specific subset of cart items, where the subset specification is based on the condition, is called a **conditional discount**. Conditional discounts are represented by the class `ConditionalDiscount`

which directly inherits from `PromotionActionDescriptor`

. The configuration parameters added by `ConditionalDiscount`

are the following:

`ConditionalItemsSelection`

: type`String`

`ConditionalItemsMinPrice`

: type`Double`

, constraint: value at least 0.00

`ConditionalItemsSelection`

is the crucial parameter used to specify the subset of cart items to which the discount is meant to apply. It can take four values with corresponding set interpretation:

`InCart`

: (the discount applies to) all cart items.`Conditional`

: all cart items which meet the condition of the rule (see Backgroundabove).`NextConditional`

: all cart items which meet the rule's condition but do not "count towards the minimum number of included items."`Selected`

: all cart items that belong to a group of products that you can define explicitly.

Note

*The minimum number of included items* refers to a special rule condition: apply the discount if there is a minimum number of items in the cart, e.g., three items. The three items in the cart that the cart calculation algorithm takes as a proof for the condition being fulfilled *count towards the minimum number of items*.

`ConditionalItemsMinPrice`

is used to define a price bound such that a cart item is not discounted if its price is below the bound. For example, if the bound is defined to be $20, then only items with a price of at least $20 are discounted.

In the Commerce Management application the two parameters look like this:

Here is an explanation of which parameter is found where:

A conditional discount that allows for a restriction with respect to the number of cart items it can be applied to is called **item discount**. The descriptor class of this type of action, class `ItemDiscount`

, directly inherits from class `ConditionalDiscount`

and adds three configuration parameters:

`ItemsAffected`

: type`String`

`AffectedItemsNumber`

: type`Integer`

, constraint: value at least 1`PriceAffected`

: type`String`

Configuration parameter `ItemsAffected`

is used to determine whether the discount is applied to all cart items or to a limited number of cart items. The values it can take and their respective interpretations are the following:

`All`

: no restriction with respect to the number of cart items to be discounted.`Amount`

: the number of cart items to be discounted is restricted by the value of configuration parameter`AffectedItemsNumber`

.

Parameter `PriceAffected`

helps to determine the order in which the cart items are discounted. Two different orders are supported at the time being:

`LowestPrice`

: ascending with respect to item price.`HighestPrice`

: descending with respect to item price.

Value `LowestPrice`

is more advantageous for the seller as it can help to reduce the cost caused by promotion actions. In contrast to this, the value `HighestPrice`

is more beneficial for the consumer because the discount granted is likely to be higher. Of course, the consumer's benefit may in the long term be profitable for the seller, too.

Let's have a look at the way the three parameters are displayed in the Commerce Management application.

It follows a rough explanation of what can be seen.

The `ID`

**ItemPercentageOff** stands for an item discount which grants a certain percentage discount on item price in the cart. As an item discount, its corresponding descriptor class `ItemPercentageOffDiscount`

directly inherits from class `ItemDiscount`

and adds just one self-evident configuration parameter to the various parameters of the item discount:

`PercentageValue`

: type`Double`

, constraint: value a valid percentage, i.e. between 0.01 and 100

Among all descriptor classes mentioned so far, the class `ItemPercentageOffDiscount`

is the first that fully describes a certain action and not only adds some configuration parameters that are common to a type of action. Here, no further specialization is done.

Have a look at the complete *item percentage off discount* configuration webform. All parts of it should be clear now.

For the sake of completeness we annotate the figure:

The `ID`

**ItemTargetPriceDiscount** stands for an item discount that sets the price of cart items to a fixed lower value - if possible. Its descriptor class, `ItemTargetPriceDiscount`

, adds the following configuration parameter to those of the item discount:

`TargetPrice`

: type`Money`

Cart items with lower price than the target price, of course, do not get a higher price if the action is applied. The price of those items remains unchanged. Nevertheless, they are treated as if they were discounted. This has an exceptional effect in the following situation. Assuming that the action is defined to be "Item target price is $100 to be applied to 2 cart items, the maximum number of applications per order is 1", and `PriceAffected`

is `LowestPrice`

. If there are three items in the cart with price $70, $50, and $150, respectively, then action application has no visible effect on the cart because the two items discounted have a price lower than the target price. In order to prevent lower price items from being target price discounted you have to set `ConditionalItemsMinPrice`

to the same value as `TargetPrice`

.

So, item target price has to be applied with care. Another argument for applying this action with care is the absence of an upper bound for the price of a discounted item. In principle a cart item that costs $1.000.000 can be set to a target price of $1. This can, of course, be prevented by setting `ConditionalItemsSelection`

to `Selected`

and solely selecting suitable products.

The item target price discount configuration webform is not much different from the one of the item percentage off discount shown above. The only difference is that a target value can be set instead of a percentage value.

The `ID`

**ItemValueOffDiscount** stands for an item discount which reduces the item costs by a fixed value. Its descriptor class, `ItemValueOffDiscount`

, adds the following configuration parameter to the list of item discount parameters:

`ValueOff`

: type`Money`

Note

If a cart item costs less than the price reduction amount then its price is just reduced to zero.

The webform of the item value off discount differs from the one of the item percentage off discount simply in that parameter `ValueOff`

can be set instead of parameter `PercentageValue`

.

Of all actions implemented so far shipping discounts are the most complex ones. On the one hand this is due to the fact that each of them can be configured to take effect on one of three levels: item, order, or bucket. On the other hand it is because a variety of different shipping methods and shipping regions can be configured in such a way that the discount only applies if the choice of shipping method and region in the cart corresponds to those configured for the action.

Shipping discounts are conditional discounts, and as each of them potentially can take effect on one of the three levels item, order, and bucket, the descriptor class of shipping discounts, `ShippingDiscount`

, directly inherits from class `ConditionalDiscount`

.

At the moment the class `ShippingDiscount`

adds the following configuration parameters:

`TargetAffected`

: type`String`

`ItemRestriction`

: type`Boolean`

; depending on`TargetAffected`

`AffectedItemsNumber`

: type`Integer`

; depending on`ItemRestriction`

, constraint: value at least 1`MethodsAffected`

: type`String`

`ShippingMethods`

: type`Collection`

; depending on`MethodsAffected`

`RegionsAffected`

: type`String`

`ShippingRegions`

: type`Collection`

; depending on`RegionsAffected`

Parameter `TargetAffected`

is needed to determine the discount's level of effect, and hence, can take one of three values:

`Order`

: the order as a whole is discounted.`Bucket`

: the discount is applied bucket per bucket.`Items`

: discount application on item level, i.e., item per item.

Solely in the case where the discount's level of effect is `Items`

, parameters `ItemRestriction`

and `AffectedItemsNumber`

come into play. Then the role of these parameters is exactly the same as of parameters `ItemsAffected`

and `AffectedItemsNumber`

defined for the item discount, respectively, with the only difference that `ItemRestriction`

takes a `Boolean`

value whereas `ItemsAffected`

takes one of the two strings *All* and *Amount*.

The only configuration parameter that an item discount has and a shipping discount on item level does not have is `PriceAffected`

. To introduce this parameter for shipping discounts, too, may be a reasonable new feature. Of course, `PriceAffected`

for shipping discounts would have to relate to the shipping costs rather than to the item costs.

Configuration parameter `MethodsAffected`

serves for determining whether to apply the discount for all shipping methods or for a selection of them. Similarly, parameter `RegionsAffected`

serves for determining whether to apply the discount for all shipping regions or just for a selection of them. Therefore the two values that these parameters can take are

`All`

and`Selected`

with the obvious meanings. The related parameters `ShippingMethods`

and `ShippingRegions`

are, of course, effective if and only if value `Selected`

is configured. In this case `ShippingMethods`

stores a `Collection`

of selected shipping methods, and `ShippingRegions`

keeps track of the configured selection of shipping regions.

The following three shipping discount specializations are completely analogous to the corresponding specializations of the item discount. The difference is that the discount is granted rather for shipping than for item costs, and the level of effect can be either item (shipping), bucket (shipping), or order (shipping).

See above.

The following two figures show the shipping percentage off discount configuration webform without and with annotations, respectively.

The webforms of the remaining shipping discounts are completely analogous.

See above.

See above.

Non-conditional discounts apply to the order/cart as a whole, and hence, their descriptors inherit directly from `PromotionActionDescriptor`

. Other than the above shipping discounts the non-conditional discounts implemented so far tend to be quite simple and their webforms are self-explanatory.

The following two specializations are achieved in analogous manner to the corresponding specializations of the item discount, and hence, need not be described in detail. In order to understand the effect of these discounts, you just have to keep in mind that they are applied to the cart as a whole.

See above.

See above.

A **free gift discount** grants a configured number of selected products added to cart as gift, where the number of gifts added can be regulated by means of the above-mentioned configuration parameters of class `PromotionActionDescriptor`

.

We distinguish between two kinds of free gifts. An **automatic gift** visibly appears in the cart whereas the **hidden gift** is invisible to a consumer who puts products into a cart.

The descriptor classes of both gift types adds a parameter

`LimitToMaxItemCount`

: type`Integer`

, constraint: value at least 1

which is used to determine the number of times the cart calculation algorithm attempts to add each of the selected gift products to a single cart.

The information provided in the Knowledge Base may not be applicable to all systems and situations. Intershop Communications will not be liable to any party for any direct or indirect damages resulting from the use of the Customer Support section of the Intershop Corporate Web site, including, without limitation, any lost profits, business interruption, loss of programs or other data on your information handling system.