Concept - Basket Handling

1 Introduction

This document describes the new Basket Processing API initially introduced with Intershop version 7.4 including the latest changes done with version 7.8.

The previous basket handling implementation on processing layer(s) can be considered as being historically evolved from early Enfinity versions until Intershop version 7.3 and could not satisfy present and future requirements any longer because of the following lacks and issues:

  • Implementation of basic basket processing functionality was tightly interwoven with Web technology related artifacts like Sessions and Cookies.
  • Processing functionality was not clearly separated in specific layers.
    Logic was scattered across several manager classes, pipelines and pipelets.
  • Process related pipelines contained view logic, view related pipelines implemented basic processing logic in some cases.
  • Process related logic provided no details about the success or failure(s) of complex basket manipulation operations to overlaying layers.
  • Overloading of complex pipelines was the only mechanism for realizing extensibility and customization in most cases.
  • Missing separation of aspects introduced various dependencies to non-basket related code artifacts, like AB testing or change event tracking.

The advent of the new Application-centric design in Intershop 7 and the fact that basic Intershop 7 frameworks have not to support Web UI based applications exclusively, but also mobile clients and REST clients results in the following main requirements:

  • Form stringent process pipeline API that can be used by different types of applications, e.g., Web UI, mobile, REST.
  • Ensure a strict separation in process and view pipelines.
  • Use Business Object types or classes according to JavaBeans specification for pipeline start and end node parameters only.
  • Mark all start and end nodes as strict to provide a more deterministic behavior during the execution of a pipeline as well as for providing results of pipeline execution to the callee.
  • Separate functionality in specific layers, that are responsible for certain functional parts.
  • Introduce extension mechanisms for customer projects on all layers.
  • Isolate non-domain related aspects from common processing and hook them by extension mechanisms.

2 Principle Objectives

2.1 Pipeline Layer

  • Specify all pipeline start and end nodes as to be strict.
  • Specify all start node parameters that are required in the pipeline as to be mandatory.
  • Keep any technology specific artifacts (e.g., HTML/HTTP) out of the processing pipelines (e.g., Session, Cookie, Request).
  • Keep process related pipelines as small and as simple as possible:
    • Avoid dozens of identical checks, like the one if a product that should be added to the basket really has the status 'Online'. Implement the check only once at a specific location.
    • Avoid time-consuming loop nodes that loop over a set of given items, like all line items of a basket.
    • Move complex processing logic from pipeline to Java layer.
    • Create only pipelines that are really required and not the ones that might be required in the future.
  • Use Business Object types for pipeline start and end node parameters only. Use simple JavaBean type implementations to provide all necessary information about the call parameters and results of basket manipulation actions (add-to-basket, remove-from-basket, etc.) to overlaying layers.
  • Remove domain-centric (Channel/Organization/Repository Domain) approach from pipelines. The com.intershop.beehive.app.capi.AppContext instance is available in all pipelines now and contains all necessary information, e.g., for retrieval of configuration values.
  • Remove fixed wiring of cross-cutting concerns, like AB-testing or change event reporting from processing pipelines. Insert pipeline extension points before and after every basket manipulation action instead of enabling involvement of cross-cutting functionality. This design reduces the need for pipeline inheritance and leads to a clearly structured pipeline design.

2.2 Java Layer

  • Do not use the outdated Singleton Manager implementations any longer, because they will clash with the Application-oriented design.
  • Remove tight coupling with other business functionality, like user handling.
  • Introduce Java extension points for complex manipulation actions to enable easy adjustment and enhancement of functionality.

3 Basket Life-Cycle

During its lifetime a basket is in one of the following states:
  • BASKET_OPEN - Basket is open for every kind of manipulation, like add products, warranties and coupons, remove line items.
    Furthermore a basket being in this state is ready for checkout.
  • BASKET_ORDERED - Checkout of basket has been successfully finished.
  • BASKET_EXPIRED - A basket in the state BASKET_OPEN expires, because:
  • BASKET_INVALID - Basket is ready for removal.
  • BASKET_UNSPECIFIED - This state is currently not used but has to be kept for compatibility reasons.

