Accurate Fulfillment Dates

Before ordering a product, a shopper may appreciate visibility as to when they would receive it. The Kibo Composable Commerce Platform can calculate accurate fulfillment dates for each product that allow you to offer promised dates to your shoppers. These dates and the inputs used to calculate them are provided for you to use as needed and display on the storefront's product details pages.

These dates and input parameters are returned from the Get Inventory API and Order Routing’s Candidates and Suggest APIs, and are supported for all shipment types and all products with current and/or future inventory.

Product Fulfillment Dates

Fulfillment dates are generally calculated based on the date when the product is available at the fulfillment location + the processing time it takes to prepare the shipment. If transfers are required for an item, then the transfer time will be factored into the calculation as well. 

  • Fulfillment Processing Time: Time taken by a location to fulfill shipments to be ready for ship or pickup. This is used when calculating fulfillment dates for Direct Ship, Transfer, and In Store Pickup products as applicable. These fields are returned in API responses if populated, irrespective of whether the location is enabled for that fulfillment type or not.
  • Receive Processing Time: The time taken by a location to receive inventory and make it ready to fulfill, such as by unloading a truck and processing the inventory. This is only used for incoming inventory (future inventory and transfers). This time is not directly calculated into fulfillment dates— it is up to your implementation to factor it in as needed for incoming inventory. 
  • Transfer Time: This is the approximate time taken to transfer a product from the transfer location to a destination location, measured in either hours or days. This transfer time is irrespective of what location it is sending the transfer to. For example, a warehouse will have the same transfer time to any of the stores it is transferring to.

The rest of this section explains how these values are used to calculate BOPIS and STH fulfillment dates, as well as how to set the processing and transfer times in location settings.

Buy Online Pickup In Store

The fulfillment date for BOPIS products refers to when it will be ready for pickup. This is calculated differently depending on the transfer and available inventory scenario.

  • With Transfers Disabled: Fulfillment Date = Current Date + In Store Pickup Processing Time
  • With Transfers Enabled and Available Inventory at BOPIS Location: Fulfillment Date = Current Date + In Store Pickup Processing Time 
  • With Transfers Enabled and No Available Inventory at BOPIS Location: The system will return all location candidates from the Candidates API with a “transfer fulfillment date” field (Current Date + Transfer Time + Transfer Processing Time). 
    • You are responsible for using this information to display the fulfillment date. Kibo recommends using this information to calculate a date range, as opposed to giving shoppers the exact fulfillment date. This is because the transfer location is not finalized until after the order is placed, so it may have a different fulfillment time than originally estimated and displaying a date range will provide a buffer to account for that.
    • You will need to use: BOPIS Fulfillment Date + Transfer Fulfillment Dates of candidate locations (earliest and last for a date range) + Receive Processing Time (if applicable and used for incoming transfers).
  • With Future Inventory: When current inventory is not enough at the selected BOPIS location or at the transfer locations, then future inventory at the BOPIS location will be used. Future fulfillment dates at the BOPIS location will be calculated as Incoming Inventory Date + In Store Pickup Processing Time. 
    • It is up to you to use the earliest future fulfillment date that will be enough to fulfill the product quantity. You are responsible for adding the Receive Processing Time to this fulfillment date, which should be used any time there is incoming future inventory.

For example, you could display the below messaging on the product details page:

  • Available for in-store pick up today after 3 PM
  • Available for in-store pick up after August 21

Ship to Home

The fulfillment date for Ship to Home products refers to when it will be ready to ship to the customer. The calculation depends on whether there is current inventory available or if future inventory will be used instead.

  • If Current Inventory: Fulfillment Date = Current Date + Direct Ship Processing Time
  • If Future Inventory: Fulfillment Date = Incoming Inventory Date + Direct Ship Processing Time
    • You are responsible for adding the Receive Processing Time to this fulfillment date, which should be used any time there is incoming future inventory.

For example, you could display the below messaging on the product details page:

  • Ready to Ship: Tomorrow
  • Get it soon! Ready to ship by August 21

Ship to Home Consolidation

As Ship to Home Consolidation utilizes transfers, its calculations are similar to those listed above for BOPIS scenarios. As the consolidation location is not yet known when the order is placed, the Candidates API will return fulfillment dates with the location candidates that have partial inventory.

One way that you could use this information for your storefront is to take the earliest and latest fulfillment dates across all locations, buffer with the maximum processing time across all locations, and then add the transfer time. This will generate a date range that accounts for whichever location is selected as the final consolidation location. Remember to factor in the Receive Processing Time for incoming transfer inventory.

Set Processing and Transfer Times

