When a SKU is bundled into a collection of SKUs, the RepositoryInventoryManager handles the bundle differently than an individual SKU.

The default ATG Commerce implementation defines bundles as lists of SKUs in the Product Catalog. For more information, see the Using and Extending the Standard Catalog chapter. SKUs that represent a bundle have a bundleLinks property that is a list of each skuLink in the bundle. Each skuLink contains a quantity and a SKU (from the Product Catalog).

SKUs that do not represent a bundle correspond to one item in the inventory repository and have an empty bundleLinks list. In this way, new bundles can be defined in the product catalog, without referring to or updating the inventory repository. Alternatively, bundles can be defined within the inventory as a separate inventory item by extending the RepositoryInventoryManager. Information on extending the RepositoryInventoryManager is described in this section.

The RepositoryInventoryManager calculates the stocklevel of a bundle based on the stockLevel of each item in bundle. These values are kept up to date in real time in each query method. The stockLevel is the largest number of bundles that could be purchased given the stocklevel of the SKUs in the bundle. For example:

The Bundle SKU D contains

  • 1 of SKU A

  • 2 of SKU B

  • 10 of SKU C

The stocklevel values for the individual SKUs are:

  • SKU A stocklevel = 20

  • SKU B stocklevel = 20

  • SKU C stocklevel = 20

Therefore, SKU D’s (the bundle’s) stocklevel=2 because that is how many bundles could successfully be purchased given the current inventory.

A bundle’s backorderLevel and preorderLevel are calculated in a similar way.

RepositoryInventoryManager sets the threshold of bundles as 0 to prevent events from being triggered when purchasing a bundle. If one of the bundle’s SKUs falls below its threshold, an event is triggered. This is true for the stockThreshold, backorderThreshold, and preorderThreshold.

The availabilityDate of a bundle is the latest availabilityDate of the SKUs in the bundle. The availabilityStatus of a bundle is calculated as follows:

  • OUT_OF_STOCK – Indicates that at least one of the bundled items is OUT_OF_STOCK or that the stockLevel, backorderLevel, and preorderLevel are all below the quantity needed for one bundle.

  • PREORDERABLE – Indicates that none of the items is OUT_OF_STOCK, but at least one of the bundled items is PREORDERABLE.

  • BACKORDERABLE – Indicates that none of the items are OUT_OF_STOCK or PREORDERABLE, but at least one of the items is BACKORDERABLE.

  • IN_STOCK – Indicates that all of the bundled items are IN_STOCK with a stockLevel greater than the quantity of the item included in one bundle.

When a bundle is purchased, the call is successful if all of the bundled SKUs are IN_STOCK. If it is successful, the stocklevel of each SKU is decreased by the number of bundles purchased multiplied by the number of SKUs contained in the bundle. In the example above if someone successfully purchased the Bundle, the stocklevel of SKU A would be decreased to 19, the stocklevel of SKU B to 18, and the stocklevel of SKU C to 10.

Bundle processing makes it possible for a SKUs backorderLevel to decrease even if there are enough items in stock. Consider the example above replacing SKU A’s stockLevel with 0. The bundle is not IN_STOCK now. Assume that all the items have a backorderLevel of 100. The fulfillment framework will try to backorder the bundle. The RepositoryInventoryManager will set SKU A’s backorderLevel to 99, SKU B’s backorderLevel to 98, and SKU C’s backorderLevel to 90 even though there is stock available for SKU B and SKU C. When the fulfillment framework later calls purchaseOffBackorder, each backorderLevel will be increased back to 100 (assuming no one else backordered the items in the meantime) and each stockLevel will be decreased as described above.

When the HardgoodFulfiller receives an UpdateInventory message, it looks for orders that contain items with the catalogRefId specified in the UpdateInventory message. The items also must have a ShippingGroupCommerceItemRelationship in BACK_ORDERED, PRE_ORDERED, or OUT_OF_STOCK state. Therefore, if an item is a bundle, the catalogRefId of the bundle needs to be included in the message for orders waiting on that bundle to be updated. It is not sufficient to include only the component of the bundle that was updated.

Building a Store without Bundles

RepositoryInventoryManager can be used as the inventory system for a store even if it does not have bundles. If your system does not include bundles, then none of the items will be treated as bundled. If you don’t want SKUs with a non-empty bundleLinks property to be treated as bundles, extend the RepositoryInventoryManager and override the isBundle() method to always return false. This will force the inventory system to treat all items the same way. Perform the same extension to the RepositoryInventoryManager if you want bundles to be processed in the same way as regular SKUs.

Changing the Bundle Handling

If you want to handle bundles in a different way than described above, but you want process SKUs that are not bundles in the same way, extend the RepositoryInventoryManager and override the bundle-specific methods.

The methods listed below are called with the methods of the InventoryManager API if the ID passed in is a bundle. For example, if purchase(someId) is called and someId refers to a bundle, purchase will call purchaseBundle(someId). These methods are implemented in RepositoryInventoryManager, but not in any of the other classes.

 
loading table of contents...