atg.commerce.fulfillment
Class OrderFulfiller

java.lang.Object
  extended by atg.nucleus.logging.VariableArgumentApplicationLoggingImpl
      extended by atg.nucleus.GenericService
          extended by atg.commerce.messaging.SourceSinkTemplate
              extended by atg.commerce.fulfillment.FulfillerSystem
                  extended by atg.commerce.fulfillment.OrderFulfiller
All Implemented Interfaces:
MessageSink, MessageSource, NameContextBindingListener, NameContextElement, NameResolver, AdminableService, ApplicationLogging, atg.nucleus.logging.ApplicationLoggingSender, atg.nucleus.logging.TraceApplicationLogging, atg.nucleus.logging.VariableArgumentApplicationLogging, ComponentNameResolver, Service, ServiceListener, java.util.EventListener

public class OrderFulfiller
extends FulfillerSystem

This class handles the start of the fulfillment process and is responsible for the routing of various requests made to the fulfillment subsystem. In a sense, the OrderFulfiller is the hub of communication relating to fulfillment. The order to be fulfilled is received through a SubmitOrder message and is handled by the handleSubmitOrder method . The OrderFulfiller is responsible for farming out FulfillOrderFragment messages to the various fulfillers interested in pieces of the order.

Different fulfillers such as HardgoodFulfiller receive the FulfillOrderFragment message and begin processing of the shipping groups specified within.

Additionally the OrderFulfiller receives ModifyOrderNotification and ModifyOrder messages. These messages are handled by the OrderFulfillerModificationHandler which is then responsible for making the changes requested or forwarding them to the fulfillers who currently own the responsibility for the areas in which the modifications are to be made.

Once the FulfillOrderFragment messages are sent, the OrderFulfiller loses control of the shipping groups and of the ShippingGroupCommerceItemRelationships. Control of these objects is regained once the shipping group ships or an error occurs. (i.e. the state of the shipping group is set to NO_PENDING_ACTION or PENDING_MERHANT_ACTION)

The order is settled (paid for) according to the value of the settleOnFirstShipment property. If this property is true, the order is settled after the first shipping group in the order ships. If this property is false, the order is settled after the last shipping group in the order ships.

See Also:
SubmitOrder, handleSubmitOrder(java.lang.String, javax.jms.ObjectMessage), FulfillOrderFragment, HardgoodFulfiller, ModifyOrder, ModifyOrderNotification, OrderFulfillerModificationHandler, isSettleOnFirstShipment()

Field Summary
static java.lang.String CLASS_VERSION
           
 
Fields inherited from class atg.commerce.fulfillment.FulfillerSystem
mModifyOrderNotificationPort, mModifyOrderPort, NUCLEUS_NAME
 
Fields inherited from class atg.nucleus.GenericService
SERVICE_INFO_KEY
 
Fields inherited from interface atg.nucleus.logging.TraceApplicationLogging
DEFAULT_LOG_TRACE_STATUS
 
Fields inherited from interface atg.nucleus.logging.ApplicationLogging
DEFAULT_LOG_DEBUG_STATUS, DEFAULT_LOG_ERROR_STATUS, DEFAULT_LOG_INFO_STATUS, DEFAULT_LOG_WARNING_STATUS
 
Constructor Summary
OrderFulfiller()
           
 
Method Summary
protected  void finishOrder(Order pOrder, java.util.List pModificationList)
          Deprecated. Replaced by the pipeline processor
 java.util.Properties getChainToRunMap()
           
 java.io.Serializable getKeyForMessage(javax.jms.ObjectMessage oMessage)
          This method will return the key to be used for locking out other messages with the same key while a thread is handling this message.
 ModificationHandler getModificationHandler()
          The ModificationHandler that will be used to deal with all ModifyOrder and ModifyOrderNotification messages.
protected  java.io.Serializable getOrderIdFromMessage(SubmitOrder cMessage)
          This is called only for the submitOrder messages
