When I started to analyze (summer 2015) the possibilities to migrate non-ATP stores to the ATP model the IBM Knowledge Center was claiming the migration was not supported. However, not supported does not mean not possible.

So, I dig it and found a "simple" way to accomplish the migration.

Now (since 2016), finally, the switch of an existing store to the ATP mode is supported again (old version of WCS had even a migration script).

In this brief article I'll report few tips about the "migration" of existing stores to the ATP inventory model.

Target:

WebSphere Commerce professional

Environment:

  • WebSphere Commerce Developer v 7.0.0.9 FEP8
  • WebSphere Application Server 7.0.0.31
  • DB2 9.7
  • SOLR 4.3.0 (local)

A simple flag, STORE.INVENTORYSYSTEM, determines the type of inventory the store manages. Of course, this configuration has an huge impact of the whole order flow and so the handling of the stock.

I started with an extended site store which had the non-ATP model; STORE.INVENTORYSYSTEM was -2. The aim was to switch this store to the ATP model.

The switch to the ATP consist on update this property to -1. However, there are multiple things to take in account since an ATP model is not so trivial to handle.

 

Fulfillment center

The value of the property FFMCENTER.INVENTORYOPFLAGS should be determined answering the following questions:

 

Store

There are multiple properties should be filled in order to set properly the ATP behavior:

 

Scheduled Jobs

For the ATP WCS provides a set of Scheduled Jobs could be key to deliver properly the customer needs.

So, according to the requirements above scheduled jobs should be configured and enabled or merely disabled.

 

ATP data model and data load

One of the highly impacting component is the data load since the ATP data model contains new tables and relationships to deal with.

In particular, the catalog data load should properly fill the following tables- for the correct work of the ATP process-:

The stock have to be loaded now in the table RECEIPT and, according to the specific ATP model needed, there are new tables to fill

 So, the Inventory data load should be accurately planned and implemented.

Most of the effort will be probably spend of the configuration of the data load (to take in account for any eventual plan).

 

Front end and the expected date

Once a product have been configured as backorderable it will appear in the following way (in Aurora) if it's out of stock (no stock in RECEIPT):

b2ap3_thumbnail_2016-03-29_1322.png

Than, the checkout will show the customer when it will be available (the expected date):

b2ap3_thumbnail_2016-03-29_1323.png

In order to properly configure the expected date the data load should fill the tables RA and RADETAIL (as mentioned above).

If these tables are not filled the expected date is calculated according to the property STORE.DEFAULTBOOFFSET.

 

Some useful example of data load CSV files

Example of CSV non-ATP

CurrentStoreIdentifier,PartNumber,CatEntryStoreIdentifier,FulfillmentCenterId,FulfillmentCenterName,Quantity,QuantityUnit,Delete
Sample B2B Store,Cords-Black-29W x 28L,Extended Sites Catalog Asset Store,10101,Madisons Home,201,C62,0


Example of CSV ATP

PartNumber,ParentPartNumber,Type,INVQuantityMeasure,INVQuantityMultiple,TrackingInventory,BackOrderable,ReleaseSeparately,Creditable,ForceBackorder,ReturnNotDesired,MinQTYForSplit,PickingMethod,Discontinued,Delete
Cords-Black-29W x 28L,Cords,ItemBean,C62,1,Y,Y,N,Y,N,N,0,F,N,0

Example of CSV ATP (backorder enabled)

PartNumber,ParentPartNumber,Type,INVQuantityMeasure,INVQuantityMultiple,TrackingInventory,BackOrderable,ReleaseSeparately,Creditable,ForceBackorder,ReturnNotDesired,MinQTYForSplit,PickingMethod,Discontinued,Delete
GSH020_2008,,ProductBean,C62,,,,,,,,,,,
GSH020_200801,GSH020_2008,ItemBean,C62,1,Y,Y,N,Y,N,N,0,F,N,0

Note:

The ATP inventory configuration data are typically loaded together with catalog entry data in a single CSV file for initial loading, because each ATP inventory configuration data is related to a catalog entry record in the database. In this case, CatalogEntryMediator is used to load data.
In another case, catalog entry data are initially loaded by CatalogEntryMediator without ATP inventory configuration data, so default ATP inventory configuration data are loaded in to database. If user wants to modify the ATP inventory configuration data after that, FulfillmentPropertyMediator can be used to load only ATP inventory configuration data without impact to existing catalog entry data.

 

Example of CSV ATP (load the receipt)

PartNumber,CreateTime,ReceiptDate,Quantity,Cost,Currency,VendorName,Comment1,Comment2
GSH020_200801,2015-06-03 01:01:01.123456,2015-06-03 00:00:00.0,1,1,USD,eFEP8 Vendor,comment 1,comment 2

Example of CSV ATP (load the expected date)

VendorName,RACreateTime,PartNumber,ExpectedDate,Quantity,RADetailComment
eFEP8 Vendor,2015-06-02 11:36:01.123456,GSH020_200801,2015-06-28 00:00:00.0,10,radetail comment

 

Some useful query to check the ATP data

Query RECEIPT knowing the CATALOG_ID, STORE_ID and the PARTNUMBER

SELECT RECEIPT_ID, VERSIONSPC_ID, QTYRECEIVED, QTYINPROCESS, QTYONHAND, QTYINKITS FROM RECEIPT WHERE VERSIONSPC_ID IN
    (SELECT VERSIONSPC_ID FROM VERSIONSPC WHERE ITEMSPC_ID IN
        (SELECT ITEMSPC_ID FROM ITEMSPC WHERE BASEITEM_ID IN
            (SELECT BASEITEM_ID FROM STOREITEM WHERE BASEITEM_ID IN
                (SELECT BASEITEM_ID FROM CATENTRY WHERE CATENTRY_ID IN
                    (SELECT CATENTRY_ID FROM CATGPENREL WHERE CATENTRY_ID IN
                        (SELECT CATENTRY_ID FROM CATENTRY WHERE PARTNUMBER = '<PARTNUMBER>')
                          AND CATALOG_ID = <CATALOG_ID>)
                 )
             AND STOREENT_ID = <STORE_ID>)
         AND PARTNUMBER = '<PARTNUMBER>')
    )

 Query ITEMFFMCTR knowing the CATALOG_ID, STORE_ID and the PARTNUMBER

SELECT * FROM ITEMFFMCTR WHERE ITEMSPC_ID IN
    (SELECT ITEMSPC_ID FROM ITEMSPC WHERE BASEITEM_ID IN
            (SELECT BASEITEM_ID FROM STOREITEM WHERE BASEITEM_ID IN
                (SELECT BASEITEM_ID FROM CATENTRY WHERE CATENTRY_ID IN
                    (SELECT CATENTRY_ID FROM CATGPENREL WHERE CATENTRY_ID IN
                        (SELECT CATENTRY_ID FROM CATENTRY WHERE PARTNUMBER = '<PARTNUMBER>')
                          AND CATALOG_ID = <CATALOG_ID>)
                 )
             AND STOREENT_ID = <STORE_ID>)
         AND PARTNUMBER = '<PARTNUMBER>')

 

 

References