Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * #%L
   * BroadleafCommerce Framework
   * %%
   * Copyright (C) 2009 - 2013 Broadleaf Commerce
   * %%
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
  * 
  *       http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * #L%
  */
 package org.broadleafcommerce.core.order.service;
 
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 

Author(s):
apazzolini
 
 @Service("blOrderService")
 @ManagedResource(objectName="org.broadleafcommerce:name=OrderService", description="Order Service", currencyTimeLimit=15)
 public class OrderServiceImpl implements OrderService {
     private static final Log LOG = LogFactory.getLog(OrderServiceImpl.class);
     
     /* DAOs */
     @Resource(name = "blOrderPaymentDao")
     protected OrderPaymentDao paymentDao;
     
     @Resource(name = "blOrderDao")
     protected OrderDao orderDao;
     
     @Resource(name = "blOfferDao")
     protected OfferDao offerDao;
    /* Factories */
    @Resource(name = "blNullOrderFactory")
    
    /* Services */
    @Resource(name = "blPricingService")
    protected PricingService pricingService;
    
    @Resource(name = "blOrderItemService")
    
    @Resource(name = "blFulfillmentGroupService")
    
    @Resource(name = "blOfferService")
    protected OfferService offerService;
    @Resource(name = "blSecureOrderPaymentService")
    @Resource(name = "blMergeCartService")
    
    @Resource(name = "blOrderServiceExtensionManager")
    
    /* Workflows */
    @Resource(name = "blAddItemWorkflow")
    protected Processor addItemWorkflow;
    
    @Resource(name = "blUpdateProductOptionsForItemWorkflow")
    @Resource(name = "blUpdateItemWorkflow")
    protected Processor updateItemWorkflow;
    
    @Resource(name = "blRemoveItemWorkflow")
    protected Processor removeItemWorkflow;
    @Resource(name = "blTransactionManager")
    @Value("${pricing.retry.count.for.lock.failure}")
    protected int pricingRetryCountForLockFailure = 3;
    @Value("${pricing.retry.wait.interval.for.lock.failure}")
    protected long pricingRetryWaitIntervalForLockFailure = 500L;
    
    /* Fields */
    protected boolean moveNamedOrderItems = true;
    protected boolean deleteEmptyNamedOrders = true;
    @Value("${automatically.merge.like.items}")
    protected boolean automaticallyMergeLikeItems;
    @Override
    @Transactional("blTransactionManager")
    public Order createNewCartForCustomer(Customer customer) {
        return .createNewCartForCustomer(customer);
    }
    @Override
    @Transactional("blTransactionManager")
    public Order createNamedOrderForCustomer(String nameCustomer customer) {
        Order namedOrder = .create();
        namedOrder.setCustomer(customer);
        namedOrder.setName(name);
        namedOrder.setStatus(.);
        
        if ( != null) {
            .getProxy().attachAdditionalDataToNewNamedCart(customernamedOrder);
        }
        
        if (BroadleafRequestContext.getBroadleafRequestContext() != null) {
            namedOrder.setLocale(BroadleafRequestContext.getBroadleafRequestContext().getLocale());
        }
        
        return .save(namedOrder); // No need to price here
    }
    @Override
    public Order findNamedOrderForCustomer(String nameCustomer customer) {
        return .readNamedOrderForCustomer(customername);
    }
    @Override
    public Order findOrderById(Long orderId) {
        return .readOrderById(orderId);
    }
    @Override
    public Order getNullOrder() {
        return .getNullOrder();
    }
    @Override
    public Order findCartForCustomer(Customer customer) {
        return .readCartForCustomer(customer);
    }
    @Override
    public List<OrderfindOrdersForCustomer(Customer customer) {
        return .readOrdersForCustomer(customer.getId());
    }
    @Override
    public List<OrderfindOrdersForCustomer(Customer customerOrderStatus status) {
        return .readOrdersForCustomer(customerstatus);
    }
    @Override
    public Order findOrderByOrderNumber(String orderNumber) {
        return .readOrderByOrderNumber(orderNumber);
    }
    @Override
    public List<OrderPaymentfindPaymentsForOrder(Order order) {
        return .readPaymentsForOrder(order);
    }
    
    @Override
    @Transactional("blTransactionManager")
    public OrderPayment addPaymentToOrder(Order orderOrderPayment paymentReferenced securePaymentInfo) {
        payment.setOrder(order);
        order.getPayments().add(payment);
        order = persist(order);
        int paymentIndex = order.getPayments().size() - 1;
        if (securePaymentInfo != null) {
            .save(securePaymentInfo);
        }
        return order.getPayments().get(paymentIndex);
    }
    @Override
    public Order save(Order orderBoolean priceOrderthrows PricingException {
        //persist the order first
        TransactionStatus status = TransactionUtils.createTransaction("saveOrder",
                    .);
        try {
            order = persist(order);
            TransactionUtils.finalizeTransaction(statusfalse);
        } catch (RuntimeException ex) {
            TransactionUtils.finalizeTransaction(statustrue);
            throw ex;
        }
        //make any pricing changes - possibly retrying with the persisted state if there's a lock failure
        if (priceOrder) {
            int retryCount = 0;
            boolean isValid = false;
            while (!isValid) {
                try {
                    order = .executePricing(order);
                    isValid = true;
                } catch (Exception ex) {
                    boolean isValidCause = false;
                    Throwable cause = ex;
                    while (!isValidCause) {
                        if (cause.getClass().equals(LockAcquisitionException.class)) {
                            isValidCause = true;
                        }
                        cause = cause.getCause();
                        if (cause == null) {
                            break;
                        }
                    }
                    if (isValidCause) {
                        if (.isInfoEnabled()) {
                            .info("Problem acquiring lock during pricing call - attempting to price again.");
                        }
                        isValid = false;
                        if (retryCount >= ) {
                            if (.isInfoEnabled()) {
                                .info("Problem acquiring lock during pricing call. Retry limit exceeded at (" + retryCount + "). Throwing exception.");
                            }
                            if (ex instanceof PricingException) {
                                throw (PricingExceptionex;
                            } else {
                                throw new PricingException(ex);
                            }
                        } else {
                            order = findOrderById(order.getId());
                            retryCount++;
                        }
                        try {
                            Thread.sleep();
                        } catch (Throwable e) {
                            //do nothing
                        }
                    } else {
                        if (ex instanceof PricingException) {
                            throw (PricingExceptionex;
                        } else {
                            throw new PricingException(ex);
                        }
                    }
                }
            }
            //make the final save of the priced order
            status = TransactionUtils.createTransaction("saveOrder",
                                .);
            try {
                order = persist(order);
                TransactionUtils.finalizeTransaction(statusfalse);
            } catch (RuntimeException ex) {
                TransactionUtils.finalizeTransaction(statustrue);
                throw ex;
            }
        }
        return order;
    }
    
    // This method exists to provide OrderService methods the ability to save an order
    // without having to worry about a PricingException being thrown.
    protected Order persist(Order order) {
        return .save(order);
    }
    @Override
    @Transactional("blTransactionManager")
    public void cancelOrder(Order order) {
        .delete(order);
    }
    @Override
    @Transactional("blTransactionManager")
    public void deleteOrder(Order order) {
        .delete(order);
    }
    @Override
    @Transactional("blTransactionManager")
    public Order addOfferCode(Order orderOfferCode offerCodeboolean priceOrderthrows PricingExceptionOfferMaxUseExceededException {
        preValidateCartOperation(order);
        Set<OfferaddedOffers = .getUniqueOffersFromOrder(order);
        //TODO: give some sort of notification that adding the offer code to the order was unsuccessful
        if (!order.getAddedOfferCodes().contains(offerCode) && !addedOffers.contains(offerCode.getOffer())) {
            if (!.verifyMaxCustomerUsageThreshold(order.getCustomer(), offerCode)) {
                throw new OfferMaxUseExceededException("The customer has used this offer code more than the maximum allowed number of times.");
            }
            order.getAddedOfferCodes().add(offerCode);
            order = save(orderpriceOrder);
        }
        return order;
    }
    @Override
    @Transactional("blTransactionManager")
    public Order removeOfferCode(Order orderOfferCode offerCodeboolean priceOrderthrows PricingException {
        order.getAddedOfferCodes().remove(offerCode);
        order = save(orderpriceOrder);
        return order;   
    }
    @Override
    @Transactional("blTransactionManager")
    public Order removeAllOfferCodes(Order orderboolean priceOrderthrows PricingException {
         order.getAddedOfferCodes().clear();
         order = save(orderpriceOrder);
         return order;  
    }
    @Override
    @ManagedAttribute(description="The delete empty named order after adding items to cart attribute", currencyTimeLimit=15)
    public void setDeleteEmptyNamedOrders(boolean deleteEmptyNamedOrders) {
        this. = deleteEmptyNamedOrders;
    }
    
    @Override
    public OrderItem findLastMatchingItem(Order orderLong skuIdLong productId) {
        if (order.getOrderItems() != null) {
            for (int i=(order.getOrderItems().size()-1); i >= 0; i--) {
                OrderItem currentItem = (order.getOrderItems().get(i));
                if (currentItem instanceof DiscreteOrderItem) {
                    DiscreteOrderItem discreteItem = (DiscreteOrderItemcurrentItem;
                    if (skuId != null) {
                        if (discreteItem.getSku() != null && skuId.equals(discreteItem.getSku().getId())) {
                            return discreteItem;
                        }
                    } else if (productId != null && discreteItem.getProduct() != null && productId.equals(discreteItem.getProduct().getId())) {
                        return discreteItem;
                    }
                } else if (currentItem instanceof BundleOrderItem) {
                    BundleOrderItem bundleItem = (BundleOrderItemcurrentItem;
                    if (skuId != null) {
                        if (bundleItem.getSku() != null && skuId.equals(bundleItem.getSku().getId())) {
                            return bundleItem;
                        }
                    } else if (productId != null && bundleItem.getProduct() != null && productId.equals(bundleItem.getProduct().getId())) {
                        return bundleItem;
                    }
                }
            }
        }
        return null;
    }
    
    @Override
    @Transactional("blTransactionManager")
    public Order confirmOrder(Order order) {
        return .submitOrder(order);
    }
    
    @Override
    @Transactional("blTransactionManager")
    public Order addAllItemsFromNamedOrder(Order namedOrderboolean priceOrderthrows RemoveFromCartExceptionAddToCartException {
        Order cartOrder = .readCartForCustomer(namedOrder.getCustomer());
        if (cartOrder == null) {
            cartOrder = createNewCartForCustomer(namedOrder.getCustomer());
        }
        List<OrderItemitems = new ArrayList<OrderItem>(namedOrder.getOrderItems());
        for (OrderItem item : items) {
            if () {
                removeItem(namedOrder.getId(), item.getId(), false);
            }
            
            OrderItemRequestDTO orderItemRequest = .buildOrderItemRequestDTOFromOrderItem(item);
            cartOrder = addItem(cartOrder.getId(), orderItemRequestpriceOrder);
        }
        
        if () {
            cancelOrder(namedOrder);
        }
        
        return cartOrder;
    }
    
    @Override
    @Transactional("blTransactionManager")
    public Order addItemFromNamedOrder(Order namedOrderOrderItem itemboolean priceOrderthrows RemoveFromCartExceptionAddToCartException {
        Order cartOrder = .readCartForCustomer(namedOrder.getCustomer());
        if (cartOrder == null) {
            cartOrder = createNewCartForCustomer(namedOrder.getCustomer());
        }
        
        if () {
            removeItem(namedOrder.getId(), item.getId(), false);
        }
            
        cartOrder = addItem(cartOrder.getId(), orderItemRequestpriceOrder);
        
        if (namedOrder.getOrderItems().size() == 0 && ) {
            cancelOrder(namedOrder);
        }
            
        return cartOrder;
    }
    
    @Override
    @Transactional("blTransactionManager")
    public Order addItemFromNamedOrder(Order namedOrderOrderItem itemint quantityboolean priceOrderthrows RemoveFromCartExceptionAddToCartExceptionUpdateCartException {
        // Validate that the quantity requested makes sense
        if (quantity < 1 || quantity > item.getQuantity()) {
            throw new IllegalArgumentException("Cannot move 0 or less quantity");
        } else if (quantity == item.getQuantity()) {
            return addItemFromNamedOrder(namedOrderitempriceOrder);
        }
        
        Order cartOrder = .readCartForCustomer(namedOrder.getCustomer());
        if (cartOrder == null) {
            cartOrder = createNewCartForCustomer(namedOrder.getCustomer());
        }
        
        if () {
            // Update the old item to its new quantity only if we're moving items
            OrderItemRequestDTO orderItemRequestDTO = new OrderItemRequestDTO();
            orderItemRequestDTO.setOrderItemId(item.getId());
            orderItemRequestDTO.setQuantity(item.getQuantity() - quantity);
            updateItemQuantity(namedOrder.getId(), orderItemRequestDTOfalse);
        }
            
        orderItemRequest.setQuantity(quantity);
        cartOrder = addItem(cartOrder.getId(), orderItemRequestpriceOrder);
            
        return cartOrder;
    }
    
    @Override
    @Transactional("blTransactionManager")
    public OrderItem addGiftWrapItemToOrder(Order orderGiftWrapOrderItemRequest itemRequestboolean priceOrderthrows PricingException {
        GiftWrapOrderItem item = .createGiftWrapOrderItem(itemRequest);
        item.setOrder(order);
        item = (GiftWrapOrderItem.saveOrderItem(item);
        
        order.getOrderItems().add(item);
        order = save(orderpriceOrder);
        
        return item;
    }
    
    @Override
    @Transactional(value = "blTransactionManager", rollbackFor = {AddToCartException.class})
    public Order addItem(Long orderIdOrderItemRequestDTO orderItemRequestDTOboolean priceOrderthrows AddToCartException {
        // Don't allow overrides from this method.
        orderItemRequestDTO.setOverrideRetailPrice(null);
        orderItemRequestDTO.setOverrideSalePrice(null);
        return addItemWithPriceOverrides(orderIdorderItemRequestDTOpriceOrder);
    }
    @Override
    @Transactional(value = "blTransactionManager", rollbackFor = { AddToCartException.class })
    public Order addItemWithPriceOverrides(Long orderIdOrderItemRequestDTO orderItemRequestDTOboolean priceOrderthrows AddToCartException {
        Order order = findOrderById(orderId);
        preValidateCartOperation(order);
        if () {
            OrderItem item = findMatchingItem(orderorderItemRequestDTO);
            if (item != null) {
                orderItemRequestDTO.setQuantity(item.getQuantity() + orderItemRequestDTO.getQuantity());
                orderItemRequestDTO.setOrderItemId(item.getId());
                try {
                    return updateItemQuantity(orderIdorderItemRequestDTOpriceOrder);
                } catch (RemoveFromCartException e) {
                    throw new AddToCartException("Unexpected error - system tried to remove item while adding to cart"e);
                } catch (UpdateCartException e) {
                    throw new AddToCartException("Could not update quantity for matched item"e);
                }
            }
        }
        try {
            // We only want to price on the last addition for performance reasons and only if the user asked for it.
            int numAdditionRequests = priceOrder ? (1 + orderItemRequestDTO.getChildOrderItems().size()) : -1;
            int currentAddition = 1;
            CartOperationRequest cartOpRequest = new CartOperationRequest(findOrderById(orderId), orderItemRequestDTOcurrentAddition == numAdditionRequests);
            List<ActivityMessageDTOorderMessages = new ArrayList<ActivityMessageDTO>();
            orderMessages.addAll(((ActivityMessagescontext).getActivityMessages());
            
            if (CollectionUtils.isNotEmpty(orderItemRequestDTO.getChildOrderItems())) {
                for (OrderItemRequestDTO childRequest : orderItemRequestDTO.getChildOrderItems()) {
                    childRequest.setParentOrderItemId(context.getSeedData().getOrderItem().getId());
                    currentAddition++;
                    CartOperationRequest childCartOpRequest = new CartOperationRequest(context.getSeedData().getOrder(), childRequestcurrentAddition == numAdditionRequests);
                    ProcessContext<CartOperationRequestchildContext = (ProcessContext<CartOperationRequest>) .doActivities(childCartOpRequest);
                    orderMessages.addAll(((ActivityMessageschildContext).getActivityMessages());
                }
            }
            
            context.getSeedData().getOrder().setOrderMessages(orderMessages);
            return context.getSeedData().getOrder();
        } catch (WorkflowException e) {
            throw new AddToCartException("Could not add to cart"getCartOperationExceptionRootCause(e));
        }
    }
    @Override
    @Transactional(value = "blTransactionManager", rollbackFor = {UpdateCartException.classRemoveFromCartException.class})
    public Order updateItemQuantity(Long orderIdOrderItemRequestDTO orderItemRequestDTOboolean priceOrderthrows UpdateCartExceptionRemoveFromCartException {
        preValidateCartOperation(findOrderById(orderId));
        if (orderItemRequestDTO.getQuantity() == 0) {
            return removeItem(orderIdorderItemRequestDTO.getOrderItemId(), priceOrder);
        }
        
        try {
            CartOperationRequest cartOpRequest = new CartOperationRequest(findOrderById(orderId), orderItemRequestDTOpriceOrder);
            context.getSeedData().getOrder().getOrderMessages().addAll(((ActivityMessagescontext).getActivityMessages());
            return context.getSeedData().getOrder();
        } catch (WorkflowException e) {
            throw new UpdateCartException("Could not update cart quantity"getCartOperationExceptionRootCause(e));
        }
    }
    @Override
    @Transactional(value = "blTransactionManager", rollbackFor = {RemoveFromCartException.class})
    public Order removeItem(Long orderIdLong orderItemIdboolean priceOrderthrows RemoveFromCartException {
        preValidateCartOperation(findOrderById(orderId));
        try {
            OrderItem oi = .readOrderItemById(orderItemId);
            if (CollectionUtils.isNotEmpty(oi.getChildOrderItems())) {
                List<LongchildrenToRemove = new ArrayList<Long>();
                for (OrderItem childOrderItem : oi.getChildOrderItems()) {
                    childrenToRemove.add(childOrderItem.getId());
                }
                for (Long childToRemove : childrenToRemove) {
                    removeItemInternal(orderIdchildToRemovefalse);
                }
            }
            return removeItemInternal(orderIdorderItemIdpriceOrder);
        } catch (WorkflowException e) {
            throw new RemoveFromCartException("Could not remove from cart"getCartOperationExceptionRootCause(e));
        }
    }
    
    protected Order removeItemInternal(Long orderIdLong orderItemIdboolean priceOrderthrows WorkflowException {
        OrderItemRequestDTO orderItemRequestDTO = new OrderItemRequestDTO();
        orderItemRequestDTO.setOrderItemId(orderItemId);
        CartOperationRequest cartOpRequest = new CartOperationRequest(findOrderById(orderId), orderItemRequestDTOpriceOrder);
        return context.getSeedData().getOrder();
    }
    @Override
    @Transactional(value = "blTransactionManager", rollbackFor = { RemoveFromCartException.class })
    public Order removeInactiveItems(Long orderIdboolean priceOrderthrows RemoveFromCartException {
        Order order = findOrderById(orderId);
        try {
            for (OrderItem currentItem : new ArrayList<OrderItem>(order.getOrderItems())) {
                if (!currentItem.isSkuActive()) {
                    removeItem(orderIdcurrentItem.getId(), priceOrder);
                }
            }
        } catch (Exception e) {
            throw new RemoveFromCartException("Could not remove from cart"e.getCause());
        }
        return findOrderById(orderId);
    }
    @Override
    public boolean getAutomaticallyMergeLikeItems() {
        return ;
    }
    @Override
    public void setAutomaticallyMergeLikeItems(boolean automaticallyMergeLikeItems) {
        this. = automaticallyMergeLikeItems;
    }
    
    @Override
    @ManagedAttribute(description="The move item from named order when adding to the cart attribute", currencyTimeLimit=15)
    public boolean isMoveNamedOrderItems() {
        return ;
    }
    @Override
    @ManagedAttribute(description="The move item from named order when adding to the cart attribute", currencyTimeLimit=15)
    public void setMoveNamedOrderItems(boolean moveNamedOrderItems) {
        this. = moveNamedOrderItems;
    }
    @Override
    @ManagedAttribute(description="The delete empty named order after adding items to cart attribute", currencyTimeLimit=15)
    public boolean isDeleteEmptyNamedOrders() {
        return ;
    }
    @Override
    @Transactional("blTransactionManager")
    public void removeAllPaymentsFromOrder(Order order) {
        removePaymentsFromOrder(ordernull);
    }
    @Override
    @Transactional("blTransactionManager")
    public void removePaymentsFromOrder(Order orderPaymentType paymentInfoType) {
        List<OrderPaymentinfos = new ArrayList<OrderPayment>();
        for (OrderPayment paymentInfo : order.getPayments()) {
            if (paymentInfoType == null || paymentInfoType.equals(paymentInfo.getType())) {
                infos.add(paymentInfo);
            }
        }
        order.getPayments().removeAll(infos);
        for (OrderPayment paymentInfo : infos) {
            try {
                .findAndRemoveSecurePaymentInfo(paymentInfo.getReferenceNumber(), paymentInfo.getType());
            } catch (WorkflowException e) {
                // do nothing--this is an acceptable condition
                .debug("No secure payment is associated with the OrderPayment"e);
            }
            order.getPayments().remove(paymentInfo);
            paymentInfo = .readPaymentById(paymentInfo.getId());
            .delete(paymentInfo);
        }
    }
    @Override
    @Transactional("blTransactionManager")
    public void removePaymentFromOrder(Order orderOrderPayment payment){
        OrderPayment paymentToRemove = null;
        for (OrderPayment info : order.getPayments()){
            if (info.equals(payment)){
                paymentToRemove = info;
            }
        }
        if (paymentToRemove != null){
            try {
                .findAndRemoveSecurePaymentInfo(paymentToRemove.getReferenceNumber(), payment.getType());
            } catch (WorkflowException e) {
                // do nothing--this is an acceptable condition
                .debug("No secure payment is associated with the OrderPayment"e);
            }
            order.getPayments().remove(paymentToRemove);
            payment = .readPaymentById(paymentToRemove.getId());
            .delete(payment);
        }
    }
    
    
This method will return the exception that is immediately below the deepest WorkflowException in the current stack trace.

Parameters:
e the workflow exception that contains the requested root cause
Returns:
the root cause of the workflow exception
        Throwable cause = e.getCause();
        if (cause == null) {
            return e;
        }
        
        Throwable currentCause = cause;
        while (currentCause.getCause() != null) {
            currentCause = currentCause.getCause();
            if (currentCause instanceof WorkflowException) {
                cause = currentCause.getCause();
            }
        }
        
        return cause;
    }

    
Returns true if the two items attributes exactly match.

Parameters:
item1
item2
Returns:
    protected boolean compareAttributes(Map<StringOrderItemAttributeitem1AttributesOrderItemRequestDTO item2) {
        int item1AttributeSize = item1Attributes == null ? 0 : item1Attributes.size();
        int item2AttributeSize = item2.getItemAttributes() == null ? 0 : item2.getItemAttributes().size();
        if (item1AttributeSize != item2AttributeSize) {
            return false;
        }
        for (String key : item2.getItemAttributes().keySet()) {
            String itemOneValue = (item1Attributes.get(key) == null) ? null : item1Attributes.get(key).getValue();
            String itemTwoValue = item2.getItemAttributes().get(key);
            if (!itemTwoValue.equals(itemOneValue)) {
                return false;
            }
        }
        return true;
    }
    protected boolean itemMatches(Sku item1SkuProduct item1ProductMap<StringOrderItemAttributeitem1Attributes,
            OrderItemRequestDTO item2) {
        // Must match on SKU and options
        if (item1Sku != null && item2.getSkuId() != null) {
            if (item1Sku.getId().equals(item2.getSkuId())) {
                return true;
            }
        } else {
            if (item1Product != null && item2.getProductId() != null) {
                if (item1Product.getId().equals(item2.getProductId())) {
                    return compareAttributes(item1Attributesitem2);
                }
            }
        }
        return false;
    }
    protected OrderItem findMatchingItem(Order orderOrderItemRequestDTO itemToFind) {
        if (order == null) {
            return null;
        }
        for (OrderItem currentItem : order.getOrderItems()) {
            if (currentItem instanceof DiscreteOrderItem) {
                DiscreteOrderItem discreteItem = (DiscreteOrderItemcurrentItem;
                if (itemMatches(discreteItem.getSku(), discreteItem.getProduct(), discreteItem.getOrderItemAttributes(),
                        itemToFind)) {
                    return discreteItem;
                }
            } else if (currentItem instanceof BundleOrderItem) {
                BundleOrderItem bundleItem = (BundleOrderItemcurrentItem;
                if (itemMatches(bundleItem.getSku(), bundleItem.getProduct(), nullitemToFind)) {
                    return bundleItem;
                }
            }
        }
        return null;
    }
    @Override
    @Transactional(value = "blTransactionManager", rollbackFor = { UpdateCartException.class })
    public Order updateProductOptionsForItem(Long orderIdOrderItemRequestDTO orderItemRequestDTOboolean priceOrderthrows UpdateCartException {
        try {
            CartOperationRequest cartOpRequest = new CartOperationRequest(findOrderById(orderId), orderItemRequestDTOpriceOrder);
            context.getSeedData().getOrder().getOrderMessages().addAll(((ActivityMessagescontext).getActivityMessages());
            return context.getSeedData().getOrder();
        } catch (WorkflowException e) {
            throw new UpdateCartException("Could not product options"getCartOperationExceptionRootCause(e));
        }
    }
    @Override
    public void printOrder(Order orderLog log) {
        if (!log.isDebugEnabled()) {
            return;
        }
        
        TableCreator tc = new TableCreator(new TableCreator.Col[] {
            new TableCreator.Col("Order Item", 30),
            new TableCreator.Col("Qty"),
            new TableCreator.Col("Unit Price"),
            new TableCreator.Col("Avg Adj"),
            new TableCreator.Col("Total Adj"),
            new TableCreator.Col("Total Price")
        });
        for (OrderItem oi : order.getOrderItems()) {
            tc.addRow(new String[] {
                oi.getName(),
                String.valueOf(oi.getQuantity()),
                String.valueOf(oi.getPriceBeforeAdjustments(true)),
                String.valueOf(oi.getAverageAdjustmentValue()),
                String.valueOf(oi.getTotalAdjustmentValue()),
                String.valueOf(oi.getTotalPrice())
            });
        }
        
        tc.addSeparator()
            .withGlobalRowHeaderWidth(15)
            .addRow("Subtotal"order.getSubTotal())
            .addRow("Order Adj."order.getOrderAdjustmentsValue())
            .addRow("Tax"order.getTotalTax())
            .addRow("Shipping"order.getTotalShipping())
            .addRow("Total"order.getTotal())
            .addSeparator();
        
        log.debug(tc.toString());
    }
    
    @Override
    public void preValidateCartOperation(Order cart) {
        ExtensionResultHolder erh = new ExtensionResultHolder();
        if (erh.getThrowable() instanceof IllegalCartOperationException) {
            throw ((IllegalCartOperationExceptionerh.getThrowable());
        } else if (erh.getThrowable() != null) {
            throw new RuntimeException(erh.getThrowable());
        }
    }