protected  boolean handleMessage(java.lang.String pPortName, javax.jms.ObjectMessage pMessage)
           This is called to handle a newly received message.
 void handleSubmitOrder(java.lang.String pPortName, javax.jms.ObjectMessage pMessage)
           This method is called to handle all messages of type SubmitOrder.
 boolean isAllowRemoveOrderWithPendingShipment()
          A ModifyOrder request, requesting that an order be removed should be processed even if there exists a shipping group that is in a PENDING_SHIPMENT state.
 boolean isSettleOnFirstShipment()
          This property determines whether the order should be settled on the first shipment of a shipping group in the order or after the last shipment of the shipping groups.
protected  Order loadOrder(java.lang.String pId)
          Deprecated. Replaced by the pipeline processor
protected  java.util.List retrieveShippingGroupsToBeSplit(Order pOrder)
          Deprecated. Replaced by the pipeline processor
 void sendOrderToFulfiller(Order pOrder, java.lang.String pFulfiller, java.util.List pShippingGroupIds, SubmitOrder pSubmitOrder, java.util.List pModificationList)
           This method will set the states of the shipping groups to processing, send a ModifyOrderNotification using OrderFulfillmentTools.sendModifyOrderNotification and will send a FulfillOrderFragment for the port of the fulfiller name passed in.
 void setAllowRemoveOrderWithPendingShipment(boolean pAllowRemoveOrderWithPendingShipment)
           
 void setChainToRunMap(java.util.Properties pChainToRunMap)
           
 void setModificationHandler(ModificationHandler pModificationHandler)
           
 void setSettleOnFirstShipment(boolean pSettleOnFirstShipment)
           
protected  void setShippingGroupStateProcessing(Order pOrder, java.util.List pListShipGroupIds, java.util.List pModificationList)
          Deprecated. Replaced by the pipeline processor
protected  void setShippingGroupSubmittedDate(ShippingGroup pShippingGroup, java.util.List pModificationList)
          Deprecated. Replaced by the pipeline processor
protected  void settleOrder(Order pOrder, java.util.List pModificationList)
          Deprecated. Replaced by the pipeline processor
protected  java.util.List splitShippingGroups(Order pOrder, java.util.List pShippingGroupsToBeSplit, java.util.List pModificationList)
          Deprecated. Replaced by the pipeline processor
protected  void updateOrder(Order pOrder)
          Deprecated. Replaced by the pipeline processor
 void verifyOrderFulfillment(Order pOrder)
           This method verifies that the order to be fulfilled is in a state which allows it to be fulfilled.
 
Methods inherited from class atg.commerce.fulfillment.FulfillerSystem
doStartService, getClientLockManager, getCommerceItemStates, getFulfillmentPipelineManager, getLookUpOrderIdFromMessage, getLookUpOrderIdFromOrder, getModifyOrderNotificationPort, getModifyOrderPort, getOrderFulfillmentTools, getOrderManager, getOrderStates, getPaymentGroupStates, getPaymentManager, getShipItemRelationshipStates, getShippingGroupStates, handleNewMessageType, receiveMessage, setClientLockManager, setCommerceItemStates, setFulfillmentPipelineManager, setLookUpOrderIdFromMessage, setLookUpOrderIdFromOrder, setModifyOrderNotificationPort, setModifyOrderPort, setOrderFulfillmentTools, setOrderManager, setOrderStates, setPaymentGroupStates, setPaymentManager, setShipItemRelationshipStates, setShippingGroupStates
 
Methods inherited from class atg.commerce.messaging.SourceSinkTemplate
getDelayOnSendRetry, getMessageSourceContext, getMessageSourceName, getTransactionManager, isAllowMessageSending, sendCommerceMessage, sendObjectMessage, setAllowMessageSending, setDelayOnSendRetry, setMessageSourceContext, setMessageSourceName, setTransactionManager, startMessageSource, stopMessageSource
 
Methods inherited from class atg.nucleus.GenericService
addLogListener, createAdminServlet, doStopService, getAbsoluteName, getAdminServlet, getLoggingForVlogging, getLogListenerCount, getLogListeners, getName, getNameContext, getNucleus, getRoot, getServiceConfiguration, getServiceInfo, isLoggingDebug, isLoggingError, isLoggingInfo, isLoggingTrace, isLoggingWarning, isRunning, logDebug, logDebug, logDebug, logError, logError, logError, logInfo, logInfo, logInfo, logTrace, logTrace, logTrace, logWarning, logWarning, logWarning, nameContextElementBound, nameContextElementUnbound, removeLogListener, resolveName, resolveName, resolveName, resolveName, sendLogEvent, setLoggingDebug, setLoggingError, setLoggingInfo, setLoggingTrace, setLoggingWarning, setNucleus, setServiceInfo, startService, stopService
 
