atg.commerce.pricing
Class ItemDiscountCalculator

java.lang.Object
  extended by atg.nucleus.logging.VariableArgumentApplicationLoggingImpl
      extended by atg.nucleus.GenericService
          extended by atg.commerce.pricing.DiscountCalculatorService
              extended by atg.commerce.pricing.ItemDiscountCalculator
All Implemented Interfaces:
ItemPricingCalculator, atg.naming.AbsoluteNameable, NameContextBindingListener, NameContextElement, atg.naming.NameContextParentable, NameResolver, AdminableService, atg.nucleus.Configured, ApplicationLogging, atg.nucleus.logging.ApplicationLoggingSender, atg.nucleus.logging.TraceApplicationLogging, VariableArgumentApplicationLogging, ComponentNameResolver, Service, ServiceListener, java.util.EventListener
Direct Known Subclasses:
BulkItemDiscountCalculator, GWPDiscountCalculator, GWPPriceCalculator, ItemDiscountMultiplierCalculator

public class ItemDiscountCalculator
extends DiscountCalculatorService
implements ItemPricingCalculator

Calculates the new price for an item or items based on a given pricing model. The pricing model must be a RepositoryItem of type item-discount (that is, it must be a RepositoryItem with all the same properties as the DCS item-discount item descriptor).

The calculator has two methods of operation: 1. If the extra parameters map contains pre-qualified items and a discount structure then the calculator will just apply the discount to those items. QualifiedItem objects should be stored in a Collection with the map key Constants.QUALIFIED_ITEMS. The DiscountStructure object should be stored with the map key Constants.DISCOUNT_STRUCTURE. 2. The calculator will inspect the pricing model repository item that it is given and, based on the discountType and adjuster properties, applies the discount to the price in the ItemPriceInfo corresponding to each CommerceItem that's passed in. It does this by consulting the Qualifier service for a list of items which should receive the input discount. It calls Qualifier.findQualifyingItems to do this.

The ItemDiscountCalculator inherits properties from DiscountCalculatorService.

See Also:
Qualifier, DiscountCalculatorService

Field Summary
static java.lang.String CLASS_VERSION
          Class version string
static java.lang.String EXTRA_PARAM_QUALIFIERSERVICE
          The name used for specifying a qualifier service through the extra parameters map passed into the pricing operation.
 
Fields inherited from class atg.commerce.pricing.DiscountCalculatorService
AMOUNT_INCREASE_TYPE, AMOUNT_OFF_TYPE, FIXED_PRICE_TYPE, ILLEGAL_TYPE, mPromotionTools, PERCENT_OFF_TYPE
 
Fields inherited from class atg.nucleus.GenericService
SERVICE_INFO_KEY
 
Fields inherited from interface atg.nucleus.logging.TraceApplicationLogging
DEFAULT_LOG_TRACE_STATUS
 
Fields inherited from interface atg.nucleus.logging.ApplicationLogging
DEFAULT_LOG_DEBUG_STATUS, DEFAULT_LOG_ERROR_STATUS, DEFAULT_LOG_INFO_STATUS, DEFAULT_LOG_WARNING_STATUS
 
Constructor Summary
ItemDiscountCalculator()
           
 
Method Summary
protected  long determineDiscountNumber(DetailedItemPriceInfo pDetailedItemPriceInfo, QualifiedItem pQualifiedItem, RepositoryItem pPricingModel)
          determines the quantity to be discounted in the given detailed item price info
 void doStartService()
          Checks to see if property qualifierService is set
 double findAdjustedPrice(DetailedItemPriceInfo pDetailedItemPriceInfo, java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, RepositoryItem pProfile, java.util.Locale pLocale, Order pOrder, java.util.Map pExtraParameters)
          Calls the DiscountCalculatorService's adjust method to determine the new price for the input pDetailedItemPriceInfo.
protected  java.util.Collection findQualifyingItems(java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, RepositoryItem pProfile, java.util.Locale pLocale, Order pOrder, java.util.Map pExtraParameters)
          Produces a collection of QualifiedItem objects, each of which contains a CommerceItem and a map of detailed item price info to the ranges to be discounted.
