When a SKU is bundled into a collection of SKUs, the RepositoryInventoryManager
handles the bundle differently than an individual SKU.
The default Oracle ATG Web Commerce implementation defines bundles as lists of SKUs in the Product Catalog. For more information, see the Using and Extending the Product 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
= 20SKU B
stocklevel
= 20SKU 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
, andpreorderLevel
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.
isBundle
purchaseBundle
purchaseBundleOffBackorder
purchaseBundleOffPreorder
preorderBundle
backorderBundle
queryBundleStocklevel
queryBundleBackorderLevel
queryBundlePreorderLevel
queryBundleStockThreshold
queryBundleBackorderThreshold
queryBundlePreorderThreshold
queryBundleAvailabilityDate
deriveBundleAvailabilityStatus