Methods inherited from class atg.nucleus.logging.VariableArgumentApplicationLoggingImpl
vlogDebug, vlogDebug, vlogDebug, vlogDebug, vlogError, vlogError, vlogError, vlogError, vlogInfo, vlogInfo, vlogInfo, vlogInfo, vlogTrace, vlogTrace, vlogTrace, vlogTrace, vlogWarning, vlogWarning, vlogWarning, vlogWarning
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

CLASS_VERSION

public static final java.lang.String CLASS_VERSION
See Also:
Constant Field Values
Constructor Detail

OrderFulfiller

public OrderFulfiller()
Method Detail

setSettleOnFirstShipment

public void setSettleOnFirstShipment(boolean pSettleOnFirstShipment)

isSettleOnFirstShipment

public boolean isSettleOnFirstShipment()
This property determines whether the order should be settled on the first shipment of a shipping group in the order or after the last shipment of the shipping groups.

See Also:
OrderFulfillmentTools.isOrderSettleable(atg.commerce.order.Order, boolean)

setAllowRemoveOrderWithPendingShipment

public void setAllowRemoveOrderWithPendingShipment(boolean pAllowRemoveOrderWithPendingShipment)

isAllowRemoveOrderWithPendingShipment

public boolean isAllowRemoveOrderWithPendingShipment()
A ModifyOrder request, requesting that an order be removed should be processed even if there exists a shipping group that is in a PENDING_SHIPMENT state. (Keep in mind that the request is still denied if there is a shipping group in a NO_PENDING_ACTION state.) defaults to true


setModificationHandler

public void setModificationHandler(ModificationHandler pModificationHandler)

getModificationHandler

public ModificationHandler getModificationHandler()
The ModificationHandler that will be used to deal with all ModifyOrder and ModifyOrderNotification messages. It has two methods that are used by OrderFulfiller: handleModifyOrder and handleModifyOrderNotification.

See Also:
ModifyOrder, ModifyOrderNotification, OrderFulfillerModificationHandler

getChainToRunMap

public java.util.Properties getChainToRunMap()

setChainToRunMap

public void setChainToRunMap(java.util.Properties pChainToRunMap)

handleMessage

protected boolean handleMessage(java.lang.String pPortName,
                                javax.jms.ObjectMessage pMessage)
                         throws javax.jms.JMSException

This is called to handle a newly received message. Before this method is called, the message is subjected to basic validity checks, a transaction is established, and an exclusive lock is acquired for the message's key.

The OrderFulfiller handles the following types of messages: SubmitOrder, ModifyOrder and ModifyOrderNotification. Handling messages of different types can be done by extending the handleNewMessageType method and adding whatever logic is required in there.

Overrides:
handleMessage in class FulfillerSystem
Parameters:
pPortName - - the port on which this message was received
pMessage - - the message that was sent on the port
Throws:
javax.jms.JMSException
See Also:
SubmitOrder, ModifyOrder, ModifyOrderNotification, FulfillerSystem#receive, FulfillerSystem.handleNewMessageType(java.lang.String, javax.jms.ObjectMessage)

getKeyForMessage

public java.io.Serializable getKeyForMessage(javax.jms.ObjectMessage oMessage)
                                      throws javax.jms.JMSException
This method will return the key to be used for locking out other messages with the same key while a thread is handling this message.

Overrides:
getKeyForMessage in class FulfillerSystem
Parameters:
pMessage - the ObjectMessage containing the CommerceMessage.
Returns:
an Object which serves as the key for the message
Throws:
javax.jms.JMSException

getOrderIdFromMessage

protected java.io.Serializable getOrderIdFromMessage(SubmitOrder cMessage)
This is called only for the submitOrder messages

