The fulfillment architecture consists of the following base classes:
Commerce Messages
Modification classes
Other classes
CommerceMessage Class
This class is the base class used by all the object messages sent in the fulfillment process. The properties in this class can be used for tracking messages. The class includes the following properties:
source
– identifies the source from which this message was sent. This property can be used to help screen messages.id
– a unique identifying string, the combination of the id and the source should be unique.userId
– the id of the last user to act on this message.originalSource
– the original source of this message. If a message is forwarded on from one component to the next, theoriginalSource
never changes but the source does.originalId
– the original message ID as it came from the original source.originalUserId
– the ID of the end user whose action initiated the message.
Although all these fields exist, only source
, id
, originalSource
and originalId
are used in the fulfillment subsystem. The other fields exist to accommodate extensions to the base class.
SubmitOrder Class
The SubmitOrder
message is sent to the OrderFulfiller
when the order is submitted for fulfillment. The SubmitOrder
message, like all of the other messages in fulfillment, is a serializable object contained within a JMS object message. The message includes a serialized order object containing all the information needed to fulfill the order.
The SubmitOrder
message is sent at the end of the checkout process. The message is constructed and sent in a processor as part of the processOrder
chain called sendFulfillmentMessage
. The properties are in /atg/commerce/order/processor/SendFulfillmentMessage
.
In the default implementation, the SubmitOrder
message is sent over localdms
to the ScenarioManager
and to the MessageForwardFilter
. The MessageForwardFilter
forwards the message over sqldms
to the /Fulfillment/SubmitOrder
durable topic. The OrderFulfiller
is the only listener on that durable topic. See the Dynamo Message System chapter in the ATG Platform Programming GuideATG Platform Programming Guide for more information. See the OrderFulfiller Class section for more details about what happens after the message is received.
FulfillOrderFragment Class
The OrderFulfiller
sends the FulfillerOrderFragment
message to the various fulfillment systems responsible for sending out the products in the shipping groups. All shipping groups in an order with the same fulfiller are sent in FulfillerOrderFragment
. The FulfillerOrderFragment
message contains the shipping group IDs.
The FulfillOrderFragment
message, like all of the other messages in fulfillment, is a serializable object contained within a JMS object message. The message includes a serialized order and the list of shipping groups IDs included in this fragment. This message is sent by the OrderFulfiller
to the various fulfillment systems responsible for fulfilling the shipping groups. When this message is sent, control of the object is transferred to the system that receives the message. By default, this system is the HardgoodFulfiller
.
ModifyOrder Class
The ModifyOrder
message extends the CommerceMessage
class and adds the following properties:
orderId
– the ID of the order being modifiedtype
– the JMS message typemodifications
– an array of modifications to be performed.
The ModifyOrder
message allows external sources to request changes to the order object. The list of modifications is included in the message’s modifications array. The recipient of the ModifyOrder
message is responsible for determining whether a modification is possible given the flow of control and the ownership of the objects for which the modification is requested.
After attempting to perform the modification, Oracle ATG Web Commerce sends a ModifyOrderNotification
referencing the modifications that were requested and indicating whether the modification was successful or not. If a component receives a ModifyOrder
message for an object to which the component does not have access, the request is forwarded on to other configured systems with access rights to the objects to be modified.
In Commerce, systems only listen for, and work on, one type of Modification in the ModifyOrder
message. By default, the modification listened for is the one requesting a cancellation of an order. This type is implemented in the OrderFulfillerModificationHandler
and the HardgoodFulfillerModificationHandler
, both of which extend the ModificationHandler
class. These classes are designed to deal with ModifyOrder
and ModifyOrderNotification
messages.
The ModifyOrder
message is received by the OrderFulfiller
. The OrderFulfiller
checks that none of the shipping groups have been shipped by examining their states. If any of the shipping groups have been shipped then a ModifyOrderNotification
message is sent with the requested modifications marked as failed. The sender of the original ModifyOrder
message is responsible for listening for the ModifyOrderNotification
.
The ModifyOrder
message and its modification array are flexible enough to accommodate any changes to the order structure and its subcomponents. However, Commerce implements only the most basic cancel order features because of the variety of business rules that can apply for requested changes and the legality of certain changes.
The ModificationHandler
class provides the flexibility to change the behavior in handling ModifyOrder
and ModifyOrderNotification
messages.
ModifyOrderNotification Class
The ModifyOrderNotification
class extends CommerceMessage
and adds the following properties:
orderId
– the ID of the order being modifiedmodifyOrderSource
– the originator of theModifyOrder
message if thisModifyOrderNotification
is in response to aModifyOrder
modifyOrderId
– the ID of theModifyOrder
message if thisModifyOrderNotification
is in response to aModifyOrder
modifications
– an array of the modifications that were made to this order
The ModifyOrderNotification
message provides a running record of all changes to the order or any of its sub-components. All changes made by components in the system are recorded and distributed in a ModifyOrderNotification
message. This allows distributed systems a way to keep their various databases synchronized when it pertains to certain aspects of the order. For example, it is possible for a business that has several fulfillers to have each fulfiller use a different backend system.
The control flow described earlier in this section clearly defines which components are responsible for order objects during different points in the fulfillment process. If one of the fulfillers makes a change to a shipping group for which it is responsible, the change is captured in a Modification, which is sent inside a ModifyOrderNotification
. For example, the fulfiller could change the state of a given item relationship to backordered.
The ModifyOrderNotifcation
is received by all the systems that are listening for it and it is the responsibility of those systems to update back ends to keep all the systems synchronized. In Oracle ATG Web Commerce, all the repositories are accessible by all of the components. This eliminates the need to synchronize various disparate databases. However, if a customer requires that a disparate system make modifications to the order objects, the OrderFulfillerModificationHandler
would need to be augmented to reflect the changes reported by the ModifyOrderNotification
messages being sent by the disparate systems.
UpdateInventory Class
The UpdateInventory
message extends the CommerceMessage
class. It adds one property:
itemIds
– a list of IDs of items that were previously unavailable (BACKORDERABLE, PREORDERABLE, or OUT_OF_STOCK) but now have stock available.
UpdateInventory
is sent by a third party system, such as an inventory subsystem, to indicate that items are available. The HardgoodFulfiller
in Oracle ATG Web Commerce listens for these messages. The HardgoodFulfiller
queries the order repository for all shipping groups that contain items from the list that are in a preordered or backordered state.
Modification Class
Each ModifyOrder
and ModifyOrderNotification
message contains an array of Modification
objects. The Modification
class is the base class for each of these modification objects. All modifications represent some change to a specified Order. In the default implementation of Oracle ATG Web Commerce, there are four types of Modification objects: ADD, REMOVE, UPDATE, or SHIPPING_GROUP_UPDATE. Refer to GenericAdd
, GenericRemove
, GenericUpdate
, and ShippingGroupUpdate
for more information.
Each Modification also targets a specific kind of object within an Order. For example, the Modification can remove a shipping group. The different possible targets are TARGET_ITEM, TARGET_SHIPPING_GROUP, TARGET_PAYMENT_GROUP, TARGET_ORDER, or TARGET_RELATIONSHIP. A status for each modification indicates success or failure.
The IdTargetModification
and IdContainerModification
classes are two abstract subclasses of Modification. For more information, see the ATG Platform API Reference.
GenericAdd Class
The GenericAdd
class is used to add a target specified by ID or value to a target specified by ID or value. For example:
Add item by ID or value to shipping group by ID or value.
Add item by ID or value to payment group by ID or value.
Add item by value to order by ID.
Add shipping group by value to order by ID.
Add payment group by value to order by ID.
These are the only valid combinations. Both the ID and the value should not be set for either the target or the container. Everything should be added to the order before it is used as either a target or container for another GenericAdd
.
For example if you are adding a new item, shipping group, and payment group, and want to add the item to both of the groups you would do the following:
Add the item to the order.
Add the shipping group to the order.
Add the payment group to the order.
Add the item to the shipping group.
Add the item to the payment group.
GenericRemove Class
The GenericRemove
class is used to remove an object specified by ID from a container specified by ID. If an item, shipping group, or payment group is removed from an order, it is removed from any relationships.
GenericUpdate Class
This class contains the information that describes a property change for an object. It contains the original value of the property (as a serializable Object) and the new value for the property.
For example, to change the state of a ShippingGroup
from PENDING_SHIPMENT to NO_PENDING_ACTION (for example ship the shipping group):
Set the
targetId
of theGenericUpdate
to the ID of the shipping group to be shipped.Set the
containerId
of theGenericUpdate
to the ID of the order containing that shipping group.Set the
propertyName
of theGenericUpdate
to “state” to update the state property of the shipping group.Set the
originalValue
to PENDING_SHIPMENT and set the new value to NO_PENDING_ACTION.
If you included the resulting GenericUpdate
in a ModifyOrder
message and sent it to the OrderFulfiller
, the status of the given shipping group would change to reflect that it has shipped.
ShippingGroupUpdate Class
This special Modification notifies the fulfillment system of any changes within a Shipping Group that happen externally. If the OrderFulfiller
receives a ModifyOrderNotification
with a ShippingGroupUpdate
Modification in it, the shipping groups listed in the Modification are reprocessed.
This is a convenient way of notifying fulfillment of complex changes to an order. It contains an order ID and an array of shipping group IDs that have been updated. After receiving this message, the OrderFulfiller
forwards it to each of the appropriate fulfillers, who then reprocess the entire shipping group.
PaymentGroupUpdate Class
This special Modification notifies the fulfillment system of any changes within a PaymentGroup
that happen externally.
OrderFulfiller Class
The OrderFulfiller
receives the SubmitOrder
message, which marks the start of the fulfillment process. The fulfillment process relies on a persistent, durable JMS subsystem to deliver messages as they become available. There should be only one instance of an OrderFulfiller
in place to receive the SubmitOrder
message. The method invoked on the reception of a message is the receiveMessage
method. The method will determine what type of message was sent and call the appropriate handle method for that message type.
The following methods handle the different messages:
getModificationHandler().handleModifyOrder
– This method handlesModifyOrder
messages. The handling ofModifyOrder
messages is delegated to theModificationHandler
class, which is configured as a property of theOrderFulfiller
.getModificationHandler().handleModifyOrderNotification
– This method deals withModifyOrder
messages. The handling ofModifyOrderNotification
messages is delegated to theModificationHandler
class, which is configured as a property of theOrderFulfiller
.handleNewMessageType
– This method is called if the types of the messages don’t match up to any of the above three types. By default, this is left as an empty method for future extensibility.handleSubmitOrder
- This method is called to handle allSubmitOrder
messages. It runs thehandleSubmitOrder
pipeline chain. For more information, see Appendix F, Pipeline Chains.
For information on the handling of ModifyOrder
and ModifyOrderNotification
messages, refer to the OrderFulfillerModificationHandler Class section.
HardgoodFulfiller Class
The HardgoodFulfiller
class receives the FulfillOrderFragment
message and begins the Fulfillment Process for the shipping groups listed within the message. This class is responsible for calling the appropriate pipeline chains.
When a shipping group is shipped, the warehouse notifies the HardgoodFulfiller
. The HardgoodFulfiller
then calls the appropriate pipeline chain to change the state of the shipping group and items within it and sends a ModifyOrderNotification
detailing the changes. For more information on fulfillment pipelines, see the Fulfillment Pipelines section of this chapter.
ElectronicFulfiller Class
The ElectronicFulfiller
is used to fulfill any type of good that is delivered electronically. Electronic goods should be associated with an ElectronicShippingGroup
. The ElectronicFulfiller
then fulfills the order by calling the appropriate pipeline chain.
Currently, the only items that use the ElectronicFulfiller
are gift certificates. The ElectronicFulfiller
could be used to fulfill any item using the following two actions
Create a claimable item in the claimable repository
E-mail user notification (and a claim code) that they have something waiting for them.
For more information on claimable items, see the Configuring Commerce Services chapter.
Electronic goods are fulfilled differently than hard goods. Electronic goods can take on a variety of forms. ElectronicFulfiller
creates items in a repository. These items represent an electronic good that the user can then obtain.
The ElectronicFulfiller
is responsible for fulfilling the order of various electronic goods. ElectronicFulfiller
fulfills electronic goods by performing two actions:
Creating an entry in a repository that represents the electronic good that the user can purchase.
Notifying a user that an electronic good is waiting for them to claim.
By default, Oracle ATG Web Commerce includes a component called SoftgoodFulfiller
, which is located at /atg/commerce/fulfillment/SoftgoodFulfiller
. This component is an instance of the atg.commerce.fulfillment.ElectronicFulfiller
.
OrderFulfillmentTools Class
The OrderFulfillmentTools
class contains methods that help create messages, modify objects, and manipulate the states in the Order, Shipping Groups, Payment Groups and relationships.
This class is used by fulfillment pipelines. The OrderFulfillmentTools
class contains various convenience methods for commonly performed tasks in fulfillment. For more information, please refer to the ATG Platform API Reference.
The OrderFulfillmentTools
also maintains the mapping of fulfillers to port names. The OrderFulfiller
uses these ports to send FulfillOrderFragment
messages to the correct fulfiller. The OrderFulfiller
has a different output port for each fulfiller. Messages sent through these ports are written to a different topic for each fulfiller. It is important that each possible value of the fulfiller property of each item in the product catalog is included in this mapping.
OrderFulfillerModificationHandler Class
The OrderFulfillerModificationHandler
class extends the ModificationHandler
interface. It is configured to handle the ModifyOrder
and ModifyOrderNotification
messages for the OrderFulfiller
class. The OrderFulfiller
class contains the ModificationHandler
property, which deals with both ModifyOrder
and ModifyOrderNotification
messages. To change the handling behavior of ModifyOrder
and ModifyOrderNotification
messages, extend the OrderFulfillerModificationHandler
class and change the ModificationHandler
property of OrderFulfiller
to point to the new class.
The default implementation deals with the following ModifyOrder
modifications:
Remove an order by sending a
ModifyOrder
message containing a Modification of type REMOVE. TheOrderFulfiller
receives this message. If the order and its shipping group are not in a NO_PENDING_ACTION state, thenModifyOrder
messages are sent to the various fulfillers handling the shipping groups. Every fulfiller who can cancel the shipping group responds by setting the state of the shipping group to PENDING_REMOVE. If all of the shipping group states are changed to PENDING_REMOVE, then the order state changes to REMOVED and all of the shipping group states can be changed to REMOVED. An order cannot be cancelled if any of its shipping groups have been shipped. If you attempt aGenericRemove
modification on an order that cannot be removed (for example, if one of the shipping groups in the order has shipped) then the order is set to PENDING_MERCHANT_ACTION.Notify the fulfillment system that a shipping group has shipped by sending a
ModifyOrder
message with aGenericUpdate
that changes the state of the shipping group from PENDING_SHIPMENT to NO_PENDING_ACTION. TheOrderFulfiller
will receive this message and forward it to the responsible fulfiller. For more information, see the GenericUpdate Class section.
The default implementation deals with the following ModifyOrderNotification
modifications:
Shipping group’s state changes to NO_PENDING_ACTION, PENDING_MERCHANT_ACTION, PENDING_REMOVE, or failure to change to PENDING_REMOVE.
When a customer updates a shipping group, the
OrderFulfiller
sends aModifyOrderNotification
message to the fulfiller responsible for this shipping group. This forces a reprocessing of the shipping group.
The Oracle ATG Web Commerce default implementation settles payment on first or last shipment of the shipping groups. You can configure when to charge payment in the SettleOnFirstShipment
property of the OrderFulfiller
. By default, charging takes place after the shipment of the last shipping group. The settlement is for the total value of the order. If settlement occurs on first shipment and a shipping group that hasn’t been shipped is cancelled, a credit must be issued for the items that were paid for but never shipped.
The extendible infrastructure allows all types of ModifyOrder
messages and ModifyOrderNotifications
depending on your business requirements.
HardgoodFulfillerModificationHandler Class
The HardgoodFulfillerModificationHandler
deals with the ModifyOrder
and ModifyOrderNotifications
messages received by the HardgoodFulfiller
. The HardgoodFulfiller
contains a ModificationHandler
property, which is set by default to the HardgoodFulfillerModificationHandler
. This class is similar to the OrderFulfillerModificationHandler
.
To change the handling behavior of ModifyOrder
and ModifyOrderNotification
messages, extend the HardgoodFulfillerModificationHandler
class and change the ModificationHandler
property HardgoodFulfiller
to point to the new class.
The default implementation deals with the following ModifyOrder
modification:
Remove the shipping group from the order:
The fulfillers can remove shipping groups if they have not been shipped. Determining whether a shipping group has been shipped can be difficult because of the asynchronous nature of shipping items. Consulting the states may not be enough to determine if the group has been shipped. Oracle ATG Web Commerce consults the state to make sure that it isn’t in a NO_PENDING_ACTION or REMOVED state. This is sufficient because in the default Commerce configuration, there is no integration with a real warehouse so shipment is indicated by changing a set of states in the order repository. Some vendors might decide to create business rules that limit the time in which cancellations can occur because it is difficult to determine the exact shipping time for a shipping group.
Ship the shipping group:
The
HardgoodFulfiller
can be notified that a shipping group has shipped through aModifyOrder
message (which is originally sent to theOrderFulfiller
, then forwarded to theHardgoodFulfiller
). TheHardgoodFulfiller
gets aGenericUpdate
modification through theModifyOrder
message, checks the current state of the shipping group to ensure that it is PENDING_SHIPMENT. If everything is fine, it sets the state to NO_PENDING_ACTION and notifies the rest of the system of the change with aModifyOrderNotification
message.
It also handles the following ModifyOrderNotification
modification:
Shipping group update:
A shipping group is re-processed when the method
processMultipleShippingGroups
inHardgoodFulfiller
is called. This method is called when a modification of type SHIPPING_GROUP_UPDATE is received. TheHardgoodFulfiller
does not listen on the topic over whichModifyOrderNotification
messages are sent. Instead, theOrderFulfufiller
listens on that topic and forwards the appropriate messages directly to theHardgoodFulfiller
using the port in defined inOrderFulfillmentTools.fulfillerPortNameMap
.