protected  double getAmountToDiscount(DetailedItemPriceInfo pDetailedItemPriceInfo, java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, RepositoryItem pProfile, java.util.Locale pLocale, Order pOrder, java.util.Map pExtraParameters)
          This will return the amount that will eventually be discounted.
 PricingTools getPricingTools()
          pricing tools to help with price generation
 atg.core.util.RangeComparator getRangeComparator()
          The object that is used to compare ranges
protected  DetailedItemPriceInfo priceDetailedItemPriceInfo(DetailedItemPriceInfo pDetailedItemPriceInfo, QualifiedItem pQualifiedItem, java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, RepositoryItem pProfile, java.util.Locale pLocale, Order pOrder, java.util.Map pExtraParameters)
          Deprecated. This method is deprecated. Call updateDetailedItemPriceInfos instead.
 void priceEachItem(java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, java.util.Locale pLocale, RepositoryItem pProfile, java.util.Map pExtraParameters)
          give each item the configured discount, if it qualifies
 void priceItem(ItemPriceInfo pPriceQuote, CommerceItem pItem, RepositoryItem pPricingModel, java.util.Locale pLocale, RepositoryItem pProfile, java.util.Map pExtraParameters)
          give a single item the configured discount, if it is eligible.
 void priceItems(java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, java.util.Locale pLocale, RepositoryItem pProfile, Order pOrder, java.util.Map pExtraParameters)
          Price a List of items together in a context when it comes right down to it, we're only discounting single items : the only reason we need to price items in a context is to allow complex qualification statements.
protected  void priceQualifyingItem(QualifiedItem pQualifiedItem, java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, RepositoryItem pProfile, java.util.Locale pLocale, Order pOrder, java.util.Map pExtraParameters)
          Determines and sets the amount of the ItemPriceInfo in pPriceQuotes at the index corresponding to the CommerceItem in pItems that is contained in pQualifiedItem.
protected  void priceQualifyingItems(java.util.Collection pQualifyingItems, java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, RepositoryItem pProfile, java.util.Locale pLocale, Order pOrder, java.util.Map pExtraParameters)
          Loops through each QualifiedItem object in pQualifyingItems, determining and setting the price for each QualifiedItem's CommerceItem'sItemPriceInfo.
 void setPricingTools(PricingTools pPricingTools)
          pricing tools to help with price generation
 void setRangeComparator(atg.core.util.RangeComparator pRangeComparator)
           
protected  java.util.List updateDetailedPriceInfos(DetailedItemPriceInfo pDetailedItemPriceInfo, QualifiedItem pQualifiedItem, java.util.List pPriceQuotes, java.util.List pItems, RepositoryItem pPricingModel, RepositoryItem pProfile, java.util.Locale pLocale, Order pOrder, java.util.Map pExtraParameters)
          Maintains the Amount, Adjustments, and HasBeenDiscounted properties of pDetailedItemPriceInfo
protected  void updateQualifyingDetails(QualifiedItem pQualifiedItem, ItemPriceInfo pPriceQuote)
          This method allows a QualifiedItem qualifyingDetailsMap to be updated.
protected  void updateQuantityAsQualifier(FilteredCommerceItem pFilteredCommerceItem, java.util.List<DetailedItemPriceInfo> pDetails, java.util.List<atg.core.util.Range> pQuantityAsQualifierRanges)
          After a partial adjustment a detail may have been split into multiple details.
protected  boolean validateQualifierService()
          Determines if the qualifier service is valid.
 
Methods inherited from class atg.commerce.pricing.DiscountCalculatorService
adjust, adjustAmount, getAdjuster, getDiscountType, getDiscountType, getPricingModelProperties, getPromotionTools, getQualifierService, getQualifierService, isNegativeAmountException, setNegativeAmountException, setPricingModelProperties, setPromotionTools, setQualifierService
 