After the basket creation (1) the basket is in the state BASKET_OPEN. The creation is triggered when a customer adds a product to the basket for the first time. When customer successfully finishes his/her checkout (4), the basket gets the state BASKET_ORDERED. The transition (2) from BASKET_OPEN to BASKET_EXPIRED depends on the basket type. A session-based basket will get this state when the session times out or user logs out. A time-based basket, which reaches the configured inactivity time period (domain preference "BasketLifetime") is moved to the basket history by the background job Move Outdated Baskets To History. Note that the actual expiration time of a basket depends on a combination of both, the configured inactivity time period as well as the run-time of the job: For instance, if the inactivity time period is set to two hours, but the job runs only once at midnight, then an inactive basket may still become active again, if the configured inactivity time period is increased in the back-office after the two hours have passed, but before the end of the day.

After basket reaches the state BASKET_EXPIRED, it is treated in the same way independent from its type.

Basket Status

Either the basket is marked as removable by changing its state to BASKET_INVALID (5) after a configurable period of time (domain preference "BasketInHistoryLifetime") or it is 'reactivated' for some reasons (3). It is in the responsibility of the functionality that 'reactivates' the basket from basket history to remove certain parts of the basket, e.g. payment methods, addresses, item prices, etc.
The transition to BASKET_INVALID is made by the job  Invalidate History Baskets. It updates the field status only. The job Remove Invalid Baskets finally purges (7) all invalid baskets from the database.


You will find a description and additional information about the jobs in Reference - Intershop 7.8 Jobs.

4 Basket Creation

4.1 Web Application Layer

Baskets are created by the pipeline ViewCart-GetCurrentCartBO in case they cannot be retrieved from a session or cookie by calling lower level processing pipelines. For unregistered users and time-based baskets, a basket cookie is created so the basket will be restored in case the user leaves the shop and the session is terminated.

4.2 Business Object Layer

Business object layer specific logic is implemented in the bc_orderprocess pipeline, the bc_basket (BO interfaces), bc_basket_orm and sld_ch_b2c_base cartridges (BO implementations).

4.2.1 Pipeline

ProcessBasket-CreateBasket

4.2.2 Pipeline Extension Points

The pipeline defines following extension points:

  • CreateBasket
  • CreatedBasket

Extension pipelines assigned to extension point CreateBasket are called before the basket will be created. Pipelines assigned to this extension point are not part of the basket creation transaction.

Extension pipelines assigned to extension point CreatedBasket are called after the basket has been created. Pipelines assigned to this extension point are part of the basket creation transaction.

4.2.3 Java (BO)

Basic basket creation functionality is done in Java by implementations of com.intershop.component.basket.capi.BasketBORepository which provide the following two methods:

BasketBO createBasketBO();
BasketBO createBasketBO(UserBO user);

The only difference between the two methods above is that the second one assigns the basket to the given user. There may be application specific implementations of com.intershop.component.basket.capi.BasketBORepository that implement other or additional behavior.

5 Basket Retrieval

5.1 Web Application Layer

Existing baskets are retrieved by the pipeline ViewCart-GetExistingCartBO. The lookup mechanism first checks the session dictionary for an active basket. If a basket is found and not expired, this one will be used in the further checkout process. Otherwise the user's active baskets will be looked up from the database. If there is an active (not expired) basket, this one will be returned. For anonymous users and time-based baskets a basket cookie is created. If there is neither a basket for the current user in the session dictionary nor in the database, this basket cookie will be used to retrieve the basket. When a basket is retrieved this way, the basket will be anonymized and the owner will be set to the current user.

5.2 Business Object Layer

Business object layer specific logic is implemented in the bc_orderprocess (pipeline), the bc_basket (BO interfaces), bc_basket_orm and sld_ch_b2c_base cartridges (BO implementations).

5.2.1 Pipeline

ProcessBasket-GetBasketByID
ProcessBasket-GetBasketsByUser

In contrast to the previous ProcessCart pipelines, no new basket is created if no existing one has been found.

5.2.2 Java (BO)

Basket business object instances can be retrieved by implementations of com.intershop.component.basket.capi.BasketBORepository. A repository defines the following methods:

BasketBO getBasketBO(String id);

BasketBO getActiveBasketBO(String id);