Returns:
an Object which serves as the key for the message

handleSubmitOrder

public void handleSubmitOrder(java.lang.String pPortName,
                              javax.jms.ObjectMessage pMessage)
                       throws javax.jms.JMSException

This method is called to handle all messages of type SubmitOrder. It will call the pipeline chain to process the message. Should developers wish to change the behavior of the OrderFulfiller class in handling a SubmitOrder message this method should be overridden

The order is verified using verifyOrderFulfillment to make sure it is in a state where fulfillment is possble. If it isn't an error is logged and no processing is done to that order. Next a list of shipping groups that need to be split are determined using the retrieveShippingGroupsToBeSplit method. If the method returns any shipping groups that need to be split, the splitShippingGroups method is called with the order and the returned shipping groups, followed by a repricing of the order.

The chain then determines which fulfillers need to get which shipping groups and uses the OrderFulfillmentTools.getFulfillersForShippingGroups to return the HashMap which contains this information about the various fulfillers and the shipping groups that those fulfillers should be receiving. The OrderFulfillmentTools.getFulfillerPort will return the port on which the message is sent for each fulfiller, and sendOrderToFulfiller.

The order is written back to the repository using updateOrder

Parameters:
pPortName - - the port on which this message is received
pMessage - - the object message which should contain a SubmitOrder message
Throws:
javax.jms.JMSException - is thrown on a failure to send a message
See Also:
SubmitOrder, verifyOrderFulfillment(atg.commerce.order.Order), retrieveShippingGroupsToBeSplit(atg.commerce.order.Order), OrderFulfillmentTools.getFulfillersForShippingGroups(java.util.List), OrderFulfillmentTools.getFulfillerPort(java.lang.String), sendOrderToFulfiller(atg.commerce.order.Order, java.lang.String, java.util.List, atg.commerce.fulfillment.SubmitOrder, java.util.List), updateOrder(atg.commerce.order.Order)

verifyOrderFulfillment

public void verifyOrderFulfillment(Order pOrder)
                            throws IllegalOrderStateException

This method verifies that the order to be fulfilled is in a state which allows it to be fulfilled. If the order is in an incomplete state or a no pending action state then an exception is thrown.

Parameters:
pOrder - - the order to be verified.
Throws:
atg.commerce.IllegalOrderStateException - if the order is in an illegal state
IllegalOrderStateException

sendOrderToFulfiller

public void sendOrderToFulfiller(Order pOrder,
                                 java.lang.String pFulfiller,
                                 java.util.List pShippingGroupIds,
                                 SubmitOrder pSubmitOrder,
                                 java.util.List pModificationList)
                          throws CommerceException,
                                 javax.jms.JMSException

This method will set the states of the shipping groups to processing, send a ModifyOrderNotification using OrderFulfillmentTools.sendModifyOrderNotification and will send a FulfillOrderFragment for the port of the fulfiller name passed in. This method uses the OrderFulfillmentTools.getFulfillerPort to determine which port to send the message out on.

Parameters:
pOrder - - the order to be fulfilled
pFulfiller - - the fulfiller name
pShippingGroupIds - - the ids of the shipping groups to be serviced by the fulfiller
pSubmitOrder - - the original message that this is a fragment of
Throws:
javax.jms.JMSException - is thrown on failure to send the message to the fulfiller.
CommerceException
See Also:
ModifyOrderNotification, OrderFulfillmentTools.sendModifyOrderNotification(java.lang.String, java.util.List, atg.commerce.fulfillment.ModifyOrder, atg.commerce.messaging.SourceSinkTemplate, java.lang.String, atg.commerce.fulfillment.ModifyOrderNotification), FulfillOrderFragment, OrderFulfillmentTools.getFulfillerPort(java.lang.String)

setShippingGroupStateProcessing

protected void setShippingGroupStateProcessing(Order pOrder,
                                               java.util.List pListShipGroupIds,
                                               java.util.List pModificationList)
Deprecated. Replaced by the pipeline processor

Set the shipping group states to processing and add the Modification objects created to the ModificationList that is passed. This method also sets the submittedDate of the order.The caller of this method is responsible for packaging the changes in a ModifyOrderNotification object and sending it out. This method can be overriden if the state detail information should be changed to something else or if any other work needs to be done when the shippin group state change occurs.

