use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.
the class FulfillmentGroupOfferProcessorTest method testFilterFulfillmentGroupLevelOffer.
public void testFilterFulfillmentGroupLevelOffer() {
replay();
PromotableOrder order = dataProvider.createBasicPromotableOrder();
List<PromotableCandidateFulfillmentGroupOffer> qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
List<Offer> offers = dataProvider.createFGBasedOffer("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF);
fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
// test that the valid fg offer is included
// No item criteria, so each fulfillment group applies
assertTrue(qualifiedOffers.size() == 2 && qualifiedOffers.get(0).getOffer().equals(offers.get(0)));
qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
offers = dataProvider.createFGBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test1\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))");
fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
// test that the valid fg offer is included
// only 1 fulfillment group has qualifying items
assertTrue(qualifiedOffers.size() == 1 && qualifiedOffers.get(0).getOffer().equals(offers.get(0)));
qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
offers = dataProvider.createFGBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75240", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test1\"),MVEL.eval(\"toUpperCase()\",\"test2\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))");
fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
// test that the invalid fg offer is excluded - zipcode is wrong
assertTrue(qualifiedOffers.size() == 0);
qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
offers = dataProvider.createFGBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test5\"),MVEL.eval(\"toUpperCase()\",\"test6\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))");
fgProcessor.filterFulfillmentGroupLevelOffer(order, qualifiedOffers, offers.get(0));
// test that the invalid fg offer is excluded - no qualifying items
assertTrue(qualifiedOffers.size() == 0);
verify();
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.
the class FulfillmentGroupOfferProcessorImpl method createCandidateFulfillmentGroupOffer.
protected PromotableCandidateFulfillmentGroupOffer createCandidateFulfillmentGroupOffer(Offer offer, List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers, PromotableFulfillmentGroup fulfillmentGroup) {
PromotableCandidateFulfillmentGroupOffer promotableCandidateFulfillmentGroupOffer = promotableItemFactory.createPromotableCandidateFulfillmentGroupOffer(fulfillmentGroup, offer);
qualifiedFGOffers.add(promotableCandidateFulfillmentGroupOffer);
return promotableCandidateFulfillmentGroupOffer;
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.
the class FulfillmentGroupOfferProcessorImpl method filterFulfillmentGroupLevelOffer.
@Override
public void filterFulfillmentGroupLevelOffer(PromotableOrder order, List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers, Offer offer) {
for (PromotableFulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) {
boolean fgLevelQualification = false;
fgQualification: {
// handle legacy fields in addition to the 1.5 order rule field
if (couldOfferApplyToOrder(offer, order, fulfillmentGroup)) {
fgLevelQualification = true;
break fgQualification;
}
for (PromotableOrderItem discreteOrderItem : order.getAllOrderItems()) {
if (couldOfferApplyToOrder(offer, order, discreteOrderItem, fulfillmentGroup)) {
fgLevelQualification = true;
break fgQualification;
}
}
}
if (fgLevelQualification) {
fgLevelQualification = false;
// handle 1.5 FG field
if (couldOfferApplyToFulfillmentGroup(offer, fulfillmentGroup)) {
fgLevelQualification = true;
}
}
// Item Qualification - new for 1.5!
if (fgLevelQualification) {
CandidatePromotionItems candidates = couldOfferApplyToOrderItems(offer, fulfillmentGroup.getDiscountableOrderItems());
// on all the items in the order across all fulfillment groups (not the default behavior)
if (!candidates.isMatchedQualifier() && getQualifyGroupAcrossAllOrderItems(fulfillmentGroup)) {
candidates = couldOfferApplyToOrderItems(offer, order.getAllOrderItems());
}
if (candidates.isMatchedQualifier()) {
PromotableCandidateFulfillmentGroupOffer candidateOffer = createCandidateFulfillmentGroupOffer(offer, qualifiedFGOffers, fulfillmentGroup);
candidateOffer.getCandidateQualifiersMap().putAll(candidates.getCandidateQualifiersMap());
}
}
}
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.
the class FulfillmentGroupOfferProcessorImpl method applyAllFulfillmentGroupOffers.
@Override
@SuppressWarnings("unchecked")
public boolean applyAllFulfillmentGroupOffers(List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers, PromotableOrder order) {
Map<FulfillmentGroupOfferPotential, List<PromotableCandidateFulfillmentGroupOffer>> offerMap = new HashMap<FulfillmentGroupOfferPotential, List<PromotableCandidateFulfillmentGroupOffer>>();
for (PromotableCandidateFulfillmentGroupOffer candidate : qualifiedFGOffers) {
FulfillmentGroupOfferPotential potential = new FulfillmentGroupOfferPotential();
potential.setOffer(candidate.getOffer());
if (offerMap.get(potential) == null) {
offerMap.put(potential, new ArrayList<PromotableCandidateFulfillmentGroupOffer>());
}
offerMap.get(potential).add(candidate);
}
List<FulfillmentGroupOfferPotential> potentials = new ArrayList<FulfillmentGroupOfferPotential>();
for (FulfillmentGroupOfferPotential potential : offerMap.keySet()) {
List<PromotableCandidateFulfillmentGroupOffer> fgOffers = offerMap.get(potential);
Collections.sort(fgOffers, new ReverseComparator(new BeanComparator("discountedAmount", new NullComparator())));
Collections.sort(fgOffers, new BeanComparator("priority", new NullComparator()));
if (potential.getOffer().isLimitedUsePerOrder() && fgOffers.size() > potential.getOffer().getMaxUsesPerOrder()) {
for (int j = potential.getOffer().getMaxUsesPerOrder(); j < fgOffers.size(); j++) {
fgOffers.remove(j);
}
}
filterOffersByQualifyingAndSubtotalRequirements(order, fgOffers);
for (PromotableCandidateFulfillmentGroupOffer candidate : fgOffers) {
if (potential.getTotalSavings().getAmount().equals(BankersRounding.zeroAmount())) {
BroadleafCurrency currency = order.getOrderCurrency();
if (currency != null) {
potential.setTotalSavings(new Money(BigDecimal.ZERO, currency.getCurrencyCode()));
} else {
potential.setTotalSavings(new Money(BigDecimal.ZERO));
}
}
Money priceBeforeAdjustments = candidate.getFulfillmentGroup().calculatePriceWithoutAdjustments();
Money discountedPrice = candidate.getDiscountedPrice();
potential.setTotalSavings(potential.getTotalSavings().add(priceBeforeAdjustments.subtract(discountedPrice)));
potential.setPriority(candidate.getOffer().getPriority());
}
potentials.add(potential);
}
// Sort fg potentials by priority and discount
Collections.sort(potentials, new BeanComparator("totalSavings", Collections.reverseOrder()));
Collections.sort(potentials, new BeanComparator("priority"));
potentials = removeTrailingNotCombinableFulfillmentGroupOffers(potentials);
boolean fgOfferApplied = false;
for (FulfillmentGroupOfferPotential potential : potentials) {
Offer offer = potential.getOffer();
boolean alreadyContainsTotalitarianOffer = order.isTotalitarianOfferApplied();
List<PromotableCandidateFulfillmentGroupOffer> candidates = offerMap.get(potential);
for (PromotableCandidateFulfillmentGroupOffer candidate : candidates) {
applyFulfillmentGroupOffer(candidate.getFulfillmentGroup(), candidate);
fgOfferApplied = true;
}
for (PromotableFulfillmentGroup fg : order.getFulfillmentGroups()) {
fg.chooseSaleOrRetailAdjustments();
}
if ((offer.isTotalitarianOffer() != null && offer.isTotalitarianOffer()) || alreadyContainsTotalitarianOffer) {
fgOfferApplied = compareAndAdjustFulfillmentGroupOffers(order, fgOfferApplied);
if (fgOfferApplied) {
break;
}
} else if (!offer.isCombinableWithOtherOffers()) {
break;
}
}
return fgOfferApplied;
}
use of org.broadleafcommerce.core.offer.service.discount.domain.PromotableCandidateFulfillmentGroupOffer in project BroadleafCommerce by BroadleafCommerce.
the class OfferServiceImpl method applyAndSaveFulfillmentGroupOffersToOrder.
@Override
@Transactional("blTransactionManager")
public Order applyAndSaveFulfillmentGroupOffersToOrder(List<Offer> offers, Order order) throws PricingException {
OfferContext offerContext = OfferContext.getOfferContext();
if (offerContext == null || offerContext.executePromotionCalculation) {
PromotableOrder promotableOrder = promotableItemFactory.createPromotableOrder(order, true);
List<Offer> possibleFGOffers = new ArrayList<Offer>();
for (Offer offer : offers) {
if (offer.getType().getType().equals(OfferType.FULFILLMENT_GROUP.getType())) {
possibleFGOffers.add(offer);
}
}
List<Offer> filteredOffers = orderOfferProcessor.filterOffers(possibleFGOffers, order.getCustomer());
List<PromotableCandidateFulfillmentGroupOffer> qualifiedFGOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
for (Offer offer : filteredOffers) {
fulfillmentGroupOfferProcessor.filterFulfillmentGroupLevelOffer(promotableOrder, qualifiedFGOffers, offer);
}
if (!qualifiedFGOffers.isEmpty()) {
fulfillmentGroupOfferProcessor.applyAllFulfillmentGroupOffers(qualifiedFGOffers, promotableOrder);
fulfillmentGroupOfferProcessor.calculateFulfillmentGroupTotal(promotableOrder);
orderOfferProcessor.synchronizeAdjustmentsAndPrices(promotableOrder);
}
return orderService.save(order, false);
}
return order;
}
Aggregations