Collection<? extends BasketBO> getActiveBasketBOs();
Collection<? extends BasketBO> getActiveBasketBOs(UserBO user);

Method getActiveBasketBO(String id) only returns the basket with the specified ID if it is in the state BASKET_OPEN, whereas method getBasketBO(final String id) returns a basket that is in state BASKET_EXPIRED too. None of the methods above returns baskets that are in the states: BASKET_ORDERED, BASKET_INVALID, BASKET_UNSPECIFIED.

6 Add-to-Basket Operation

Adding a product to the basket may be a simple operation at the first glance. There are a lot of special cases beside the happy path that have to be considered.

6.1 Class Diagram

concept_basket_handling_add_to_basket_class_diagram

6.2 Handler Chain

concept_basket_handling_add_to_basket_handler_chain

6.2.1 Pre-Add-To-Basket-Handlers

Handler chain executes listed pre-add-to-basket handlers in the following order:

6.2.1.1 AddToBasketProductVariationHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductVariationHandler

If the product to be added specified in the add-to-basket context is a Variation Master then handler tries to retrieve the default variation product. If default variation product exists then this one is set at the add-to-basket context instead, otherwise handler indicates an failure if no default variation is available.

6.2.1.2 AddToBasketProductStatusHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductStatusHandler

Configuration: BasketAcceptedItemStatus -> ( OnlineOnly | OnlineOrOffline)

Handler indicates an failure if the product to be added has the status Offline, but according to configuration only products with status Online (OnlineOnly) are allowed to be added to the basket.

6.2.1.3 AddToBasketProductLifeCycleHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductLifeCycleHandler

Handler checks whether the product reached the end-of-life or last-order-date. In case of expiry one of the dates an error is indicated and the product not added to the basket.

6.2.1.4 AddToBasketProductIntegrityHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductIntegrityHandler

The handler verifies that the product fulfills following criteria:

  • is available
  • is not only offered as part of a retail set  
  • can be added to basket solely or only together * with the product where it depends on.

For each of these constraint violated a failure is pointed out and the product not added.

6.2.1.5 AddToBasketProductAccessibilityHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductAccessibilityHandler

The handler indicates a failure if the product to be added to the basket is not accessible. A product may be inaccessible, e.g., because a catalog view is defined and the product is excluded from this view for a given customer.

6.2.1.6 AddToBasketLookupExistingLineItemHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.LookupExistingLineItemHandler

Handler looks for all existing line items in the basket that represents the same product as the one to be added. Handler sets the found line items at the add-to-basket context if the start node parameter ForceSeparateLineItem at the ProcessBasket-AddProduct pipeline has not been set to value equals to true to force creation of a new line item explicitly.

6.2.1.7 AddToBasketBehaviorHandler

Configuration: BasketAddProductBehaviour -> ( MergeQuantities | DisallowRepeats | AllowRepeats)

Handler determines the add-to-basket behavior based on following values:

  • The configuration value, specified for BasketAddProductBehaviour.
  • The ForceSeparateLineItem setting at the add-to-basket context.
  • The MergeGroup setting at the add-to-basket context.

6.2.1.8 AddToBasketLookupMergeCandidateHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.LookupMergeCandidateHandler

Handler iterates over all line items found by the LookupExistingLineItemHandler and stores the line item which meets of the following conditions:

  • Start node parameter  MergeGroup at the ProcessBasket-AddProduct pipeline has been set to a value that is equal to the one of the existing line item. (An example with different merge group values would be the following case: Four products should be added to the basket, whereas two ones are paid with the default currency and the other two ones are paid with bonus points.)
  • Found line item does not represent a free or hidden gift product automatically added to the basket by calculation
  • Found line item has no gifting options like gift wrap or gift message
  • Found line item has also no warranty assigned
  • The product in the line item is not a digital gift card.

6.2.1.9 AddToBasketMaxItemSizeHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.MaxItemSizeHandler

Configuration: BasketMaxItemSize -> (n)

Handler indicates a failure if configured value for maximum number of items will be exceeded after the product is added to the basket.

6.2.1.10 AddToBasketMaxItemQuantityHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.MaxItemQuantityHandler

Configuration: BasketMaxItemQuantity -> (n)