To define the processing and transfer times of locations:

  1. Go to Main > Orders > Locations.
  2. Either select an existing location or create a new location.
  3. In the Processing Time section of the location settings, set the Receive Processing Time followed by the Direct Ship / Transfer and In Store Pickup values. The fields and associated fulfillment dates that use these fields in calculations are returned only if a value has been provided.
  4. Optional: If transfers are enabled, enter a Transfer time for the Transfer Fulfillment Date to be calculated. This should be the time taken to transfer inventory from the transfer location to a destination location. Set the Transfer time unit to determine whether it is measured in hours or days. The Transfer Enabled toggle and transfer time settings
  5. Click Save.

Fulfillment Dates in the API

The Get Inventory and Order Routing APIs return the following fulfillment dates and processing times for current inventory and each future inventory record:

"sthFulfillmentDate": string,
"bopisFulfillmentDate": string,
"transferFulfillmentDate": string,
"bopisProcessingTimeHours": integer,
"sthProcessingTimeHours": integer,
"transferProcessingTimeHours": integer,
"receiveProcessingTimeHours": integer

The processing time input fields are always returned by APIs if they have been configured, irrespective of whether the location specified in the request is enabled for that fulfillment type. However, the fulfillment dates are only returned if the location is enabled for that fulfillment type. For instance, if a location is only STH and Transfer enabled then Order Routing will not return BOPIS fields. Transfer dates will never be returned in cases with Future inventory even if the location is enabled for transfer because future inventory transfers are not supported.

Processing time fields will only be returned if they were set in the location settings. If not set, they will be excluded from the response. Be aware that the transferProcessingTimeHours field is referring to the Transfer Time. If set in days, it is converted to hours and returned. Additionally, the sthProcessingTimeHours field is used for both the Direct Ship Processing Time and Transfer Processing Time as applicable.

Below is an example of a Get Inventory API response that includes all fulfillment date information:

[
    {
        "locationName": "Example Store",
        "locationCode": "B",
        "tenantID": 11111,
        "onHand": 117,
        "available": 117,
        "allocated": 0,
        "pending": 0,
        "sthFulfillmentDate" : "2023-03-29T17:00:00+0000",
        "sthProcessingTimeHours" :  6,
        "bopisFulfillmentDate" : "2023-03-29T17:00:00+0000",
        "bopisProcessingTimeHours" :  6,
        "transferFulfillmentDate" : "2023-03-29T17:00:00+0000",
        "transferProcessingTimeHours" :  5,
        "receiveProcessingTimeHours" :  5,
        "transferTimeHours" :  5,
        "partNumber": "product_2",
        "upc": "product_2",
        "sku": "product_2",
        "blockAssignment": false,
        "ltd": 0,
        "floor": 0,
        "safetyStock": 0,
        "distance": 0,
        "directShip": true,
        "transferEnabled": true,
        "pickup": true,
        "countryCode": "US"
    }
]

Below is an example of the Order Routing Suggest API response that includes all fulfillment date information:

{
    "assignmentSuggestions": {
        "1": [
            {
                "orderItemID": 1,
                "locationID": 010101,
                "locationCode": "8",
                "quantity": 100,
                "route": "DIRECTSHIP",
                "sthFulfillmentDate": "2023-06-26T22:26:39Z",
                "bopisFulfillmentDate": "2023-06-27T00:26:39Z",
		"transferFulfillmentDate": "2023-06-26T22:26:39Z",
                "bopisProcessingTimeHours": 8,
                "sthProcessingTimeHours": 6,
		"transferProcessingTimeHours": 6,
		"receiveProcessingTimeHours": 6,
            }
        ]
    },
    "futureAssignmentSuggestions": {
        "1": [
            {
                "orderItemID": 1,
                "locationID": 010101,
                "locationCode": "8",
                "quantity": 1000,
                "route": "DIRECTSHIP",
                "futureDate": "2023-07-07T20:00:00Z",
                "futureDateString": "2023-07-07T20:00Z",
                "sthFulfillmentDate": "2023-07-08T02:00:00Z",
                "bopisFulfillmentDate": "2023-07-08T04:00:00Z",
		"transferFulfillmentDate": "2023-07-08T02:00:00Z",
                "bopisProcessingTimeHours": 8,
                "sthProcessingTimeHours": 6,
		"transferProcessingTimeHours": 6,
		"receiveProcessingTimeHours": 6,
            }
        ]
    },
    "stateChangeSuggestions": {
        "1": {
            "orderItemID": 1,
            "stateChange": "CUSTOMER_CARE",
            "quantity": 9900
        }
    },
    "availableLocations": [],
    "responseID": 33221100,
    "route": "DIRECTSHIP",
    "emptyResponse": false
}

Below is an example of the Order Routing Candidates API response that includes all fulfillment date information. 

