/** * Copyright 2012 the original author or authors. * <p/> * 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 * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * 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. */ package org.broadleafcommerce.inventory.checkout.service.workflow; import java.util.Map; import javax.annotation.Resource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.broadleafcommerce.core.catalog.domain.Sku; import org.broadleafcommerce.core.checkout.service.workflow.CheckoutContext; import org.broadleafcommerce.core.checkout.service.workflow.CheckoutSeed; import org.broadleafcommerce.core.workflow.DefaultErrorHandler; import org.broadleafcommerce.core.workflow.ErrorHandler; import org.broadleafcommerce.core.workflow.ProcessContext; import org.broadleafcommerce.core.workflow.WorkflowException; import org.broadleafcommerce.inventory.domain.FulfillmentLocation; import org.broadleafcommerce.inventory.exception.ConcurrentInventoryModificationException; import org.broadleafcommerce.inventory.service.InventoryService; import org.springframework.stereotype.Component; /** * This error handler essentially does exactly what the * {@link DefaultErrorHandler} does, * but it also attempts to detect whether inventory was decremented during the * workflow. If * so, it attampts to compensate for that inventory. * * @author Kelly Tisdell * @deprecated Use InventoryRollbackHandler */ @Deprecated @Component("blInventoryCompensatingCheckoutErrorHandler") public class InventoryCompensatingCheckoutErrorHandler implements ErrorHandler { private static final Log LOG = LogFactory .getLog(InventoryCompensatingCheckoutErrorHandler.class); @Resource(name = "blInventoryService") protected InventoryService inventoryService; @SuppressWarnings("unused") private String name; private final int maxRetries = 5; @Override public void setBeanName(String name) { this.name = name; } @SuppressWarnings("unchecked") @Override public void handleError(ProcessContext context, Throwable th) throws WorkflowException { context.stopProcess(); CheckoutSeed seed = ((CheckoutContext) context).getSeedData(); // The DecrementInventoryActivity, if successful, adds the inventory // that was decremented to the context. If we // find that, then we need to attempt to compensate for that inventory. if (seed.getUserDefinedFields() != null && seed.getUserDefinedFields().get("BLC_INVENTORY_DECREMENTED") != null) { Map<FulfillmentLocation, Map<Sku, Integer>> inventoryToIncrement = (Map<FulfillmentLocation, Map<Sku, Integer>>) seed .getUserDefinedFields().get("BLC_INVENTORY_DECREMENTED"); if (!inventoryToIncrement.isEmpty()) { for (Map.Entry<FulfillmentLocation, Map<Sku, Integer>> entry : inventoryToIncrement .entrySet()) { FulfillmentLocation location = entry.getKey(); int retryCount = 0; while (retryCount < maxRetries) { try { if (location == null) { inventoryService.incrementInventory(entry .getValue()); inventoryService.incrementInventoryOnHand(entry .getValue()); } else { inventoryService.incrementInventory( entry.getValue(), location); inventoryService.incrementInventoryOnHand( entry.getValue(), location); } break; } catch (ConcurrentInventoryModificationException ex) { retryCount++; if (retryCount == maxRetries) { LOG.error( "After an exception was encountered during checkout, where inventory was decremented. " + maxRetries + " attempts were made to compensate, " + "but were unsuccessful for order ID: " + seed.getOrder().getId() + ". This should be corrected manually!", ex); } } catch (RuntimeException ex) { LOG.error( "An unexpected error occured in the error handler of the checkout workflow trying to compensate for inventory. This happend for order ID: " + seed.getOrder().getId() + ". This should be corrected manually!", ex); break; } } } } } LOG.error("An error occurred during the workflow", th); throw new WorkflowException(th); } }