Methods inherited from class atg.nucleus.GenericService
addLogListener, createAdminServlet, doStopService, getAbsoluteName, getAdminServlet, getAdminServletOutputStreamEncoding, getLoggingForVlogging, getLogListenerCount, getLogListeners, getName, getNameContext, getNucleus, getRoot, getServiceConfiguration, getServiceInfo, isAdminServletUseServletOutputStream, isLoggingDebug, isLoggingError, isLoggingInfo, isLoggingTrace, isLoggingWarning, isRunning, logDebug, logDebug, logDebug, logError, logError, logError, logInfo, logInfo, logInfo, logTrace, logTrace, logTrace, logWarning, logWarning, logWarning, nameContextElementBound, nameContextElementUnbound, removeLogListener, reResolveThis, resolveName, resolveName, resolveName, resolveName, sendLogEvent, setAdminServletOutputStreamEncoding, setAdminServletUseServletOutputStream, setLoggingDebug, setLoggingError, setLoggingInfo, setLoggingTrace, setLoggingWarning, setNucleus, setServiceInfo, startService, stopService
 
Methods inherited from class atg.nucleus.logging.VariableArgumentApplicationLoggingImpl
vlogDebug, vlogDebug, vlogDebug, vlogDebug, vlogDebugTrace, vlogError, vlogError, vlogError, vlogError, vlogInfo, vlogInfo, vlogInfo, vlogInfo, vlogTrace, vlogTrace, vlogTrace, vlogTrace, vlogWarning, vlogWarning, vlogWarning, vlogWarning
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CLASS_VERSION

public static final java.lang.String CLASS_VERSION
Class version string

See Also:
Constant Field Values

EXTRA_PARAM_QUALIFIERSERVICE

public static final java.lang.String EXTRA_PARAM_QUALIFIERSERVICE
The name used for specifying a qualifier service through the extra parameters map passed into the pricing operation.

See Also:
Constant Field Values
Constructor Detail

ItemDiscountCalculator

public ItemDiscountCalculator()
Method Detail

setPricingTools

public void setPricingTools(PricingTools pPricingTools)
pricing tools to help with price generation

Parameters:
pPricingTools - new value to set

getPricingTools

public PricingTools getPricingTools()
pricing tools to help with price generation

Returns:
property PricingTools

setRangeComparator

public void setRangeComparator(atg.core.util.RangeComparator pRangeComparator)

getRangeComparator

public atg.core.util.RangeComparator getRangeComparator()
The object that is used to compare ranges


priceItem

public void priceItem(ItemPriceInfo pPriceQuote,
                      CommerceItem pItem,
                      RepositoryItem pPricingModel,
                      java.util.Locale pLocale,
                      RepositoryItem pProfile,
                      java.util.Map pExtraParameters)
               throws PricingException
give a single item the configured discount, if it is eligible. eligibility is determined by consulting a configured qualifierService

Specified by:
priceItem in interface ItemPricingCalculator
Parameters:
pPriceQuote - ItemPriceInfo representing the current price quote for the item
pItem - The item to price
pPricingModel - A RepositoryItem representing a PricingModel
pLocale - the locale for this pricing
pProfile - The user's profile
pExtraParameters - A Map of extra parameters to be used in the pricing, may be null
Throws:
PricingException - if there was a problem in determining an item's price

priceEachItem

public void priceEachItem(java.util.List pPriceQuotes,
                          java.util.List pItems,
                          RepositoryItem pPricingModel,
                          java.util.Locale pLocale,
                          RepositoryItem pProfile,
                          java.util.Map pExtraParameters)
                   throws PricingException
give each item the configured discount, if it qualifies

Specified by:
priceEachItem in interface ItemPricingCalculator
Parameters:
pPriceQuotes - List of ItemPriceInfo objects representing the current price quotes for each item
pItems - The items to price (individually)
pPricingModel - A RepositoryItem representing a PricingModel
pLocale - the locale for this pricing
pProfile - The user's profile
pExtraParameters - A Map of extra parameters to be used in the pricing, may be null
Throws:
PricingException - if there was a problem in determining an item's price

priceItems

public void priceItems(java.util.List pPriceQuotes,
                       java.util.List pItems,
                       RepositoryItem pPricingModel,
                       java.util.Locale pLocale,
                       RepositoryItem pProfile,
                       Order pOrder,
                       java.util.Map pExtraParameters)
                throws PricingException
Price a List of items together in a context when it comes right down to it, we're only discounting single items : the only reason we need to price items in a context is to allow complex qualification statements.

