This section describes how qualifiers are evaluated using a “buy 1 get 1 free” example. This example uses a promotion of type “Item Discount” where the fixed price is $0.00 and the PMDL rule is:
Condition:
When order contains at least 1 (product named Shirt)
Apply discount to:
up to 1 (product named Hat)
The discount-structure in the PMDL would contain the following information:
<calculator-type="standard" discount-type="fixed-price"
adjuster="0">
If the list price of the shirt is $10.00 and the list price of the hat of $5.00, then first, the ItemPricingEngine iterates through each of the pre-calculators:
The
ItemListPriceCalculatorlooks up the list price of each item in the order. Based on the list prices, the shirt is priced at $10.00 and the hat will be priced at $5.00. This will update theItemPriceInfofor both theCommerceItemobjects in the order.The
ItemSalePriceCalculatorlooks up the sale price of each item in the order. Because neither item is on sale, this has no effect on the price.
Next, The ItemPricingEngine iterates through each of the promotions. In this example, the “Buy 1 shirt, get 1 hat free” promotion is the only promotion.
The pricing engine calls findQualifyingItems() and uses the returned calculator-type to look up the ItemDisCountCalculator.
The findQualifyingItems method performs the following functions (as well as some standard parameter verification and error checking):
wrapCommerceItems: CreatesFilteredCommerceItemsfor each itemfilterItemsForQualifier: Runs through the list of the qualifier filters. In this example, none of the qualifiers applyevaluateQualifier: Three arguments are passed toevaluateQualifier.PricingContext: Contains the following information, with specifics for this example in parentheses:pricingModel: Current promotion (Buy 1 shirt, get 1 hat free)profile: Current profile objectlocale: User’s localeorder: The order being pricedorderPriceInfo: The order’s price (not yet calculated for this order)shippingGroup: TheShippingGroupbeing priced (null, as what is being priced is not a shipping group). Note that theQualifierServicecannot run an individual shipping group rule for non-shipping promotionsshippingPriceInfo: Costs associated with the shipping group being priced (null, as what is being priced is not a shipping group)
pendingQuantityAsQualifierDetails: Clears out items that have acted as qualifiers for the current pricingModel. The filterForItemsActedAsQualifier can be used to allow items that have acted as qualifiers for another promotion to be able to act as qualifiers againFilterQualfiedItems: Represents a List ofFilteredCommerceItemobjects (Shirt and Hat) and their correspondingItemPriceInfoobjects ($10 and $5)ExtraParametersMapis not needed in this example, but can be used to pass additional parameters as needed
In this example, the evaluateQualifier method returns Boolean.TRUE. The reason this is a Boolean value is because this is a when rule. There are three choices for the condition: always, when, and for. In the case of always and when, evaluateQualifier returns a Boolean value.
Note: If the rule were a for rule, then evaluateQualifier would return the list of items that triggered the promotion. If the promotion was “For next 1 (product named shirt)” then this method would return a List containing one MatchingObject that wrapped the “shirt” CommerceItem and had quantity 1.
Because the promotion is valid, we must determine which items will receive the discount. The first step is to filter the items for the target. (filterItemsForTarget).
Note: Because this promotion involves a when rule, we can immediately evaluate the target. If this was a for rule, we would first determine the range within which DetailedItemPriceInfo(s) acted as the qualifier.
Call isDiscountableItem. This method determines whether the item has been identified as non-discountable by a Merchandising user.
Call evaluateTarget. Assuming none of the target filters applied, the list of arguments here will be the same as the list passed to evaluteQualifier. In this example, one item should be discounted so this method will return a List with one item in it. The item will be a MatchingObject with the following property values:
matchingObjectproperty is the hatCommerceItemquantityproperty is 1discountsproperty contains a List ofDiscountStructureobjects, representing thediscount-structureelement from the PMDL.
Next, the pricing engine gets the calculator-type from the DiscountStructure object, looks up the calculatorTypeCalculators map to get the calculator component, puts the QualifiedItem objects into the extra parameters map, and then calls the calculator.
Finally, the calculator’s findQualifyingItems method pulls the QualifiedItem objects out of the map. The getAdjuster and getDiscountType methods get the DiscountStructure out of the map. The calculator now knows which items should receive the discount, so it calls priceQualifyingItems. This method goes through each detail of each item that qualifies (there is only one in our case) and updates the price.
For detailed information on working with the Qualifer class, refer to the ATG Platform API Reference.

