@Override
public CartOperationRequest onItemAdded(CartOperationRequest request) throws PricingException {
Order order = request.getOrder();
OrderItem orderItem = request.getOrderItem();
Map<FulfillmentType, FulfillmentGroup> fulfillmentGroups = new HashMap<FulfillmentType, FulfillmentGroup>();
FulfillmentGroup nullFulfillmentTypeGroup = null;
//First, let's organize fulfillment groups according to their fulfillment type
//We'll use the first of each type that we find. Implementors can choose to move groups / items around later.
if (order.getFulfillmentGroups() != null) {
for (FulfillmentGroup group : order.getFulfillmentGroups()) {
if (group.getType() == null) {
if (nullFulfillmentTypeGroup == null) {
nullFulfillmentTypeGroup = group;
}
} else {
if (fulfillmentGroups.get(group.getType()) == null) {
fulfillmentGroups.put(group.getType(), group);
}
}
}
}
if (orderItem instanceof BundleOrderItem) {
//We only care about the discrete order items
List<DiscreteOrderItem> itemsToAdd = new ArrayList<DiscreteOrderItem>(((BundleOrderItem) orderItem).getDiscreteOrderItems());
for (DiscreteOrderItem doi : itemsToAdd) {
FulfillmentGroup fulfillmentGroup = null;
FulfillmentType type = resolveFulfillmentType(doi);
if (type == null) {
//Use the fulfillment group with a null type
fulfillmentGroup = nullFulfillmentTypeGroup;
} else {
if (FulfillmentType.PHYSICAL_PICKUP_OR_SHIP.equals(type)) {
//This is really a special case. "PICKUP_OR_SHIP" is convenient to allow a sku to be picked up or shipped.
//However, it is ambiguous when actually trying to create a fulfillment group. So we default to "PHYSICAL_SHIP".
type = FulfillmentType.PHYSICAL_SHIP;
}
//Use the fulfillment group with the specified type
fulfillmentGroup = fulfillmentGroups.get(type);
}
//If the null type or specified type, above were null, then we need to create a new fulfillment group
boolean createdFulfillmentGroup = false;
if (fulfillmentGroup == null) {
fulfillmentGroup = fulfillmentGroupService.createEmptyFulfillmentGroup();
//Set the type
fulfillmentGroup.setType(type);
fulfillmentGroup.setOrder(order);
order.getFulfillmentGroups().add(fulfillmentGroup);
createdFulfillmentGroup = true;
}
fulfillmentGroup = addItemToFulfillmentGroup(order, doi, doi.getQuantity() * orderItem.getQuantity(), fulfillmentGroup);
order = fulfillmentGroup.getOrder();
// If we had to create a new fulfillment group, then ensure that this will operate correctly for the next set
// of fulfillment groups
if (createdFulfillmentGroup) {
if (type == null) {
nullFulfillmentTypeGroup = fulfillmentGroup;
} else {
fulfillmentGroups.put(type, fulfillmentGroup);
}
}
}
} else if (orderItem instanceof DiscreteOrderItem) {
DiscreteOrderItem doi = (DiscreteOrderItem)orderItem;
FulfillmentGroup fulfillmentGroup = null;
FulfillmentType type = resolveFulfillmentType(doi);
if (type == null) {
//Use the fulfillment group with a null type
fulfillmentGroup = nullFulfillmentTypeGroup;
} else {
if (FulfillmentType.PHYSICAL_PICKUP_OR_SHIP.equals(type)) {
//This is really a special case. "PICKUP_OR_SHIP" is convenient to allow a sku to be picked up or shipped.
//However, it is ambiguous when actually trying to create a fulfillment group. So we default to "PHYSICAL_SHIP".
type = FulfillmentType.PHYSICAL_SHIP;
}
//Use the fulfillment group with the specified type
fulfillmentGroup = fulfillmentGroups.get(type);
}
//If the null type or specified type, above were null, then we need to create a new fulfillment group
if (fulfillmentGroup == null) {
fulfillmentGroup = fulfillmentGroupService.createEmptyFulfillmentGroup();
//Set the type
fulfillmentGroup.setType(type);
fulfillmentGroup.setOrder(order);
order.getFulfillmentGroups().add(fulfillmentGroup);
}
fulfillmentGroup = addItemToFulfillmentGroup(order, orderItem, fulfillmentGroup);
order = fulfillmentGroup.getOrder();
} else {
FulfillmentGroup fulfillmentGroup = nullFulfillmentTypeGroup;
if (fulfillmentGroup == null) {
fulfillmentGroup = fulfillmentGroupService.createEmptyFulfillmentGroup();
fulfillmentGroup.setOrder(order);
order.getFulfillmentGroups().add(fulfillmentGroup);
}
fulfillmentGroup = addItemToFulfillmentGroup(order, orderItem, fulfillmentGroup);
}