Specified by:
priceItems in interface ItemPricingCalculator
Parameters:
pPriceQuotes - List of ItemPriceInfo objects representing the current price quotes for the items
pItems - The items to price
pPricingModel - A RepositoryItem representing a PricingModel
pProfile - The user's profile
pLocale - the locale for this pricing
pOrder - The Order object of which the List of items are a part, may be null
pExtraParameters - A Map of extra parameters to be used in the pricing, may be null
Throws:
PricingException - if there was a problem in determining an item's price

validateQualifierService

protected boolean validateQualifierService()
Determines if the qualifier service is valid.

Returns:
true if the qualifier service is non null.

doStartService

public void doStartService()
                    throws ServiceException
Checks to see if property qualifierService is set

Overrides:
doStartService in class GenericService
Throws:
ServiceException - if there was a problem initializing this service

findQualifyingItems

protected java.util.Collection findQualifyingItems(java.util.List pPriceQuotes,
                                                   java.util.List pItems,
                                                   RepositoryItem pPricingModel,
                                                   RepositoryItem pProfile,
                                                   java.util.Locale pLocale,
                                                   Order pOrder,
                                                   java.util.Map pExtraParameters)
                                            throws PricingException
Produces a collection of QualifiedItem objects, each of which contains a CommerceItem and a map of detailed item price info to the ranges to be discounted. The collection of qualified items can be passed in via the extra parameters map using the key Constants.QUALIFIED_ITEMS otherwise they are determined using a qualifier service. The qualifier service to use is determined using the PromotionTools.getQualifierService method.

Note: in the lists pPriceQuotes and pItems, there is a 1:1 correspondence between ItemPriceInfos and items. That is to say, element 1 of pPriceQuotes is the ItemPriceInfo for the item at element 1 of pItems, and so on.

Side Effects:

In each ItemPriceInfo for each qualifying item, if its corresponding item acted as a qualifier in determining the qualifying items, the appropriate quantity is marked as having acted as a qualifier. This marking takes place only if the ItemPriceInfo is an instance of ItemPriceInfo.

Parameters:
pPriceQuotes - the input list of item prices
pItems - the total set of items from which qualifying items will be selected
pPricingModel - the discount which defines which items qualify
pProfile - the user for whom this calculation is being performed
pLocale - the locale in which this calculation is being performed
pOrder - the order in which the qualifying items reside
pExtraParameters - any extra information that this calculator might need to determine which items qualify for a discount.
Returns:
a Collection of QualifiedItem objects
Throws:
PricingException - if anything went wrong while determining the QualifiedItems
See Also:
PriceItems

priceQualifyingItems

protected void priceQualifyingItems(java.util.Collection pQualifyingItems,
                                    java.util.List pPriceQuotes,
                                    java.util.List pItems,
                                    RepositoryItem pPricingModel,
                                    RepositoryItem pProfile,
                                    java.util.Locale pLocale,
                                    Order pOrder,
                                    java.util.Map pExtraParameters)
                             throws PricingException
Loops through each QualifiedItem object in pQualifyingItems, determining and setting the price for each QualifiedItem's CommerceItem'sItemPriceInfo. The default implementation does this by calling priceQualifyingItem.

Note: the Collection of QualifiedItem's (and the DiscountStructure if available) is stored in the extra parameters map so that they can be accessed within the getAdjuster method since this is needed by some extensions of this calculator, e.g. BulkItemDiscountCalculator. The qualified items are stored with the key Constants.QUALIFIED_ITEMS and the discount structure is stored with the key Constants.DISCOUNT_STRUCTURE.

Side Effects: Each ItemPriceInfo in pPriceQuotes that is at the same index as that at which the CommerceItem in pItems that is the QualifiedItem's CommerceItem resides has its price set to the proper price.

Parameters:
pQualifyingItems - a collection of QualifiedItem objects that contains information about which and how many items should be discounted.
pPriceQuotes - the price objects corresponding to pItems
pItems - the items whose prices are contained in pPriceQuotes
pPricingModel - the discount which states how the qualifying items should be priced
pProfile - the person for whom the items are to be discounted
pLocale - the locale in which the items are to be discounted
pOrder - the order in which the discounted items have been placed
pExtraParameters - any extra information that this method might need to set the prices of a number of qualifying items
Throws:
PricingException - if anything went wrong while pricing the QualifiedItems
See Also:
PriceItems