Handler indicates a failure if configured value for maximum line item quantity will be exceeded after the product is added to the basket.

6.2.2 Post-Add-To-Basket-Handlers

Handler chain executes listed post-add-to-basket handlers in the following order:

6.2.2.1 AddToBasketLineItemPositionHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.LineItemPositionHandler

Handler calculates the position number in case a new line item has been created.

6.2.2.2 AddToBasketAdjustQuantityHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.AdjustQuantityHandler

Configuration: BasketMaxItemQuantity -> (n)

Handler adjusts quantity of newly created line item or of existing item with added requested quantity. Quantity is adjusted based on following configuration values and settings:

  • Minimum order quantity that may be specified at the product to be added, or the default value 1 otherwise.
  • Maximum order quantity that may be specified at the product to be added, or the configuration value specified for BasketMaxItemQuantity otherwise.
  • Step quantity that may be specified at the product to be added, or the default value 1 otherwise.

6.2.2.3 AddToBasketProductBundleHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductBundleHandler

Handler creates bundle member entries, if product to be added is a product bundle.

6.2.2.4 AddToBasketGiftCardHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.GiftCardHandler

Handler adds some Online Gift Card/Certificate (OGC)-related information to the line item, if product to be added represents an OGC.

6.2.2.5 AddToBasketWishlistHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.WishlistHandler

Handler sets the wishlist data to the created/merged product line item.

6.2.2.6 AddToBasketOrderRequiredAttributesHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.OrderRequiredAttributesHandler

Handler adds all order required product attributes to the newly created line item. It uses the ProductBOOrderRequiredAttributesExtension.getOrderRequiredAttributes().
This extension is aware of following types of order required attributes:

  1. Order required attributes directly specified at the product.
  2. Attributes that belong to the product attribute group Order Required Attributes.
  3. Classification catalog service type excludeFromShipping

Attributes are now of the type BusinessObjectAttribute. Those attributes will usually be prefixed with BusinessObjectAttributes#.

Because the checkout process does not use BO's everywhere we use an own factory ExtensibleObjectBasketProductLineItemAttributesExtensionFactory and set the prefix to an empty string.

6.2.2.7 AddToBasketDefaultShippingMethodHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.DefaultShippingMethodHandler

The Handler sets the default shipping method to newly created line items.

6.2.2.8 AddToBasketDefaultShippingMethodHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.InitialShipToAddressHandler

The handler sets the initial ship-to address for a product line item if multiple shipping is allowed. The address is determined by the following lookup order:

  • Sole ship-to address of basket (if all line items have the same ship-to address)
  • Preferred ship-to address of the basket owner

If none of these match, the ship-to address will not be set initially.

If multiple shipping is disabled, the ship-to address of the basket will be set to the preferred ship-to address of the basket owner, if this exists and the ship-to address has not been set yet.

7 Remove-from-Basket Operation

7.1 Class Diagram

concept_basket_handling_remove_from_basket_class_diagram

7.2 Handler Chain

concept_basket_handling_remove_from_basket_handler_chain

8 Update-Quantity Operation

8.1 Class Diagram

concept_basket_handling_update_quantity_class_diagram

8.2 Handler Chain

concept_basket_handling_update_quantity_handler_chain

9 Update-Variation Operation

9.1 Class Diagram

concept_basket_handling_update_variation_class_diagram

9.2 Handler Chain

concept_basket_handling_update_variation_handler_chain

9.2.1 Pre-Update-Variation-Handlers

Handler chain executes listed pre-aupdate-variation handlers in the following order:

9.2.1.1 UpdateVariationProductVariationHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductVariationHandler

If the product to be updated specified in the update-variation context is a Variation Master then handler tries to retrieve the default variation product. If default variation product exists then this one is set at the update-variation context instead, otherwise handler indicates an failure if no default variation is available.

9.2.1.2 UpdateVariationProductIntegrityHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductIntegrityHandler  

The handler verifies that the product fulfills following criteria:

  • Is available
  • Is not only offered as part of a retail set  
  • Can be added to basket solely or only together * with the product where it depends on.

For each of these constraint violated a failure is pointed out and the variation product is not updated.

9.2.1.3 UpdateVariationProductStatusHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductStatusHandler

