Inventory

InventoryManager


The InventoryManager is a public interface that contains all of the Inventory system functionality. Each method described below returns an integer status code. All successful return codes should be greater than or equal to zero, all failure codes should be less than zero. 

By default, the Status Code are:

  • int INVENTORY_STATUS_SUCCEED=0
  • int INVENTORY_STATUS_FAIL=-1
  • int INVENTORY_STATUS_INSUFFICIENT_SUPPLY = -2
  • int INVENTORY_STATUS_ITEM_NOT_FOUND = -3

Inventory Repository


ATG Commerce comes with two repositories that are relevant to the inventory system:

  • The Product Catalog stores prices, descriptions, images, and fulfiller information.
  • The Inventory Repository stores the stockLevel, availability information, and other inventory data.
Each inventory method takes an ID from the product catalog and uses that information to get the inventory ID.

Inventory definition : atg/commerce/inventory/inventory.xml

Properties :
  • creationDate :The date this inventory item was created.
  • startDate :The inventory item will not be available until this date.
  • endDate:The inventory item will not be available after this date.
  • displayName:The name that is displayed to the user to represent this inventory item.
  • description:A description of this inventory item.
  • catalogRefId : The SKU ID in the Product Catalog to which this inventory item refers.
  • availabilityStatus :The status of this inventory item. It is an enumerated type. The integer code for each possible value is shown. The following codes represent availability status:

INSTOCK (1000) - This item is in stock.
OUTOFSTOCK (1001) – This item is out of stock.
PREORDERABLE (1002)- This item may be preordered.
BACKORDERABLE (1003) - This item may be backordered.
DERIVED (1004) - This item’s availabilityStatus should be derived from the values of its stockLevel, backorderLevel, and preorderLevel. DERIVED is the default value for availabilityStatus.
DISCONTINUED (1005) – This item is discontinued.
  • availabilityDate:The date on which this item will be available if not currently available.
  • stockLevel:The amount of stock available for purchase. The value -1 indicates that an infinite amount is available.
  • backorderLevel:The amount of this item that can be backordered. The value –1 indicates that the inventory system accepts an infinite number of backorders for this item.
  • preorderLevel:The amount of this item that can be preordered. The value –1 indicates the inventory system accepts an infinite number of preorders for this item.
  • stockThreshold:If the stockLevel falls below this amount, a warning event is generated.
  • backorderThreshold:If the backorderLevel falls below this amount, a warning event is generated.
  • preorderThreshold:If the preorderLevel falls below this amount, a warning event is generated.




Inventory JMS Messages


The InventoryManager creates Java Messaging Service (JMS) messages for the following events:
  • InventoryThresholdReached
When stocklevel, backorderLevel, or preorderLevel falls below its associated threshold.
The ID number of the item.
Contains : Name of property (stocklevel, backorderLevel, or preorderLevel), Value of property, Value of threshold
  • UpdateInventory
When the stock level increases. (In the RepositoryInventoryManager, it occurs when someone calls inventoryWasUpdated)
Contains : The IDs of all items that have stock available and were previously BACKORDERABLE, PREORDERABLE, or OUT_OF_STOCK.



Allocating Items for an Order

Example, if a customer orders five of item ‘sku-0’ then the inventory system can be used to allocate, or “purchase” that item:

String itemId = "sku-0";
long quantity = 5;
// Assume inventory manager is defined as a property in this class.
InventoryManager inventory = getInventoryManager();
int status = inventory.purchase(itemId, quantity);

The purchase call status at this time is either INVENTORY_STATUS_SUCCEED, or INVENTORY_STATUS_FAIL.
If it is INVENTORY_STATUS_SUCCEED, then everything is ready and processing can continue.
If the status is INVENTORY_STATUS_FAIL, then check the availability status of the item to determine why it failed:

Displaying an Item’s Availability to a Customer :


int availability = inventory.queryAvailabilityStatus(itemId);

Check Availability Status :


int newStatus;

 if(availability == inventory.AVAILABILITY_STATUS_BACKORDERABLE)
newStatus = inventory.backorder(itemId, quantity);

 else if(availability == inventory.AVAILABILITY_STATUS_IN_STOCK)
newStatus = inventory.backorder(itemId, quantity);

 else if(availability == inventory.AVAILABILITY_STATUS_PREORDERABLE_
newStatus = inventory.preorder(itemId, quantity);

 else  // the only other option is AVAILABILITY_STATUS_OUT_OF_STOCK
newStatus = inventory.INVENTORY_STATUS_FAIL;

The newStatus value INVENTORY_STATUS_FAIL indicates one of the following situations:
  • The item is out of stock.
  • The request is attempting to allocate more items than available.
  • The item is backorderable but the system could not successfully backorder the item. This could occur if the quantity in the order was higher than the number of items available to be backordered.
  • The item is discontinued.

Canceling or Removing an Item from an Order


How to use the inventory manager to cancel or remove an item from the order.

String id = "sku-0";
long quantity = 5;
int itemState = getItemState();
InventoryManager inventory = getInventoryManager();
// now, use the appropriate method, depending on the state
int status;
if(itemState == PENDING_DELIVERY) // normal case
status = inventory.increaseStockLevel(itemId, quantity);
else if(itemState == BACK_ORDERED)
status = inventory.increaseBackorderLevel(itemId,quantity);
else if(itemState == PRE_ORDERED)
status = inventory.increasePreorderLevel(itemId, quantity);

Filling Partial Orders


For example, if a customer orders five towels, but there are only three towels available, you can configure the Fulfillment system to “purchase” as many items as possible and backorder any additional items.

Follow these steps to make the configuration changes:
  • Determine how many items are available using InventoryManager.queryStockLevel().
  • Purchase that amount remaining using InventoryManager.purchase().
Note: It is possible that another customer could purchase these items in the time between when you called queryStockLevel and called purchase. If this is the case, you can either loop until the purchase is successful or there is no inventory left or you can extend the InventoryManager to purchase all items available.
  • Create a new ShippingGroupCommerceItemRelationship in the same shipping group as the item currently being processed and for the same CommerceItem. Set the old relationship’s quantity to whatever was successfully purchased. Set the new relationship’s quantity to the remaining quantity. The state of the old relationship is PENDING_DELIVERY while the state of the new relationship will depend on InventoryManager.queryAvailabilityStatus().



Preventing Inventory Deadlocks


InventoryManager includes the acquireInventoryLocks and releaseInventoryLocks methods.

These methods can be used to prevent deadlocks in the database, especially if there are multiple Oracle ATG Web Commerce instances concurrently updating inventory.
  • acquireInventoryLocks acquires locks for the inventory items that apply to the given IDs. 
  • releaseInventoryLocks releases locks for the inventory items that apply to the given IDs.
RepositoryInventoryManager implements acquireInventoryLocks by calling RepositoryInventoryManager.lock for each id (plus each id within a bundle). It does not implement releaseInventoryLocks since those locks will be released automatically with the end of the transaction.

Example demonstrates how to use these methods to prevent deadlocks:

void myPurchase(List pCatalogRefIds, long pQuantity)
{
   InventoryManager im = getInventoryManager();
   try {
      im.acquireInventoryLocks(pCatalogRefIds);
      Iterator idIterator = pCatalogRefIds.iterator();
      int success;
      while(idIterator.hasNext()) {
         String id = (String) idIterator.next();
         success = im.purchase(id, pQuantity);
         . . .
      }
   }
   finally {
      im.releaseInventoryLocks(pCatalogRefIds);
   }
}




No comments :