You can create a new fulfiller if your site requires fulfillment functionality different from that of the HardgoodFulfiller or ElectronicFulfiller that ship with ATG Commerce. For example, you could create a new fulfiller if your customers can purchase a research report. Instead of allocating this report from inventory and shipping it to the customer via UPS or Federal Express, you send them the report as an attachment via e-mail. There is no need to check inventory since the report is automatically in stock. Shipment can be done immediately since your newly created fulfiller can interface directly with an e-mail system. This section will describe how to implement and configure this new simpler fulfiller. In this example, the new fulfiller is called MyOwnFulfiller.

JMS messages connect the new fulfiller and the rest of ATG Commerce. Specifically, fulfillment of a shipping group begins with a FulfillOrderFragment message. To receive these messages, the new fulfiller must implement atg.dms.patchbay.MessageSink.

In addition to receiving the FulfillOrderFragment messages, MyOwnFulfiller must send out messages to inform the rest of ATG Commerce about changes made to each order. To send these messages, MyOwnFulfiller must implement atg.dms.patchbay.MessageSource. There is a class in atg.commerce.messaging that provides most of the functionality MyOwnFulfiller will need to send and receive messages. This class is called SourceSinkTemplate. It implements both MessageSource and MessageSink. MyOwnFulfiller will be defined as follow:

package myPackage;
import atg.commerce.fulfillment.*;
import atg.commerce.messaging.*;

public class MyOwnFulfiller extends SourceSinkTemplate

The only method in SourceSinkTemplate that MyOwnFulfiller needs to overwrite is receiveMessage.

public void receiveMessage (String pPortName, Message pMessage)
      throws JMSException

The Patch Bay system calls this method when a message is sent to MyOwnFulfiller. For more information, see the Dynamo Message System chapter in the ATG Programming Guide. At this time, the only message MyOwnFulfiller listens for is FulfillOrderFragment. The receiveMessage method can check the type of the object in the message. Only the interested code will be listed here, error checking will be assumed.

} // end of receiveMessage

The handleFulfillOrderFragment method retrieves the order from the message and the list of shipping groups that need to be fulfilled. For this example, the necessary error checking will be listed here.

  1. Retrieve the FulfillOrderFragmentCommerceMessage from the incoming message:

    public void handleFulfillOrderFragment(ObjectMessage pMessage)
          FulfillOrderFragment fragment =
                (FulfillOrderFragment) pMessage.getObject();

  2. Retrieve the order and the shipping groups IDs:

    Order order = fragment.getOrder();
    String[] shippingGroupIds = fragment.getShippingGroupIds();

  3. Call a new method called processShippingGroup for each shipping group in the message.

    for(int i=0; i<shippingGroupIds.length; i++) {
          ShippingGroup sg =
          processShippingGroup(order, shippingGroup);

  4. One of the responsibilities of MyOwnFulfiller is to notify the rest of ATG Commerce what changes were made to the order included in this FulfillOrderFragment. To do this, MyOwnFulfiller needs to remember each modification made. Therefore, inside handleFulfillOrderFragment, declare a new List that will contain Modification objects. These objects are added to the list as changes are made. This list will need to be included in any method calls. The above code now looks like this:

    List modifications = new ArrayList();
    for(int i=0; i<shippingGroupIds.length; i++) {
          ShippingGroup sg =
          processShippingGroup(order, shippingGroup,

After processing is complete, MyOwnFulfiller saves the order and include the modifications in a message. This is handled by a method in the OrderFulfillmentTools:

OrderManager orderManager = getOrderManager();
OrderFulfillmentTools tools = getOrderFulfillmentTools();

tools.sendModifyOrderNotification(order.getId(), // order
   modificationList, // modifications
   null,             // ModifyOrder
   this,             // MessageSource
   getModifyOrderNotificationPort(),// port
   null);            // original message
}  // end of handleFulfillOrderFragment

See the ATG API Reference for a detailed description of the OrderFulfillmentToolssendModifyOrderNotification method.

MyOwnFulfiller depends on a few properties being set to properly function. It will need an OrderManager, OrderFulfillmentTools, and a ModifyNotificationPort. This port is explained in the Configuring a New Fulfiller section.

The only method that has not been discussed is processShippingGroup. The following example is a simple example of the functions of processShippingGroup in order processing. The most important function is the manipulation of the object states. There are two more properties necessary for the fulfiller: ShippingGroupStates and ShipItemrRelationshipStates.

public void processShippingGroup(Order pOrder,
                ShippingGroup pShippingGroup,
                List pModificationList)
   ShippingGroupStates sgStates = getShippingGroupStates();
   ShipItemRelationshipStates sirStates =
   OrderFulfillmentTools tools =

. . . get each item relationship in the shipping group

. . . for each item

  . . . send the report via e-mail using the orders
     // set the state to DELIVERED
        "Report has been e-mailed to customer",
. . . end for loop

// the shipping groups is finished
     "This shipping group has finished shipping",

The methods in OrderFulfillmentTools create the appropriate modifications, which are sent in a ModifyOrderNotification message by handleFulfillOrderFragment. The new fulfiller is now ready to be configured into ATG Commerce.

It is possible that the e-mail cannot be sent because of some error. For example, if a message is sent out because the shipping group cannot be shipped and the message contains an invalid e-mail address. One possibility for dealing with this error is to set the ShippingGroup to PENDING_MERCHANT_ACTION. If you implement your fulfiller to do this, then the Customer Service Representative must correct the order and tell the fulfillment system to reprocess that shipping group with a ShippingGroupUpdate Modification sent within a ModifyOrderNotification message.

To facilitate this, MyOwnFulfiller.receiveMessage should be configured to listen for ModifyOrderNotification messages and call handleModifyOrderNotification if one of these messages is received. That method can then call processShippingGroup for each shipping group and send a new ModifyOrderNotification with all modifications that were made.

A new fulfiller must be configured within Nucleus before it can be used by the fulfillment system. See the Configuring a New Fulfiller section for more information.

loading table of contents...