Configuration: BasketAcceptedItemStatus-> ( OnlineOnly | OnlineOrOffline)

Handler indicates an failure if the variation product to be updated has the status Offline, but according to configuration only products with status Online (OnlineOnly) are allowed to be used in the basket.

9.2.1.4 UpdateVariationProductAccessibilityHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductAccessibilityHandler

The handler indicates a failure if the product to be set at the basket line item is not accessible. A product may be inaccessible, e.g., because a catalog view is defined and the product is excluded from this view for a given customer.

9.2.1.5 UpdateVariationLookupExistingLineItemHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.LookupExistingLineItemHandler

Handler looks for all existing line items in the basket that represents the same product as the one to be updated. Handler sets the found line items at the update-variation context if the start node parameter ForceSeparateLineItem at the ProcessBasket-UpdateVariation pipeline has not been set to value equals to true to force creation of a new line item explicitly.

9.2.1.6 UpdateVariationBehaviorHandler

Configuration: BasketAddProductBehaviour -> ( MergeQuantities | DisallowRepeats | AllowRepeats)

Handler determines the add-to-basket behavior to be considered during the update-variation process based on following values:

  • The configuration value, specified for BasketAddProductBehaviour.
  • The ForceSeparateLineItem setting at the add-to-basket context.
  • The MergeGroup setting at the add-to-basket context.

9.2.1.7 UpdateVariationLookupMergeCandidateHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.LookupMergeCandidateHandler

The handler checks at first whether the line item to be updated comply with the conditions:

  • Does not represent a free or hidden gift product automatically added to the basket by calculation
  • Has no gifting options like gift wrap or gift message
  • Has also no warranty assigned

If the constraints above are satisfied the handler iterates over all line items found by the LookupExistingLineItemHandler and stores the line item which meets of the following conditions:

  • The value  MergeGroup at the product line item to be updated is set to a value that is equal to the one of the existing line item.
    An example with different merge group values would be the following case: Four products should be added to the basket, whereas two ones are paid with the default currency and the other two ones are paid with bonus points.)
  • Found line item does not represent a free or hidden gift product automatically added to the basket by calculation
  • Found line item has no gifting options like gift wrap or gift message
  • Found line item has also no warranty assigned
  • Found line item has either no fixed price or it matches to fixed single base price given in the update-variation context
  • The product in the line item is not a digital gift card.

9.2.1.8 PreUpdateVariationProductBundleHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.PreUpdateVariationProductBundleHandler

In case the product to be replaced was a product bundle, the handler iterate over all bundle member entries and collects the products of this bundle. So they can be replaced in the post-update-variation processing by the UpdateVariationProductBundleHandler.

9.2.2 Post-Update-Variation-Handlers

Handler chain executes listed post-update-variation handlers in the following order:

9.2.2.1 UpdateVariationAdjustQuantityHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.AdjustQuantityHandler

Configuration: BasketMaxItemQuantity -> (n)

Handler adjusts quantity of newly created line item or of existing item with added requested quantity. Quantity is adjusted based on following configuration values and settings:

  • Minimum order quantity that may be specified at the product to be added, or the default value 1 otherwise.
  • Maximum order quantity that may be specified at the product to be added, or the configuration value specified for BasketMaxItemQuantity otherwise.
  • Step quantity that may be specified at the product to be added, or the default value 1 otherwise.

9.2.2.2 UpdateVariationProductBundleHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.ProductBundleHandler

In case the replaced product was a product bundle the old bundle members are removed. Then the handler creates bundle member entries, if the new variation product is a product bundle.

9.2.2.3 UpdateVariationRequiredAttributesHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.UpdateVariationOrderRequiredAttributesHandler

Handler removes at first all old order required attributes and then adds all order required product attributes to the newly created line item. It uses the ProductBOOrderRequiredAttributesExtension.getOrderRequiredAttributes().
This extension is aware of following types of order required attributes:

  1. Order required attributes directly specified at the product.
  2. Attributes that belong to the product attribute group Order Required Attributes.
  3. Classification catalog service type excludeFromShipping

Attributes are now of the type BusinessObjectAttribute. Those attributes will usually be prefixed with BusinessObjectAttributes#.