priceQualifyingItem

protected void priceQualifyingItem(QualifiedItem pQualifiedItem,
                                   java.util.List pPriceQuotes,
                                   java.util.List pItems,
                                   RepositoryItem pPricingModel,
                                   RepositoryItem pProfile,
                                   java.util.Locale pLocale,
                                   Order pOrder,
                                   java.util.Map pExtraParameters)
                            throws PricingException
Determines and sets the amount of the ItemPriceInfo in pPriceQuotes at the index corresponding to the CommerceItem in pItems that is contained in pQualifiedItem.

Side Effects:

The default implementation of this method assumes that the ItemPriceInfo whose Amount this method is maintaining has a detailedCurrentPrice property which represents a breakdown of the price into smaller quantities. These DetailedItemPriceInfo objects have their amounts maintained as well, through calls to priceDetailedItemPriceInfo. The ItemPriceInfo has its Amount, Adjustments, and QuantityDiscounted properties maintained.

Parameters:
pQualifiedItem - the object stating which item, and how many of that item, qualified for the discount defined by pPricingModel. It is expected that each QualifiedItem is a FilteredCommerceItem
pPriceQuotes - the price objects corresponding to pItems
pItems - the items whose prices are contained in pPriceQuotes
pPricingModel - the discount which states how the qualifying items should be priced
pProfile - the person for whom the items are to be discounted
pLocale - the locale in which the items are to be discounted
pOrder - the order in which the discounted items have been placed
pExtraParameters - any extra information that this method might need to set the prices of a number of the qualifying item
Throws:
PricingException - if anything went wrong while pricing the QualifiedItem
See Also:
PriceItems

priceDetailedItemPriceInfo

protected DetailedItemPriceInfo priceDetailedItemPriceInfo(DetailedItemPriceInfo pDetailedItemPriceInfo,
                                                           QualifiedItem pQualifiedItem,
                                                           java.util.List pPriceQuotes,
                                                           java.util.List pItems,
                                                           RepositoryItem pPricingModel,
                                                           RepositoryItem pProfile,
                                                           java.util.Locale pLocale,
                                                           Order pOrder,
                                                           java.util.Map pExtraParameters)
                                                    throws PricingException
Deprecated. This method is deprecated. Call updateDetailedItemPriceInfos instead.

Throws:
PricingException
See Also:
#updateDetailedItemPriceInfos

updateDetailedPriceInfos

protected java.util.List updateDetailedPriceInfos(DetailedItemPriceInfo pDetailedItemPriceInfo,
                                                  QualifiedItem pQualifiedItem,
                                                  java.util.List pPriceQuotes,
                                                  java.util.List pItems,
                                                  RepositoryItem pPricingModel,
                                                  RepositoryItem pProfile,
                                                  java.util.Locale pLocale,
                                                  Order pOrder,
                                                  java.util.Map pExtraParameters)
                                           throws PricingException
Maintains the Amount, Adjustments, and HasBeenDiscounted properties of pDetailedItemPriceInfo

Side Effects:

Each DetailedItemPriceInfo has its Amount, Adjustments, and HasBeenDiscounted properties maintained.

Parameters:
pDetailedItemPriceInfo - the price object which should receive the discount specified by pPricingModel
pQualifiedItem - the object stating which item, and how many of that item, qualified for the discount defined by pPricingModel. It is expected that each QualifiedItem is a FilteredCommerceItem
pPriceQuotes - the price objects corresponding to pItems
pItems - the items whose prices are contained in pPriceQuotes
pPricingModel - the discount which states how the qualifying items should be priced
pProfile - the person for whom the items are to be discounted
pLocale - the locale in which the items are to be discounted
pOrder - the order in which the discounted items have been placed
pExtraParameters - any extra information that this method might need to set the prices of a number of the qualifying item
Returns:
the DetailedItemPriceInfos, original and any newly created ones
Throws:
PricingException - if anything went wrong while pricing the DetailedItemPriceInfo
See Also:
priceItems, priceQualfyingItem

determineDiscountNumber

