protected void getOiFgiMap(Order order, Map<OrderItem, List<FulfillmentGroupItem>> oiFgiMap, OrderItem oi) { List<FulfillmentGroupItem> fgis = new ArrayList<>(); for (FulfillmentGroup fg : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fgi : fg.getFulfillmentGroupItems()) { if (fgi.getOrderItem().equals(oi)) { fgis.add(fgi); } } } oiFgiMap.put(oi, fgis); }
@Override public List<FulfillmentGroupItem> getFulfillmentGroupItemsForOrderItem(Order order, OrderItem orderItem) { List<FulfillmentGroupItem> fgis = new ArrayList<FulfillmentGroupItem>(); List<FulfillmentGroup> fulfillmentGroups = order.getFulfillmentGroups(); for (FulfillmentGroup fulfillmentGroup : fulfillmentGroups) { for (FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) { if (fulfillmentGroupItem.getOrderItem().equals(orderItem)) { fgis.add(fulfillmentGroupItem); } else if (orderItem instanceof BundleOrderItem) { BundleOrderItem bundleOrderItem = (BundleOrderItem) orderItem; for (DiscreteOrderItem discreteOrderItem : bundleOrderItem.getDiscreteOrderItems()) { if (fulfillmentGroupItem.getOrderItem().equals(discreteOrderItem)){ fgis.add(fulfillmentGroupItem); break; } } } } } return fgis; }
protected void removeOrderItemFromFullfillmentGroup(Order order, OrderItem orderItem) { List<FulfillmentGroup> fulfillmentGroups = order.getFulfillmentGroups(); for (FulfillmentGroup fulfillmentGroup : fulfillmentGroups) { Iterator<FulfillmentGroupItem> itr = fulfillmentGroup.getFulfillmentGroupItems().iterator(); while (itr.hasNext()) { FulfillmentGroupItem fulfillmentGroupItem = itr.next(); if (fulfillmentGroupItem.getOrderItem().equals(orderItem)) { itr.remove(); fulfillmentGroupItemDao.delete(fulfillmentGroupItem); } else if (orderItem instanceof BundleOrderItem) { BundleOrderItem bundleOrderItem = (BundleOrderItem) orderItem; for (DiscreteOrderItem discreteOrderItem : bundleOrderItem.getDiscreteOrderItems()) { if (fulfillmentGroupItem.getOrderItem().equals(discreteOrderItem)){ itr.remove(); fulfillmentGroupItemDao.delete(fulfillmentGroupItem); break; } } } } } }
protected String getItemJs(Order order, String trackerPrefix) { StringBuffer sb = new StringBuffer(); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) { OrderItem orderItem = fulfillmentGroupItem.getOrderItem(); if (orderItem instanceof DiscreteOrderItem) { if (SkuAccessor.class.isAssignableFrom(orderItem.getClass())) { Sku sku = ((SkuAccessor) orderItem).getSku(); sb.append("ga('" + trackerPrefix + "ecommerce:addItem', {"); sb.append("'id': '" + order.getOrderNumber() + "'"); sb.append(",'name': '" + sku.getName() + "'"); sb.append(",'sku': '" + sku.getId() + "'"); sb.append(",'category': '" + getVariation(orderItem) + "'"); sb.append(",'price': '" + orderItem.getAveragePrice() + "'"); sb.append(",'quantity': '" + orderItem.getQuantity() + "'"); sb.append("});"); } } } } return sb.toString(); }
@Override public void removeAssociations() { if (getFulfillmentGroup() != null) { getFulfillmentGroup().getFulfillmentGroupItems().remove(this); } setFulfillmentGroup(null); setOrderItem(null); }
@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();
/** * Returns the total price for all fulfillment items. * @param order * @return */ protected Money calculateTotalPriceForAllFulfillmentItems(Order order) { Money totalAllItemsAmount = new Money(order.getCurrency()); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fgItem : fulfillmentGroup.getFulfillmentGroupItems()) { totalAllItemsAmount = totalAllItemsAmount.add(fgItem.getTotalItemAmount()); } } return totalAllItemsAmount; }
@Override public FulfillmentGroup calculateCostForFulfillmentGroup(FulfillmentGroup fulfillmentGroup) throws FulfillmentPriceException { if (fulfillmentGroup.getFulfillmentGroupItems().size() == 0) { LOG.warn("fulfillment group (" + fulfillmentGroup.getId() + ") does not contain any fulfillment group items. Unable to price banded shipping"); fulfillmentGroup.setShippingPrice(Money.ZERO); fulfillmentGroup.setSaleShippingPrice(Money.ZERO); fulfillmentGroup.setRetailShippingPrice(Money.ZERO); return fulfillmentGroup; } if (canCalculateCostForFulfillmentGroup(fulfillmentGroup, fulfillmentGroup.getFulfillmentOption())) { //In this case, the estimation logic is the same as calculation logic. Call the estimation service to get the prices. HashSet<FulfillmentOption> options = new HashSet<FulfillmentOption>(); options.add(fulfillmentGroup.getFulfillmentOption()); FulfillmentEstimationResponse response = estimateCostForFulfillmentGroup(fulfillmentGroup, options); fulfillmentGroup.setSaleShippingPrice(response.getFulfillmentOptionPrices().get(fulfillmentGroup.getFulfillmentOption())); fulfillmentGroup.setRetailShippingPrice(response.getFulfillmentOptionPrices().get(fulfillmentGroup.getFulfillmentOption())); fulfillmentGroup.setShippingPrice(response.getFulfillmentOptionPrices().get(fulfillmentGroup.getFulfillmentOption())); return fulfillmentGroup; } throw new FulfillmentPriceException("An unsupported FulfillmentOption was passed to the calculateCostForFulfillmentGroup method"); }
@Override public Order answer() throws Throwable { Long orderId = (Long) EasyMock.getCurrentArguments()[0]; Order order = orders.get(orderId); Iterator<OrderItem> orderItemItr = order.getOrderItems().listIterator(); while (orderItemItr.hasNext()) { OrderItem item = orderItemItr.next(); if (item.getId().equals(EasyMock.getCurrentArguments()[1])) { orderItemItr.remove(); } } for (FulfillmentGroup fg : order.getFulfillmentGroups()) { Iterator<FulfillmentGroupItem> itr = fg.getFulfillmentGroupItems().iterator(); while (itr.hasNext()) { if (itr.next().getOrderItem().getId().equals(EasyMock.getCurrentArguments()[1])) { itr.remove(); } } } return order; } };
/** * Distributes the order adjustments (if any) to the individual fulfillment group items. * @param order * @param totalAllItems * @return */ protected Money distributeOrderSavingsToItems(Order order, BigDecimal totalAllItems) { Money returnAmount = new Money(order.getCurrency()); BigDecimal orderAdjAmt = order.getOrderAdjustmentsValue().getAmount(); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fgItem : fulfillmentGroup.getFulfillmentGroupItems()) { BigDecimal fgItemAmount = fgItem.getTotalItemAmount().getAmount(); BigDecimal proratedAdjAmt = totalAllItems.compareTo(BigDecimal.ZERO) == 0 ? totalAllItems : orderAdjAmt.multiply(fgItemAmount).divide(totalAllItems, RoundingMode.FLOOR); fgItem.setProratedOrderAdjustmentAmount(new Money(proratedAdjAmt, order.getCurrency())); returnAmount = returnAmount.add(fgItem.getProratedOrderAdjustmentAmount()); } } return returnAmount; }
/** * It is possible due to rounding that the order adjustments do not match the * total. This method fixes by adding or removing the pennies. * @param order * @param partialOrderItemMap */ protected void fixOrderSavingsRoundingIssues(Order order, Money totalOrderAdjustmentDistributed) { if (!order.getHasOrderAdjustments()) { return; } Money orderAdjustmentTotal = order.getOrderAdjustmentsValue(); Money amountDiff = orderAdjustmentTotal.subtract(totalOrderAdjustmentDistributed); if (!(amountDiff.getAmount().compareTo(BigDecimal.ZERO) == 0)) { long numApplicationsNeeded = countNumberOfUnits(amountDiff); Money unitAmount = getUnitAmount(amountDiff); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fgItem : fulfillmentGroup.getFulfillmentGroupItems()) { numApplicationsNeeded = numApplicationsNeeded - applyDifferenceToProratedAdj(fgItem, numApplicationsNeeded, unitAmount); if (numApplicationsNeeded == 0) { break; } } } } }
@Override public ProcessContext<CartOperationRequest> execute(ProcessContext<CartOperationRequest> context) throws Exception { CartOperationRequest request = context.getSeedData(); Long orderItemId = request.getItemRequest().getOrderItemId(); Integer orderItemQuantityDelta = request.getOrderItemQuantityDelta(); if (orderItemQuantityDelta < 0) { int numToDelete = -1 * orderItemQuantityDelta; //find the qty in the default fg OrderItem orderItem = request.getOrderItem(); int qty = 0; if (!CollectionUtils.isEmpty(orderItem.getOrder().getFulfillmentGroups())) { FulfillmentGroup fg = orderItem.getOrder().getFulfillmentGroups().get(0); if (fg.getAddress() == null && fg.getFulfillmentOption() == null) { for (FulfillmentGroupItem fgItem : fg.getFulfillmentGroupItems()) { if (fgItem.getOrderItem().getId().equals(orderItemId)) { qty += fgItem.getQuantity(); } } } } if (numToDelete >= qty) { request.getMultishipOptionsToDelete().add(new Long[] { orderItemId, (long) (numToDelete - qty) }); } } return context; }
@Test(groups = { "createFulfillmentGroupItem" }, dataProvider = "basicDiscreteOrderItem", dataProviderClass = OrderItemDataProvider.class, dependsOnGroups = { "createOrder", "createSku", "createItemFulfillmentGroup" }) @Rollback(false) @Transactional public void createFulfillmentGroupItem(DiscreteOrderItem orderItem) throws PricingException { Sku si = skuDao.readFirstSku(); orderItem.setSku(si); orderItem = (DiscreteOrderItem) orderItemDao.save(orderItem); orderItem.setOrder(salesOrder); salesOrder.addOrderItem(orderItem); orderDao.save(salesOrder); FulfillmentGroupItemRequest fulfillmentGroupItemRequest = new FulfillmentGroupItemRequest(); fulfillmentGroupItemRequest.setOrderItem(orderItem); fulfillmentGroupItemRequest.setFulfillmentGroup(fulfillmentGroup); fulfillmentGroupService.addItemToFulfillmentGroup(fulfillmentGroupItemRequest, true); FulfillmentGroupItem fgi = fulfillmentGroup.getFulfillmentGroupItems().get(fulfillmentGroup.getFulfillmentGroupItems().size()-1); assert fgi.getId() != null; fulfillmentGroupItemId = fgi.getId(); }
@Override public ProcessContext<Order> execute(ProcessContext<Order> context) throws Exception { Order order = context.getSeedData(); for(FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { Money merchandiseTotal = BroadleafCurrencyUtils.getMoney(BigDecimal.ZERO, fulfillmentGroup.getOrder().getCurrency()); for(FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) { OrderItem item = fulfillmentGroupItem.getOrderItem(); merchandiseTotal = merchandiseTotal.add(item.getTotalPrice()); } fulfillmentGroup.setMerchandiseTotal(merchandiseTotal); } context.setSeedData(order); return context; }
@Override public FulfillmentGroup answer() throws Throwable { FulfillmentGroupItemRequest fgItemRequest = (FulfillmentGroupItemRequest) EasyMock.getCurrentArguments()[0]; FulfillmentGroup fg = fgItemRequest.getFulfillmentGroup(); FulfillmentGroupItem fgItem = new FulfillmentGroupItemImpl(); fgItem.setOrderItem(fgItemRequest.getOrderItem()); fgItem.setQuantity(fgItemRequest.getQuantity()); fg.getFulfillmentGroupItems().add(fgItem); return fg; } };
protected Money sumProratedOfferAdjustments(Order order) { Money returnVal = new Money(order.getCurrency()); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) { if (fulfillmentGroupItem.getProratedOrderAdjustmentAmount() != null) { returnVal = returnVal.add(fulfillmentGroupItem.getProratedOrderAdjustmentAmount()); } } } return returnVal; }
@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();
/** * Returns the total price for all fulfillment items. * @param order * @return */ protected void updateTaxableAmountsOnItems(Order order) { Money zero = new Money(order.getCurrency()); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fgItem : fulfillmentGroup.getFulfillmentGroupItems()) { if (fgItem.getOrderItem().isTaxable()) { Money proratedOrderAdjAmt = fgItem.getProratedOrderAdjustmentAmount(); if (proratedOrderAdjAmt != null) { fgItem.setTotalItemTaxableAmount(fgItem.getTotalItemAmount().subtract(proratedOrderAdjAmt)); } else { fgItem.setTotalItemTaxableAmount(fgItem.getTotalItemAmount()); } } else { fgItem.setTotalItemTaxableAmount(zero); } } } }
public void testDistributeOneDollarAcrossFiveItems() throws Exception { Order order = dataProvider.createBasicOrder(); OrderAdjustment adjustment = new OrderAdjustmentImpl(); adjustment.setValue(new Money(new BigDecimal("1"), order.getCurrency())); adjustment.setOrder(order); order.getOrderAdjustments().add(adjustment); ProcessContext<Order> context = new DefaultProcessContextImpl<Order>(); context.setSeedData(order); fulfillmentItemPricingActivity.execute(context); Money adj1 = new Money(".31"); Money adj2 = new Money(".69"); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) { if (fulfillmentGroupItem.getSalePrice().equals(new Money("19.99"))) { assertTrue(fulfillmentGroupItem.getProratedOrderAdjustmentAmount().equals(adj1)); } else { assertTrue(fulfillmentGroupItem.getProratedOrderAdjustmentAmount().equals(adj2)); } } } }
public void testDistributeOneDollarAcrossFiveEqualItems() throws Exception { Order order = dataProvider.createBasicOrder(); Money subTotal = new Money(order.getCurrency()); for (OrderItem orderItem : order.getOrderItems()) { orderItem.setSalePrice(new Money(10D)); orderItem.getOrderItemPriceDetails().clear(); subTotal = subTotal.add(orderItem.getTotalPrice()); } OrderAdjustment adjustment = new OrderAdjustmentImpl(); adjustment.setValue(new Money(new BigDecimal("1"), order.getCurrency())); order.getOrderAdjustments().add(adjustment); adjustment.setOrder(order); order.setSubTotal(subTotal); ProcessContext<Order> context = new DefaultProcessContextImpl<Order>(); context.setSeedData(order); fulfillmentItemPricingActivity.execute(context); // Each item is equally priced, so the adjustment should be .20 per item. Money proratedAdjustment = new Money(".20"); for (FulfillmentGroup fulfillmentGroup : order.getFulfillmentGroups()) { for (FulfillmentGroupItem fulfillmentGroupItem : fulfillmentGroup.getFulfillmentGroupItems()) { assertTrue(fulfillmentGroupItem.getProratedOrderAdjustmentAmount().compareTo( proratedAdjustment.multiply(fulfillmentGroupItem.getQuantity())) == 0); } } }