Because the checkout process does not use BO's everywhere we use an own factory ExtensibleObjectBasketProductLineItemAttributesExtensionFactory and set the prefix to an empty string.

9.2.2.4 UpdateVariationGiftOptionsHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.GiftOptionsHandler

In case the replaced product had gifting options or messages it is checked if the new variation product is eligible too. If not the gift options are removed.

9.2.2.5 UpdateVariationWarrantyHandler

Default implementation: com.intershop.component.basket.orm.internal.handlers.WarrantyHandler

In case the replaced product had warranty assigned it is checked if the new variation product is eligible for warranties. If not the warranty is removed.

10 Merge-Baskets Operation

This functionality provides the possibility of merging the content of one basket into another, which is for instance used when a customer starts putting items into his basket and logs then into his account.

10.1 Business Object Layer

Business object layer specific logic is implemented in the bc_orderprocess (pipeline), the bc_basket (BO interfaces) and bc_basket_orm cartridges (BO implementations).

10.1.1 Pipeline

ProcessBasket-MergeBaskets

10.1.2 Java (BO)

Basic basket creation functionality is done in Java by implementations of com.intershop.component.basket.capi.BasketBO which provide the following two methods:

<T extends Object> MergeBasketResult merge(BasketBO other, Map<String, T> parameters);

10.2 Handler Chain

When merging the contents of the two baskets the Add-To-Basket handler chain is used. The results of the internal add calls are available in the MergeBasketResult.

11 Anonymize Basket

A basket has to be anonymized in some cases.
  • In case there is a time-based basket resulting from an outdated session.
  • If this basket is restored from a cookie holding the related basket ID it has to be anonymized.

This means that following personal data have to be removed from the basket to avoid any kind of abuse, e.g., payment data, or to prevent that another user gets profits only available to the user that created the basket originally:

  • Personal address data, like invoice-to and ship-to addresses.
  • Data entered in the course of gift messages.
  • Promotion codes resulting in discounts.
  • Payment related data.

In customer scenarios there might be additional information that should be removed from a basket presented to a possibly different user. For this reason a handler chain has been introduced on Java level, that can be used to remove custom data.

11.1 Handler Chain

concept_basket_handling_anonymize_basket_handler_chain

Every handler has to implement the following interface:

concept_basket_handling_anonymize_basket_handler
public interface AnonymizeBasketHandler
{
    void anonymize(BasketBO basket);
}

12 Validate Basket

@Beta: This feature has been introduced with 7.8. in a @Beta status. It is only used at very specific points at time of 7.8. release.

Validating the basket is necessary at any time during the checkout.

These validations should be done in Java (not in pipelines) so that the basket can easily be validated in REST as well and that the same validation is called whenever you choose to validate. So far, our implementations in pipelines differ, are not flexible, hard to extend, and cannot be directly called from REST.

An extensible Handler Chain solves those problems: Customers can write their one Handlers, it's a single point to call and it can easily be called from REST.

Depending on how far the customer is in the checkout process, different areas of the basket need to be validated. Example: on the shopping cart page, when entering the checkout, only products should be validated, while after the address page, also addresses need to be validated. Those are called scopes. Scopes right now are defined by a String: "Value" is the scope Value, meaning all handlers based on basket value are executed, like the MinItemValueValidationHandler. Keeping it that simple has the advantage of easy extensibility - by just calling the validate methods with a different string, another scope exists and can be used in the handlers.

12.1 Glossary

TermDescription
ScopesBasket Validation needs to validate different objects of the basket at different times/stages of the checkout. To distinguish those stages, a SCOPE or several SCOPES need to be defined for validation.
Example: On the shopping cart page, when entering the checkout, only products (scope Products ) should be validated, while after the address page, also addresses (scope Addresses ) need to be validated.

12.2 Parameters to Control Validation

(can be set directly via BasketValidationRecord or via pipeline node ValidateBasket)

ParameterDefault ValuePossible ValuesDescription
stopOnErrorFalseNeverStopAlways finish validation (default)
StopOnErrorStop as soon as an error occurs

StopOnErrorFinishScope

Stop when an error occurs but finish the scope the error occurred in

allowAdjustmentsTrue

True