protected long determineDiscountNumber(DetailedItemPriceInfo pDetailedItemPriceInfo,
                                       QualifiedItem pQualifiedItem,
                                       RepositoryItem pPricingModel)
                                throws PricingException
determines the quantity to be discounted in the given detailed item price info

Parameters:
pDetailedItemPriceInfo -
pQualifiedItem -
pPricingModel -
Returns:
Throws:
PricingException

updateQuantityAsQualifier

protected void updateQuantityAsQualifier(FilteredCommerceItem pFilteredCommerceItem,
                                         java.util.List<DetailedItemPriceInfo> pDetails,
                                         java.util.List<atg.core.util.Range> pQuantityAsQualifierRanges)
                                  throws PricingException
After a partial adjustment a detail may have been split into multiple details. This method ensures that the quantityAsQualifier ranges mapped against the original detail are also split accordingly.

Parameters:
pFilteredCommerceItem - FilteredCommerceItem to update
pDetails - List of DetailedItemPriceInfo after the split, includes the original detail too.
pQuantityAsQualifierRanges - List of Range of the original detail quantity as qualifiers.
Throws:
PricingException - for errors.

findAdjustedPrice

public double findAdjustedPrice(DetailedItemPriceInfo pDetailedItemPriceInfo,
                                java.util.List pPriceQuotes,
                                java.util.List pItems,
                                RepositoryItem pPricingModel,
                                RepositoryItem pProfile,
                                java.util.Locale pLocale,
                                Order pOrder,
                                java.util.Map pExtraParameters)
                         throws PricingException
Calls the DiscountCalculatorService's adjust method to determine the new price for the input pDetailedItemPriceInfo.

Parameters:
pDetailedItemPriceInfo - the price object whose price is to be modified
pPriceQuotes - the price objects corresponding to pItems
pItems - the items whose prices are contained in pPriceQuotes
pPricingModel - the discount which states how the qualifying items should be priced
pProfile - the person for whom the items are to be discounted
pLocale - the locale in which the items are to be discounted
pOrder - the order in which the discounted items have been placed
pExtraParameters - any extra information that this method might need to set the prices of a number of the qualifying item
Returns:
the adjusted price for the input pDetailedItemPriceInfo
Throws:
PricingException - if there was a problem in determining the adjusted price

getAmountToDiscount

protected double getAmountToDiscount(DetailedItemPriceInfo pDetailedItemPriceInfo,
                                     java.util.List pPriceQuotes,
                                     java.util.List pItems,
                                     RepositoryItem pPricingModel,
                                     RepositoryItem pProfile,
                                     java.util.Locale pLocale,
                                     Order pOrder,
                                     java.util.Map pExtraParameters)
                              throws PricingException
This will return the amount that will eventually be discounted. This will be priceQuote.amount by default (and there will usually be no need to change this.)

Parameters:
pOrder - The order containing the shipping group
pPriceQuote - ShippingPriceInfo representing the current price quote for the shipping group
pShippingGroup - The shipping group that will be discounted (ignored by default)
pPricingModel - A RepositoryItems representing a PricingModel (ignored by default)
pProfile - The user's profile (ignored by default)
pExtraParameters - A Map of extra parameters to be used in the pricing, may be null (ignored by default)
Returns:
The amount to discount... defaults to pPriceQuote.getAmount()
Throws:
PricingException

updateQualifyingDetails

protected void updateQualifyingDetails(QualifiedItem pQualifiedItem,
                                       ItemPriceInfo pPriceQuote)
                                throws PricingException
This method allows a QualifiedItem qualifyingDetailsMap to be updated. This can be necessary if the map created by the Qualifier service is not correct.

For example it is possible for multiple discounts in a single promotion that a previous discount could have split some detailed item price info. However the QualifiedItem was created before this split took place and so some qualifying ranges may still be pointing to the original unsplit detailed item price info. So we need to fix any such references to point to the correct dipi. This implementation will update the QualifiedItem's qualifyingDetailsMap to ensure the latest detailed item price info references are used.

Parameters:
pQualifiedItem - the QualifiedItem to check and fix if needed
pPriceQuote - the item price info
Throws:
PricingException - if the qualifying ranges can't be updated