use of org.broadleafcommerce.core.order.domain.OrderMultishipOption in project BroadleafCommerce by BroadleafCommerce.
the class OfferServiceTest method testApplyOffersToOrder_Order.
public void testApplyOffersToOrder_Order() throws Exception {
final ThreadLocal<Order> myOrder = new ThreadLocal<>();
EasyMock.expect(offerDaoMock.createOrderItemPriceDetailAdjustment()).andAnswer(OfferDataItemProvider.getCreateOrderItemPriceDetailAdjustmentAnswer()).anyTimes();
CandidateOrderOfferAnswer candidateOrderOfferAnswer = new CandidateOrderOfferAnswer();
OrderAdjustmentAnswer orderAdjustmentAnswer = new OrderAdjustmentAnswer();
EasyMock.expect(offerDaoMock.createOrderAdjustment()).andAnswer(orderAdjustmentAnswer).atLeastOnce();
OrderItemPriceDetailAnswer orderItemPriceDetailAnswer = new OrderItemPriceDetailAnswer();
EasyMock.expect(orderItemDaoMock.createOrderItemPriceDetail()).andAnswer(orderItemPriceDetailAnswer).atLeastOnce();
OrderItemQualifierAnswer orderItemQualifierAnswer = new OrderItemQualifierAnswer();
EasyMock.expect(orderItemDaoMock.createOrderItemQualifier()).andAnswer(orderItemQualifierAnswer).atLeastOnce();
CandidateItemOfferAnswer candidateItemOfferAnswer = new CandidateItemOfferAnswer();
OrderItemAdjustmentAnswer orderItemAdjustmentAnswer = new OrderItemAdjustmentAnswer();
EasyMock.expect(fgServiceMock.addItemToFulfillmentGroup(EasyMock.isA(FulfillmentGroupItemRequest.class), EasyMock.eq(false))).andAnswer(OfferDataItemProvider.getAddItemToFulfillmentGroupAnswer()).anyTimes();
EasyMock.expect(orderServiceMock.removeItem(EasyMock.isA(Long.class), EasyMock.isA(Long.class), EasyMock.eq(false))).andAnswer(OfferDataItemProvider.getRemoveItemFromOrderAnswer()).anyTimes();
EasyMock.expect(orderServiceMock.save(EasyMock.isA(Order.class), EasyMock.isA(Boolean.class))).andAnswer(OfferDataItemProvider.getSaveOrderAnswer()).anyTimes();
EasyMock.expect(orderServiceMock.findOrderById(EasyMock.isA(Long.class))).andAnswer(new IAnswer<Order>() {
@Override
public Order answer() throws Throwable {
return myOrder.get();
}
}).anyTimes();
EasyMock.expect(orderServiceMock.getAutomaticallyMergeLikeItems()).andReturn(true).anyTimes();
EasyMock.expect(orderItemServiceMock.saveOrderItem(EasyMock.isA(OrderItem.class))).andAnswer(OfferDataItemProvider.getSaveOrderItemAnswer()).anyTimes();
EasyMock.expect(fgItemDaoMock.save(EasyMock.isA(FulfillmentGroupItem.class))).andAnswer(OfferDataItemProvider.getSaveFulfillmentGroupItemAnswer()).anyTimes();
EasyMock.expect(multishipOptionServiceMock.findOrderMultishipOptions(EasyMock.isA(Long.class))).andAnswer(new IAnswer<List<OrderMultishipOption>>() {
@Override
public List<OrderMultishipOption> answer() throws Throwable {
return new ArrayList<>();
}
}).anyTimes();
multishipOptionServiceMock.deleteAllOrderMultishipOptions(EasyMock.isA(Order.class));
EasyMock.expectLastCall().anyTimes();
EasyMock.expect(fgServiceMock.collapseToOneShippableFulfillmentGroup(EasyMock.isA(Order.class), EasyMock.eq(false))).andAnswer(OfferDataItemProvider.getSameOrderAnswer()).anyTimes();
EasyMock.expect(fgItemDaoMock.create()).andAnswer(OfferDataItemProvider.getCreateFulfillmentGroupItemAnswer()).anyTimes();
fgItemDaoMock.delete(EasyMock.isA(FulfillmentGroupItem.class));
EasyMock.expectLastCall().anyTimes();
EasyMock.expect(offerTimeZoneProcessorMock.getTimeZone(EasyMock.isA(OfferImpl.class))).andReturn(TimeZone.getTimeZone("CST")).anyTimes();
replay();
Order order = dataProvider.createBasicOrder();
myOrder.set(order);
List<Offer> offers = dataProvider.createOrderBasedOffer("order.subTotal.getAmount()>126", OfferDiscountType.PERCENT_OFF);
offerService.applyAndSaveOffersToOrder(offers, order);
int adjustmentCount = order.getOrderAdjustments().size();
assertTrue(adjustmentCount == 1);
assertTrue(order.getSubTotal().subtract(order.getOrderAdjustmentsValue()).equals(new Money(116.95D)));
order = dataProvider.createBasicOrder();
myOrder.set(order);
offers = dataProvider.createOrderBasedOffer("order.subTotal.getAmount()>126", OfferDiscountType.PERCENT_OFF);
List<Offer> offers2 = dataProvider.createItemBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test1\"), MVEL.eval(\"toUpperCase()\",\"test2\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))", "([MVEL.eval(\"toUpperCase()\",\"test1\"), MVEL.eval(\"toUpperCase()\",\"test2\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))");
offers.addAll(offers2);
offerService.applyAndSaveOffersToOrder(offers, order);
// with the item offers in play, the subtotal restriction for the order offer is no longer valid
adjustmentCount = countItemAdjustments(order);
int qualifierCount = countItemQualifiers(order);
assertTrue(adjustmentCount == 2);
assertTrue(qualifierCount == 2);
adjustmentCount = order.getOrderAdjustments().size();
assertTrue(adjustmentCount == 0);
// assertTrue(order.getSubTotal().equals(new Money(124.95D)));
order = dataProvider.createBasicOrder();
myOrder.set(order);
OfferRule orderRule = new OfferRuleImpl();
// orderRule.setMatchRule("order.subTotal.getAmount()>124");
orderRule.setMatchRule("order.subTotal.getAmount()>100");
Offer offer = offers.get(0);
OfferOfferRuleXref ruleXref = new OfferOfferRuleXrefImpl(offer, orderRule, OfferRuleType.ORDER.getType());
offer.getOfferMatchRulesXref().put(OfferRuleType.ORDER.getType(), ruleXref);
offerService.applyAndSaveOffersToOrder(offers, order);
// now that the order restriction has been lessened, even with the item level discounts applied,
// the order offer still qualifies
adjustmentCount = countItemAdjustments(order);
qualifierCount = countItemQualifiers(order);
assertTrue(adjustmentCount == 2);
assertTrue(qualifierCount == 2);
adjustmentCount = order.getOrderAdjustments().size();
assertTrue(adjustmentCount == 1);
assertTrue(order.getSubTotal().subtract(order.getOrderAdjustmentsValue()).equals(new Money(112.45D)));
assertTrue(order.getSubTotal().equals(new Money(124.95D)));
order = dataProvider.createBasicPromotableOrder().getOrder();
myOrder.set(order);
// offers.get(0).setCombinableWithOtherOffers(false);
List<Offer> offers3 = dataProvider.createOrderBasedOffer("order.subTotal.getAmount()>20", OfferDiscountType.AMOUNT_OFF);
offers.addAll(offers3);
offerService.applyAndSaveOffersToOrder(offers, order);
adjustmentCount = order.getOrderAdjustments().size();
assertTrue(adjustmentCount == 2);
order = dataProvider.createBasicPromotableOrder().getOrder();
myOrder.set(order);
offers.get(0).setCombinableWithOtherOffers(false);
offerService.applyAndSaveOffersToOrder(offers, order);
// there is a non combinable order offer now
adjustmentCount = countItemAdjustments(order);
qualifierCount = countItemQualifiers(order);
assertTrue(adjustmentCount == 2);
assertTrue(qualifierCount == 2);
adjustmentCount = order.getOrderAdjustments().size();
assertTrue(adjustmentCount == 1);
assertTrue(order.getSubTotal().subtract(order.getOrderAdjustmentsValue()).equals(new Money(112.45D)));
assertTrue(order.getSubTotal().equals(new Money(124.95D)));
order = dataProvider.createBasicPromotableOrder().getOrder();
myOrder.set(order);
offers.get(0).setTotalitarianOffer(true);
offerService.applyAndSaveOffersToOrder(offers, order);
// there is a totalitarian order offer now - it is better than the item offers - the item offers are removed
adjustmentCount = countItemAdjustments(order);
qualifierCount = countItemQualifiers(order);
assertTrue(adjustmentCount == 0);
assertTrue(qualifierCount == 0);
adjustmentCount = order.getOrderAdjustments().size();
assertTrue(adjustmentCount == 1);
assertTrue(order.getSubTotal().subtract(order.getOrderAdjustmentsValue()).equals(new Money(116.95D)));
assertTrue(order.getSubTotal().equals(new Money(129.95D)));
order = dataProvider.createBasicPromotableOrder().getOrder();
myOrder.set(order);
offers.get(0).setValue(new BigDecimal(".05"));
offers.get(2).setValue(new BigDecimal(".01"));
offers.get(2).setDiscountType(OfferDiscountType.PERCENT_OFF);
offerService.applyAndSaveOffersToOrder(offers, order);
// even though the first order offer is totalitarian, it is worth less than the order item offer, so it is removed.
// the other order offer is still valid, however, and is included.
adjustmentCount = countItemAdjustments(order);
assertTrue(adjustmentCount == 2);
adjustmentCount = order.getOrderAdjustments().size();
assertTrue(adjustmentCount == 1);
assertTrue(order.getSubTotal().subtract(order.getOrderAdjustmentsValue()).equals(new Money(124.94D)));
assertTrue(order.getSubTotal().equals(new Money(124.95D)));
verify();
}
use of org.broadleafcommerce.core.order.domain.OrderMultishipOption in project BroadleafCommerce by BroadleafCommerce.
the class FulfillmentGroupOfferProcessorTest method testApplyAllFulfillmentGroupOffersWithOrderItemOffers.
public void testApplyAllFulfillmentGroupOffersWithOrderItemOffers() throws Exception {
final ThreadLocal<Order> myOrder = new ThreadLocal<Order>();
EasyMock.expect(orderItemDaoMock.createOrderItemPriceDetail()).andAnswer(OfferDataItemProvider.getCreateOrderItemPriceDetailAnswer()).anyTimes();
EasyMock.expect(orderItemDaoMock.createOrderItemQualifier()).andAnswer(OfferDataItemProvider.getCreateOrderItemQualifierAnswer()).atLeastOnce();
EasyMock.expect(fgServiceMock.addItemToFulfillmentGroup(EasyMock.isA(FulfillmentGroupItemRequest.class), EasyMock.eq(false))).andAnswer(OfferDataItemProvider.getAddItemToFulfillmentGroupAnswer()).anyTimes();
EasyMock.expect(orderServiceMock.removeItem(EasyMock.isA(Long.class), EasyMock.isA(Long.class), EasyMock.eq(false))).andAnswer(OfferDataItemProvider.getRemoveItemFromOrderAnswer()).anyTimes();
EasyMock.expect(orderServiceMock.save(EasyMock.isA(Order.class), EasyMock.isA(Boolean.class))).andAnswer(OfferDataItemProvider.getSaveOrderAnswer()).anyTimes();
EasyMock.expect(offerServiceUtilitiesMock.orderMeetsQualifyingSubtotalRequirements(EasyMock.isA(PromotableOrder.class), EasyMock.isA(Offer.class), EasyMock.isA(HashMap.class))).andReturn(true).anyTimes();
EasyMock.expect(offerServiceUtilitiesMock.orderMeetsSubtotalRequirements(EasyMock.isA(PromotableOrder.class), EasyMock.isA(Offer.class))).andReturn(true).anyTimes();
EasyMock.expect(orderServiceMock.getAutomaticallyMergeLikeItems()).andReturn(true).anyTimes();
EasyMock.expect(orderItemServiceMock.saveOrderItem(EasyMock.isA(OrderItem.class))).andAnswer(OfferDataItemProvider.getSaveOrderItemAnswer()).anyTimes();
EasyMock.expect(fgItemDaoMock.save(EasyMock.isA(FulfillmentGroupItem.class))).andAnswer(OfferDataItemProvider.getSaveFulfillmentGroupItemAnswer()).anyTimes();
EasyMock.expect(offerDaoMock.createOrderItemPriceDetailAdjustment()).andAnswer(OfferDataItemProvider.getCreateOrderItemPriceDetailAdjustmentAnswer()).anyTimes();
EasyMock.expect(offerDaoMock.createFulfillmentGroupAdjustment()).andAnswer(OfferDataItemProvider.getCreateFulfillmentGroupAdjustmentAnswer()).anyTimes();
EasyMock.expect(orderServiceMock.findOrderById(EasyMock.isA(Long.class))).andAnswer(new IAnswer<Order>() {
@Override
public Order answer() throws Throwable {
return myOrder.get();
}
}).anyTimes();
EasyMock.expect(multishipOptionServiceMock.findOrderMultishipOptions(EasyMock.isA(Long.class))).andAnswer(new IAnswer<List<OrderMultishipOption>>() {
@Override
public List<OrderMultishipOption> answer() throws Throwable {
List<OrderMultishipOption> options = new ArrayList<OrderMultishipOption>();
PromotableOrder order = dataProvider.createBasicPromotableOrder();
for (FulfillmentGroup fg : order.getOrder().getFulfillmentGroups()) {
Address address = fg.getAddress();
for (FulfillmentGroupItem fgItem : fg.getFulfillmentGroupItems()) {
for (int j = 0; j < fgItem.getQuantity(); j++) {
OrderMultishipOption option = new OrderMultishipOptionImpl();
option.setOrder(order.getOrder());
option.setAddress(address);
option.setOrderItem(fgItem.getOrderItem());
options.add(option);
}
}
}
return options;
}
}).anyTimes();
multishipOptionServiceMock.deleteAllOrderMultishipOptions(EasyMock.isA(Order.class));
EasyMock.expectLastCall().anyTimes();
EasyMock.expect(fgServiceMock.collapseToOneShippableFulfillmentGroup(EasyMock.isA(Order.class), EasyMock.eq(false))).andAnswer(new IAnswer<Order>() {
@Override
public Order answer() throws Throwable {
Order order = (Order) EasyMock.getCurrentArguments()[0];
order.getFulfillmentGroups().get(0).getFulfillmentGroupItems().addAll(order.getFulfillmentGroups().get(1).getFulfillmentGroupItems());
order.getFulfillmentGroups().remove(order.getFulfillmentGroups().get(1));
return order;
}
}).anyTimes();
EasyMock.expect(fgItemDaoMock.create()).andAnswer(OfferDataItemProvider.getCreateFulfillmentGroupItemAnswer()).anyTimes();
fgItemDaoMock.delete(EasyMock.isA(FulfillmentGroupItem.class));
EasyMock.expectLastCall().anyTimes();
EasyMock.expect(offerTimeZoneProcessorMock.getTimeZone(EasyMock.isA(OfferImpl.class))).andReturn(TimeZone.getTimeZone("CST")).anyTimes();
replay();
PromotableOrder promotableOrder = dataProvider.createBasicPromotableOrder();
Order order = promotableOrder.getOrder();
myOrder.set(promotableOrder.getOrder());
List<PromotableCandidateFulfillmentGroupOffer> qualifiedOffers = new ArrayList<PromotableCandidateFulfillmentGroupOffer>();
List<Offer> offers = dataProvider.createFGBasedOffer("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF);
offers.addAll(dataProvider.createFGBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", "fulfillmentGroup.address.postalCode==75244", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test1\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))"));
offers.get(1).setName("secondOffer");
offers.addAll(dataProvider.createItemBasedOfferWithItemCriteria("order.subTotal.getAmount()>20", OfferDiscountType.PERCENT_OFF, "([MVEL.eval(\"toUpperCase()\",\"test1\"), MVEL.eval(\"toUpperCase()\",\"test2\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))", "([MVEL.eval(\"toUpperCase()\",\"test1\"), MVEL.eval(\"toUpperCase()\",\"test2\")] contains MVEL.eval(\"toUpperCase()\", discreteOrderItem.category.name))"));
offerService.applyAndSaveOffersToOrder(offers, promotableOrder.getOrder());
offers.get(0).setTotalitarianOffer(true);
offerService.applyAndSaveFulfillmentGroupOffersToOrder(offers, promotableOrder.getOrder());
int fgAdjustmentCount = 0;
for (FulfillmentGroup fg : order.getFulfillmentGroups()) {
fgAdjustmentCount += fg.getFulfillmentGroupAdjustments().size();
}
// The totalitarian offer that applies to both fg's is not combinable and is a worse offer than the order item offers
// - it is therefore ignored
// However, the second combinable fg offer is allowed to be applied.
assertTrue(fgAdjustmentCount == 1);
promotableOrder = dataProvider.createBasicPromotableOrder();
myOrder.set(promotableOrder.getOrder());
offers.get(2).setValue(new BigDecimal("1"));
offerService.applyAndSaveOffersToOrder(offers, promotableOrder.getOrder());
offerService.applyAndSaveFulfillmentGroupOffersToOrder(offers, promotableOrder.getOrder());
fgAdjustmentCount = 0;
order = promotableOrder.getOrder();
for (FulfillmentGroup fg : order.getFulfillmentGroups()) {
fgAdjustmentCount += fg.getFulfillmentGroupAdjustments().size();
}
// The totalitarian fg offer is now a better deal than the order item offers, therefore the totalitarian fg offer is applied
// and the order item offers are removed
assertTrue(fgAdjustmentCount == 2);
int itemAdjustmentCount = 0;
for (OrderItem item : order.getOrderItems()) {
for (OrderItemPriceDetail detail : item.getOrderItemPriceDetails()) {
itemAdjustmentCount += detail.getOrderItemPriceDetailAdjustments().size();
}
}
// Confirm that the order item offers are removed
assertTrue(itemAdjustmentCount == 0);
verify();
}
use of org.broadleafcommerce.core.order.domain.OrderMultishipOption in project BroadleafCommerce by BroadleafCommerce.
the class FulfillmentGroupServiceImpl method matchFulfillmentGroupsToMultishipOptions.
@Override
@Transactional("blTransactionManager")
public Order matchFulfillmentGroupsToMultishipOptions(Order order, boolean priceOrder) throws PricingException {
List<OrderMultishipOption> multishipOptions = orderMultishipOptionService.findOrderMultishipOptions(order.getId());
// Build map of fulfillmentGroupItemId --> FulfillmentGroupItem.quantity
// Also build map of addressId:fulfillmentOptionId --> FulfillmentGroup
Map<Long, Integer> fgItemQuantityMap = new HashMap<Long, Integer>();
Map<String, FulfillmentGroup> multishipGroups = new HashMap<String, FulfillmentGroup>();
for (FulfillmentGroup fg : order.getFulfillmentGroups()) {
if (!isShippable(fg.getType())) {
continue;
}
String key = getKey(fg.getAddress(), fg.getFulfillmentOption(), fg.getType());
multishipGroups.put(key, fg);
for (FulfillmentGroupItem fgi : fg.getFulfillmentGroupItems()) {
fgItemQuantityMap.put(fgi.getId(), fgi.getQuantity());
}
}
for (OrderMultishipOption option : multishipOptions) {
String key = getKey(option.getAddress(), option.getFulfillmentOption(), ((DiscreteOrderItem) option.getOrderItem()).getSku().getFulfillmentType());
FulfillmentGroup fg = multishipGroups.get(key);
// Get or create a fulfillment group that matches this OrderMultishipOption destination
if (fg == null) {
FulfillmentGroupRequest fgr = new FulfillmentGroupRequest();
fgr.setOrder(order);
if (option.getAddress() != null) {
fgr.setAddress(option.getAddress());
}
if (option.getFulfillmentOption() != null) {
fgr.setOption(option.getFulfillmentOption());
}
fgr.setFulfillmentType(((DiscreteOrderItem) option.getOrderItem()).getSku().getFulfillmentType());
fg = addFulfillmentGroupToOrder(fgr, false);
fg = save(fg);
order.getFulfillmentGroups().add(fg);
}
// See if there is a fulfillment group item that matches this OrderMultishipOption
// OrderItem request
FulfillmentGroupItem fulfillmentGroupItem = null;
for (FulfillmentGroupItem fgi : fg.getFulfillmentGroupItems()) {
if (fgi.getOrderItem().getId().equals(option.getOrderItem().getId())) {
fulfillmentGroupItem = fgi;
}
}
// If there is no matching fulfillment group item, create a new one with quantity 1
if (fulfillmentGroupItem == null) {
fulfillmentGroupItem = fulfillmentGroupItemDao.create();
fulfillmentGroupItem.setFulfillmentGroup(fg);
fulfillmentGroupItem.setOrderItem(option.getOrderItem());
fulfillmentGroupItem.setQuantity(1);
fulfillmentGroupItem = fulfillmentGroupItemDao.save(fulfillmentGroupItem);
fg.getFulfillmentGroupItems().add(fulfillmentGroupItem);
} else {
// (fulfillmentGroupItem.getId() == null)
if (fulfillmentGroupItem.getId() != null) {
Integer qty = fgItemQuantityMap.get(fulfillmentGroupItem.getId());
if (qty == null || qty == 0) {
fulfillmentGroupItem.setQuantity(fulfillmentGroupItem.getQuantity() + 1);
} else {
qty -= 1;
fgItemQuantityMap.put(fulfillmentGroupItem.getId(), qty);
}
} else {
fulfillmentGroupItem.setQuantity(fulfillmentGroupItem.getQuantity() + 1);
}
}
multishipGroups.put(key, fg);
}
// Furthermore, delete the empty fulfillment groups.
for (Entry<Long, Integer> entry : fgItemQuantityMap.entrySet()) {
if (entry.getValue() > 0) {
FulfillmentGroupItem fgi = fulfillmentGroupItemDao.readFulfillmentGroupItemById(entry.getKey());
if (fgi.getQuantity() == entry.getValue()) {
FulfillmentGroup fg = fgi.getFulfillmentGroup();
fg.getFulfillmentGroupItems().remove(fgi);
fulfillmentGroupItemDao.delete(fgi);
if (fg.getFulfillmentGroupItems().size() == 0) {
order.getFulfillmentGroups().remove(fg);
fulfillmentGroupDao.delete(fg);
}
} else {
fgi.setQuantity(fgi.getQuantity() - entry.getValue());
fulfillmentGroupItemDao.save(fgi);
}
}
}
return orderService.save(order, priceOrder);
}
use of org.broadleafcommerce.core.order.domain.OrderMultishipOption in project BroadleafCommerce by BroadleafCommerce.
the class OrderMultishipOptionServiceImpl method getOrderMultishipOptionsFromDTOs.
@Override
public List<OrderMultishipOption> getOrderMultishipOptionsFromDTOs(Order order, List<OrderMultishipOptionDTO> optionDtos) {
List<OrderMultishipOption> orderMultishipOptions = new ArrayList<OrderMultishipOption>();
for (OrderMultishipOptionDTO optionDto : optionDtos) {
OrderMultishipOption option = new OrderMultishipOptionImpl();
if (optionDto.getAddressId() != null) {
option.setAddress(addressService.readAddressById(optionDto.getAddressId()));
}
if (optionDto.getFulfillmentOptionId() != null) {
option.setFulfillmentOption(fulfillmentOptionService.readFulfillmentOptionById(optionDto.getFulfillmentOptionId()));
}
option.setId(optionDto.getId());
option.setOrder(order);
option.setOrderItem(orderItemService.readOrderItemById(optionDto.getOrderItemId()));
orderMultishipOptions.add(option);
}
return orderMultishipOptions;
}
Aggregations