public int calculateMaxUsesForItemCriteria(OfferItemCriteria itemCriteria, Offer promotion) { int numberOfTargets = 0; int numberOfUsesForThisItemCriteria = 9999; if (candidateTargets != null && itemCriteria != null) { for (PromotableOrderItem potentialTarget : candidateTargets) { numberOfTargets += potentialTarget.getQuantityAvailableToBeUsedAsTarget(promotion); } numberOfUsesForThisItemCriteria = numberOfTargets / itemCriteria.getQuantity(); } return numberOfUsesForThisItemCriteria; }
protected void applyItemQualifiersAndTargets( PromotableCandidateItemOffer itemOffer, PromotableOrder order) { Offer promotion = itemOffer.getOffer(); OrderItemPriceComparator priceComparator = new OrderItemPriceComparator(promotion.getApplyDiscountToSalePrice()); boolean matchFound = false; do { matchFound = false; int totalQualifiersNeeded = 0; for (OfferItemCriteria itemCriteria : itemOffer.getCandidateQualifiersMap().keySet()) { totalQualifiersNeeded += itemCriteria.getQuantity(); } int receiveQtyNeeded = promotion.getTargetItemCriteria().getQuantity(); checkAll: { for (OfferItemCriteria itemCriteria : itemOffer.getCandidateQualifiersMap().keySet()) { List<PromotableOrderItem> chargeableItems = itemOffer.getCandidateQualifiersMap().get(itemCriteria); // Sort the items so that the highest priced ones are at the top Collections.sort(chargeableItems, priceComparator); // Calculate the number of qualifiers needed that will not receive the promotion. // These will be reserved first before the target is assigned. int qualifierQtyNeeded = itemCriteria.getQuantity(); for (PromotableOrderItem chargeableItem : chargeableItems) { // Mark Qualifiers if (qualifierQtyNeeded > 0) { int itemQtyAvailableToBeUsedAsQualifier = chargeableItem.getQuantityAvailableToBeUsedAsQualifier(promotion); if (itemQtyAvailableToBeUsedAsQualifier > 0) { int qtyToMarkAsQualifier = Math.min(qualifierQtyNeeded, itemQtyAvailableToBeUsedAsQualifier); qualifierQtyNeeded -= qtyToMarkAsQualifier; chargeableItem.addPromotionQualifier(itemOffer, itemCriteria, qtyToMarkAsQualifier); } } if (qualifierQtyNeeded == 0) { totalQualifiersNeeded -= itemCriteria.getQuantity(); break; } } if (qualifierQtyNeeded != 0) { break checkAll; } } checkTargets: { List<PromotableOrderItem> chargeableItems = itemOffer.getCandidateTargets(); Collections.sort(chargeableItems, priceComparator); for (PromotableOrderItem chargeableItem : chargeableItems) { // Mark Targets if (receiveQtyNeeded > 0) { int itemQtyAvailableToBeUsedAsTarget = chargeableItem.getQuantityAvailableToBeUsedAsTarget(promotion); if (itemQtyAvailableToBeUsedAsTarget > 0) { if (promotion.getMaxUses() == 0 || itemOffer.getUses() < promotion.getMaxUses()) { int qtyToMarkAsTarget = Math.min(receiveQtyNeeded, itemQtyAvailableToBeUsedAsTarget); receiveQtyNeeded -= qtyToMarkAsTarget; // atLeastOneCriteriaMatched = true; chargeableItem.addPromotionDiscount( itemOffer, itemOffer.getOffer().getTargetItemCriteria(), qtyToMarkAsTarget); } } } if (receiveQtyNeeded == 0) { break checkTargets; } } } } boolean criteriaMatched = true; if (receiveQtyNeeded != 0 || totalQualifiersNeeded != 0) { // This ItemCriteria did not match. Therefore, we need to clear all non-finalized // quantities. for (OfferItemCriteria itemCriteria : itemOffer.getCandidateQualifiersMap().keySet()) { List<PromotableOrderItem> chargeableItems = itemOffer.getCandidateQualifiersMap().get(itemCriteria); clearAllNonFinalizedQuantities(chargeableItems); } clearAllNonFinalizedQuantities(itemOffer.getCandidateTargets()); criteriaMatched = false; } if (criteriaMatched) { matchFound = true; finalizeQuantities(order.getDiscountableDiscreteOrderItems()); } // This promotion may be able to be applied multiple times if there is enough // product quantity in the order. Continue to loop through the order until // there are no more matches } while (matchFound); if (order.getSplitItems().size() == 0) { initializeSplitItems(order, order.getDiscountableDiscreteOrderItems()); } List<PromotableOrderItem> allSplitItems = order.getAllSplitItems(); for (PromotableOrderItem chargeableItem : allSplitItems) { if (itemOffer.getCandidateTargets().contains(chargeableItem)) { List<PromotableOrderItem> splitItems = chargeableItem.split(); if (splitItems != null && splitItems.size() > 0) { // Remove this item from the list List<PromotableOrderItem> temp = order.searchSplitItems(chargeableItem); if (!CollectionUtils.isEmpty(temp)) { temp.remove(chargeableItem); temp.addAll(splitItems); } } } } }