{
    "candidateSuggestions": [
        {
            "locationCode": "7",
            "locationName": "Example Store",
            "city": "Mead",
            "state": "WA",
            "countryCode": "US",
            "postalCode": "99021",
            "distance": "294.357879638671875 mi",
            "latitude": 47.794,
            "longitude": -117.294,
            "express": true,
            "pickup": true,
            "transferEnabled": true,
            "directShip": true,
            "inventory": [
                {
                    "available": 10000,
                    "sthFulfillmentDate": "2023-06-30T07:18:33Z",
                    "bopisFulfillmentDate": "2023-07-01T02:18:33Z",
		    "transferFulfillmentDate": "2023-06-30T07:18:33Z",
                    "bopisProcessingTimeHours": 120,
                    "sthProcessingTimeHours": 101,
	            "transferProcessingTimeHours": 101,
		    "transferProcessingTimeHours": 101,
                    "upc": "example-item"
                }
            ]
        }
    ]
}

Fulfillment dates are also supported for GraphQL real-time inventory service queries and will be returned if requested (which is optional). However, they are not supported on all queries. They are only returned if they make sense for the query and use case.

With Inventory Segmentation

This feature is also supported by inventory segmentation. If future inventory is not also in use, the current inventory fulfillment fields are only displayed within segmentation tags and are the same across segments at the parent level.

If future inventory is in use, then current inventory will be displayed within each tag and have the same fulfillment date for each tag instead of being displayed at the parent level. Each future inventory record within a tag will have its own fulfillment date, because future inventory records are not aggregated and each tag has its own incoming inventory date. 

This is an example of the taggedInventory section of the Get Inventory response, showing fulfillment dates at the tag level for current and future inventory:

"taggedInventory": [
            {
                "onHand": 117,
                "available": 117,
                "allocated": 0,
                "pending": 0,
                "sthFulfillmentDate" : "01/01/2024",
                "bopisFulfillmentDate" : "01/01/2024",
                "transferFulfillmentDate" : "2023-03-29T17:00:00+0000",
                "sthProcessingTimeHours" :  6,
                "bopisProcessingTimeHours" :  6,
                "transferProcessingTimeHours" :  5,
                "receiveProcessingTimeHours" :  5,
                "tags": {
                    "Channel": "Kibo",
                    "OrderType": "STH",
                    "Material": "Plastic",
                    "Color": "Blue",
                    "Shape": "Sphere"
                },
                "futureInventory": [
                    {
                        "futureInventoryID": 1634,
                        "onhand": 200,
                        "available": 200,
                        "allocated": 0,
                        "pending": 0,
                        "type": "Adjust",
                        "deliveryDate": "2024-02-20T17:00:00+0000",
                        "createDate": "2023-06-05T21:14:40+0000",
                        "sthFulfillmentDate" : "01/01/2024",
                        "bopisFulfillmentDate" : "01/01/2024",
                        "sthProcessingTimeHours" :  6,
                        "bopisProcessingTimeHours" :  6,
                        "receiveProcessingTimeHours" :  5,
                    },
                    {
                        "futureInventoryID": 1635,
                        "onhand": 200,
                        "available": 200,
                        "allocated": 0,
                        "pending": 0,
                        "type": "Adjust",
                        "deliveryDate": "2024-02-22T17:00:00+0000",
                        "createDate": "2023-06-05T21:14:46+0000",
                        "sthFulfillmentDate" : "01/01/2024",
                        "bopisFulfillmentDate" : "01/01/2024",
                        "sthProcessingTimeHours" :  6,
                        "bopisProcessingTimeHours" :  6,
                        "receiveProcessingTimeHours" :  5,
                    }
                ]
            }
        ]
    }

Product Delivery Dates

Kibo does not provide product delivery dates, but you can calculate them based on the provided fulfillment date. This section is just one example of how you may determine your own delivery dates.

First, you could set up the below parameters:

  • Marketed Shipping Method = Default shipping method to market, measured in days. 
  • Shipping Method = Shipping method chosen by the customer, measured in days

And then calculate the following delivery dates:

  • Marketed Delivery Date = Fulfillment Date + Marketed Shipping Method
  • Estimated Delivery Date = Fulfillment Date + Shipping Method

Restricted Content

Recommendations for Usage (Internal Only)

Keep the following recommendations in mind when helping clients implement accurate fulfillment dates.

  • When you know the location and there is enough inventory between current and future records, a Get Inventory call will suffice. For example, this would work in the case of BOPIS without transfers.
  • When there is not enough inventory for a future record, look for the next record with enough inventory. You would need the last inventory record that has enough quantity in order to fulfill the requested quantity and display the future date associated with it.
  • In the case of Direct Ship:
    • The Candidates API will return location candidates with fulfillment dates. You have a few options for what to do with this information.
      • Display a single fulfillment date: Pick the location candidate with the earliest incoming delivery date and display the fulfillment date for it.
      • Display a date range: The earliest and last associated fulfillment dates.
    • The Suggest API returns the location that has been suggested. Use the fulfillment date from this location’s inventory record.
  • On the use of individual input parameters for calculations of fulfillment dates:
    • Many clients have complex planning and scheduling systems that determine when an item will be ready for pickup. Having the flexibility of input parameters allows a client to interface with their SLAs and calculate the fulfillment dates as best meets their needs.