Parameters:
pOrder - the order to be operated on.
pShipGroupIds - the ids of the shipping groups whose state will change
pModificationList - the list to which the modification objects created will be added.

setShippingGroupSubmittedDate

protected void setShippingGroupSubmittedDate(ShippingGroup pShippingGroup,
                                             java.util.List pModificationList)
Deprecated. Replaced by the pipeline processor

This method sets the submitted date of the shipping group to the current time. To ensure this only happens once, it checks first to make sure it is not currently set.

Parameters:
pShippingGroup - The shipping group to set.
pModificationList - Place to store new modifications.

retrieveShippingGroupsToBeSplit

protected java.util.List retrieveShippingGroupsToBeSplit(Order pOrder)
Deprecated. Replaced by the pipeline processor

This method will take an order and return a List of the shipping groups that need to be split up into multiple shipping groups. The default implementation will flag shipping groups to be split if a shipping groups contains items that are fulfilled by multiple fulfillers.
The default implementation uses OrderFulfillmentTools.isShippingGroupSingleFulfiller to determine if all the items are fulfilled by one fulfiller.

Parameters:
pOrder - the order that contains the shipping groups
Returns:
a List of the shipping groups that should be split.
See Also:
OrderFulfillmentTools.isShippingGroupSingleFulfiller(atg.commerce.order.ShippingGroup)

splitShippingGroups

protected java.util.List splitShippingGroups(Order pOrder,
                                             java.util.List pShippingGroupsToBeSplit,
                                             java.util.List pModificationList)
                                      throws CommerceException
Deprecated. Replaced by the pipeline processor

This method will split the shipping groups specified by whatever business logic is required. The default implementation will be splitting the shipping groups according to fulfillers and will use the OrderFulfillmentTools.splitShippingGroupsByFulfiller. Should the implementor wish to choose a different algorithm for how shipping groups are split, this method should be overriden.

Parameters:
pOrder - the order which contains the shipping groups to be split
pShippingGroupsToBeSplit - the List of @see ShippingGroup objects that need to be split
Returns:
a List of the shipping groups that have been newly created.
Throws:
CommerceException
See Also:
OrderFulfillmentTools.splitShippingGroupsByFulfiller(atg.commerce.order.Order, java.util.List, java.util.List)

settleOrder

protected void settleOrder(Order pOrder,
                           java.util.List pModificationList)
                    throws PaymentException
Deprecated. Replaced by the pipeline processor

This method checks if it is okay to begin settlement and (if so) settles the order and changes the states of each payment group that is changed.

Parameters:
pOrder - The order to settle
pModificationList - place to store all new modifications
Throws:
PaymentException
See Also:
OrderFulfillmentTools.isOrderSettleable(atg.commerce.order.Order, boolean), atg.payment.PaymentManager

finishOrder

protected void finishOrder(Order pOrder,
                           java.util.List pModificationList)
Deprecated. Replaced by the pipeline processor

This method performs all processing that must be done once all the elements in an order are finished. This includes setting the orders state to NO_PENDING_ACTION and setting the completed date property. It does no verification that the order is in a state that allows it to be finished, that is done in isOrderFinished.

Parameters:
pOrder - The order to finish.
pModificationList - A place to store all modifications made
See Also:
OrderStates.NO_PENDING_ACTION, OrderFulfillmentTools.isOrderFinished(atg.commerce.order.Order)

loadOrder

protected Order loadOrder(java.lang.String pId)
                   throws CommerceException
Deprecated. Replaced by the pipeline processor

This method will return the Order from the order repository with the given id. In the standard implementation this will call the OrderManager and load the order.

Parameters:
pId - the id of the order to be retrieved
Returns:
the order corresponding to the id passed in
Throws:
CommerceException

updateOrder

protected void updateOrder(Order pOrder)
                    throws CommerceException
Deprecated. Replaced by the pipeline processor

This method will save the order using the order manager.

Parameters:
pOrder - - the order to be saved
Throws:
CommerceException - is thrown if the order fails to save for any reason.