Adjustments are allowed during validation, like removing a PLI in case of missing inventory or trying to set a preferred address if address is missing
FalseNo adjustments are allowed during validation, errors are collected but not corrected

12.3 Current Standard Scopes and Handlers

ScopeWhat forCurrent HandlersDefault Priority
ProductsProduct availability, available prices etcProductAccessibilityHandler140
ProductIntegrityHandler (replaces ProcessBasket-RemoveLineItemsWithoutPrice)135
ProductInventoryHandler (replaces ProcessBasket-AdjustBasketByInventoryStatus)

130

ProductLifeCycleHandler125

WarrantyValidationHandler (replaces ProcessBasket-RemoveWarrantiesWithoutPrice and ProcessCheckout-RemoveObsoleteWarranties)

105
MaxItemQuantityHandler95
AddressesValidators that validate existence and/or validity of addressesShipToAddressValidationHandler (replaces ProcessCheckoutAddresses-DefaultSettings)

120

InvoiceToAddressValidationHandler (replaces ProcessCheckoutAddresses-DefaultSettings)

121

AddressChangeCalculationValidationHandler122
EligibleShippingMethodsHandler115

ShippingRestrictionHandler (replaces VerifyShippingRestrictions)

110
PaymentPayment related validation like is payment available, is basket covered etc., gift-card validation

PaymentValidationHandler (replaces ProcessCheckoutPayment-CheckDefaultUserSettings, ViewCheckout-CheckPayment and ViewCheckoutReview-CheckPayment)

160
BasketAmountCoveredValidationHandler (replaces ViewCheckout-CheckPayment and ViewCheckoutReview-CheckPayment)155
ValueAre min and max values not exceeded

MinItemValueValidationHandler (replaces CheckBasketMinTotalValue)

175
MaxItemValueValidationHandler (replaces ViewCart-IsMaxOrderAmountExceeded and ViewCheckoutReview-IsMaxOrderAmountExceeded)170
ShippingAre shipping methods set and eligible

DefaultShippingMethodHandler (replaces ProcessShipping-DefaultSettings and VerifyShippingMethods) until 7.10.

Since 7.10 replaced by ShippingMethodHandler

145

DesiredDeliveryDateValidationHandler (replaces ProcessShipping-ValidateDesiredDeliveryDates and VerifyProductLineItemDesiredDeliveryDates)

100
(empty String) no scopeAll validators that should always be executed

BasketStatusValidationHandler

195
EmptyBasketValidationHandler190
MaxItemSizeHandler185
RecurringOrderValidators specially for validating a recurring basketRecurringOrderDateValidationHandler165
CostCenterValidators that check the correctness of cost center specific dataCostCenterValidationHandler150
OrderFinal order scope

TermsAndConditionsValidatorHandler (replaces ViewCheckoutReview-CheckTermsAndConditions) 

200


TaxServiceAvailableValidationHandler (replaces ViewCheckoutReview-CheckBasketContinueCheckoutIfTaxServiceUnavailable)180
PromotionValidators that check explicit promotions (with promotion code) and all related aspects (code groups, user group assignment etc.)BasketValidationPromotionHandler (replaces ProcessPromotionCodeForBasket-ValidatePromotion, ProcessPromotionCodeForBasket-ValidatePromotionCodeGroup )210
AllAll scopes should be checkedALL registered handlers are invoked in order of their priority (highest first)-

12.4 Special Parameters in BasketValidationResult

Since the BasketValidationResult is very generic, there was a need for some special parameters. Those are and can be set directly in the handlers.

Parameter NameClassDescription
parameter0 and parameter1String

Can be used to hand parameters to the SF message for the failure code.
Like "The items in your cart exceed the allowed maximum subtotal of {0} by {1}."  In this case {0} and {1} will be filled with parameter0 and parameter1.

AdjustBasketResultAdjustBasketResultCan be used to show details about Product Adjustments in SF
RemoveFromBasketResultRemoveFromBasketResultCan be used to show details about Product Removals in SF

12.5 Class Diagram

12.6 Handler Chain

concept_basket_handling_basket_validation_handler_chain



Disclaimer

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.

Customer Support
Knowledge Base
Product Resources
Support Tickets