> ## Documentation Index
> Fetch the complete documentation index at: https://developer.fabric.inc/llms.txt
> Use this file to discover all available pages before exploring further.

# Inventory Setup

This document is intended for merchants and their SI (System Integrator) partners who want to set up inventory. It describes the rules and procedures to set up inventory as per the business need.

To set up inventory:

1. [Create Location](#create-location)
2. [Update Product Information](#update-product-information-optional)
3. [Create a Network](#create-a-network)
4. [Create or Update Inventory](#create-or-update-inventory)

Refer to the following sections for additional information:

* [Search Inventory](#query-inventory)
* [Rules for Updating Counter Quantity](#rules-for-updating-counter-quantity)

**General Rules:**

* If you are using a third-party product information management system other than fabric’s Product Catalog, you must provide product details to fabric in a `.csv` file. For details, see the [Update Product Information](#updateproductinfo) section. If you are already using fabric’s Product Catalog to maintain product information, ignore this step.
* To create or update inventory, you must provide `sku`, `itemId`, `location`, `channelId`, and `counters`. You can provide other details to configure the inventory based on your requirements. For details, see the [Create Inventory](#create-or-update-inventory) section.
  * If you are using only the *Inventory service* of fabric (not the entire OMS service), you must mention allocated and shipped counter quantities to update inventory. If you are using fabric’s OMS to manage inventory and order fulfillment, allocated and shipped counter quantities will be taken care of automatically.
* Use the `onHand` counter to represent the inventory quantity that's currently in stock for selling. Per the `onHand` counter value passed in the request body, `availableToPurchase` (the virtual counter) quantity is calculated, based on the formula `onHand - allocated - shipped - safetyStock`. `safetyStock` is also subtracted if you include `safetyStock` value while creating inventory.
* Subscribe to any of the inventory webhook events to get a notification for inventory updates. For sample curl and other details, see [List of Webhook Events](/v3/orders-and-inventory/api-reference/orders/developer-guide/list-of-webhook-events).

### Create location

**API Mapping:** POST/v3/locations

Using the `POST/v3/locations` endpoint, you can create records for your stores, with details including postal code, hours of operation, BOPIS enabled, and other custom attributes that are applicable to your business.

**Request Sample:**

```JSON theme={null}
{
  "locationNumber": 23,
  "name": "Seattle Store",
  "isActive": true,
  "address": {
    "addressLine1": "123 Main St.",
    "addressLine2": "Suite 100",
    "addressLine3": "Seventh floor",
    "addressLine4": "Attention: Pat E. Kake",
    "city": "Seattle",
    "region": "WA",
    "postalCode": "98121",
    "countryCode": "US",
    "type": "Home",
    "contacts": [
      {
        "type": "OFFICE",
        "email": "[[email protected]](/cdn-cgi/l/email-protection)",
        "phone": [
          {
            "number": "0281923712",
            "type": "MOBILE"
          }
        ],
        "name": {
          "firstName": "Pat",
          "middleName": "E",
          "lastName": "Kake"
        }
      }
    ]
  },
  "type": "DC",
  "services": {
    "brand": "WHBM",
    "channel": "Frontline"
  },
  "operatingHours": [
    {
      "day": "SUNDAY",
      "hours": [
        {
          "open": "10",
          "close": "20",
          "type": "PICK_UP"
        }
      ]
    }
  ],
  "coordinates": {
    "type": "Point",
    "coordinates": [
      -122.3493,
      47.6205
    ]
  },
  "attributes": {
    "isReturns": "true"
  }
}
```

**Response Sample:**

```JSON theme={null}
{
  "locationId": "9372919a8219e8",
  "locationNumber": 23,
  "name": "Seattle Store",
  "isActive": true,
  "address": {
    "addressLine1": "123 Main St.",
    "addressLine2": "Suite 100",
    "addressLine3": "Seventh floor",
    "addressLine4": "Attention: Pat E. Kake",
    "city": "Seattle",
    "region": "WA",
    "postalCode": "98121",
    "countryCode": "US",
    "type": "Home",
    "contacts": [
      {
        "type": "OFFICE",
        "email": "[[email protected]](/cdn-cgi/l/email-protection)",
        "phone": [
          {
            "number": "0281923712",
            "type": "MOBILE"
          }
        ],
        "name": {
          "firstName": "Pat",
          "middleName": "E",
          "lastName": "Kake"
        }
      }
    ]
  },
  "type": "DC",
  "createdAt": "2022-05-25T07:58:30.996Z",
  "updatedAt": "2022-05-25T07:58:30.996Z",
  "operatingHours": [
    {
      "day": "SUNDAY",
      "hours": [
        {
          "open": "10",
          "close": "20",
          "type": "PICK_UP"
        }
      ]
    }
  ],
  "coordinates": {
    "type": "Point",
    "coordinates": [
      -122.3493,
      47.6205
    ]
  }
}
```

### Update Product Information (Optional)

**Note:** This step is required if you are using product management software other than fabric's Product Catalog. If you are using fabric's Product Catalog to maintain your product data, this step isn't required as product data will automatically be imported to the Catalog Connector.

**API Mapping:**

* Use the `PUT/products/{id}` endpoint for updating a single product by ID.
* Use the `PUT/products` endpoint for updating multiple products.

**Sample request to update a single product:**

```JSON theme={null}
{
  "sku": "XP-123345",
  "categoryId": "QWE1234CCVFDDERW21",
  "type": "ITEM",
  "attributes": [
    {
      "id": "6d7329dfd5288b0011332311",
      "value": "blue"
    }
  ],
  "parentProduct": {
    "id": "AASSBCC12334FCD12334V"
  },
  "bundleProducts": [
    {
      "sku": "XP-123345",
      "quantity": 2
    }
  ],
  "variants": [
    {
      "id": "AASSBCC12334FCD12334V"
    }
  ],
  "localizedProperties": {
    "en-US": {
      "attributes": [
        {
          "id": "W123333RRTT555y1",
          "value": "blue"
        }
      ]
    },
    "en-IN": {
      "attributes": [
        {
          "id": "W123333RRTT555AA",
          "value": "blue"
        }
      ]
    }
  }
}
```

**Sample response for updating a single product:**

```JSON theme={null}
{
  "id": "5g7329dfd5288b00113323p7",
  "sku": "QWERTTY56DDFFVVV",
  "type": "ITEM",
  "isActive": true,
  "hasDraft": true,
  "hasLive": true,
  "status": "LIVE",
  "attributes": [
    {
      "id": "227329dfd5288b0011332315",
      "name": "Color",
      "type": "string",
      "isDeleted": false,
      "value": "blue",
      "isInherited": true
    }
  ],
  "localizedProperties": {
    "en-US": {
      "attributes": [
        {
          "id": "637329dfd5288b0011332354",
          "name": "Color",
          "type": "string",
          "isDeleted": false,
          "value": "blue",
          "isInherited": true
        }
      ]
    },
    "en-IN": {
      "attributes": [
        {
          "id": "8f7329dfd5288b0011332334",
          "name": "Colour",
          "type": "string",
          "isDeleted": false,
          "value": "blue",
          "isInherited": true
        }
      ]
    }
  },
  "variants": [
    {
      "id": "967329dfd5288b0011332356"
    }
  ],
  "categoryId": "7f7329dfd5288b0011332378",
  "createdAt": "2021-09-14T22:10:30.618Z",
  "updatedAt": "2021-09-14T22:10:30.618Z"
}
```

### Create a network

**API Mapping:** POST/v3/inventory-networks

* Network refers to a group of locations with a group of SKUs in each location.
* You can create a network to map inventories for the created networks. A network code is generated for the created network. You can mention the network code while creating or updating inventories for a specific network.
* You can configure safety stock quantities for a network while creating a network. Additionally, you can configure safety stock and low stock quantities while creating or updating inventories for a specific network.

**Request Sample:**

```JSON theme={null}
{
  "code": "DC",
  "name": "Distribution Center",
  "safetyStock": 10,
  "description": "network-mar6th",
  "lowStock": 10,
  "rule": {
    "locationData.type": "Store",
    "locationData.attributes.safetyStock": 10,
    "locationData.isActive": true,
    "productData.attributes.brand": "ABC",
    "productData.attributes.isSoldOnline": true
  }
}
```

**Response Sample:**

```{ theme={null}
  "code": "DC",
  "name": "Distribution Center",
  "safetyStock": 10,
  "description": "network-mar6th",
  "lowStock": 10,
  "rule": {
    "locationData.type": "Store",
    "locationData.attributes.safetyStock": 10,
    "locationData.isActive": true,
    "productData.attributes.brand": "ABC",
    "productData.attributes.isSoldOnline": true
  },
  "createdAt": "2022-08-01T18:03:28.483971941Z",
  "updatedAt": "2022-08-01T18:03:28.483971941Z"
}
```

### Create or update inventory

**API Mapping:**

* *POST/v3/inventories:* Create inventory
* *Post/v3/inventories/action/find-and-update:* Update inventory either by replacing existing property value or by adding a new value to an existing property.

1. Set the `infiniteInventory` parameter to `true` to configure unlimited quantities of inventory.
2. Use `customAttributes` to define any custom attribute that suit your business use case. For example, you can set BOPIS (Buy Online Pickup In Store) to `true` if you are willing to allow shoppers to buy online and pick up an item from the store (based on location number).
3. If you provide values for `backOrderLimit` and `preOrderLimit` while creating inventory, `availableBackorder` and `availablePreorder` virtual-counters are displayed in the response object with the same values as provided in the request body.
4. Configure values for `safetyStock` and `lowStock` fields while creating or updating inventory for better inventory management.

**Rules for updating counter quantity:**

* Use the `onHand` counter to represent the inventory quantity that's currently in stock for selling. Based on the `onHand` counter value as passed in the request body, `availableToPurchase` quantity is calculated based on the formula `onHand - allocated - shipped` and displayed in the response object.
* (Not required if you are using the Order module of fabric OMS) Use the “allocated” counter to represent inventory that's sent to warehouses for fulfillment (only the warehouse can cancel the order at this point).
* (Not required if you are using the Order module of fabric OMS) Use the “shipped” counter to represent inventory that's marked as shipped by the warehouse (at this stage in the life-cycle the order can only be returned).
* Use “backorderReserve” and “preOrderReserve” counters (under counter object) to represent inventory quantity that's permitted for backorder (reserve for restock) or pre-order (inventory quantity on launch date).

**Sample request to create or update inventory:**

```JSON theme={null}
{
  "sku": "SKU123",
  "itemId": 12345,
  "locationNum": 999,
  "channelId": "channel1",
  "vendorId": "vendor1",
 "counters": {
    "onHand": 100,
    "allocated": 20,
    "shipped": 10
  },
  "infiniteInventory": true,
  "backOrderDate": "2022-10-21T14:28:06.968Z",
  "preOrderDate": "2022-10-21T14:28:06.968Z",
  "backOrderLimit": 50,
  "preOrderLimit": 40,
  "safetyStock": 10,
  "lowStock": 0,
  "networkCode": "ShipToHome",(get inventory by network)
  "customAttributes": {
    "isRetrun": true,
    "isBopis": true
  },
  "networkCounters": {
    "softReserve": 10
  },
}
```

**Response sample for creating or updating inventory:**

```JSON theme={null}
{
  "sku": "SKU123",
  "itemId": 12345,
  "locationNum": 999,
  "channelId": "channel1",
  "vendorId": "vendor1",
 "counters": {
    "onHand": 100,
    "allocated": 20,
    "shipped": 10
  },
  "infiniteInventory": true,
  "backOrderDate": "2022-10-21T14:28:06.968Z",
  "preOrderDate": "2022-10-21T14:28:06.968Z",
  "backOrderLimit": 50,
  "preOrderLimit": 40,
  "safetyStock": 10,
  "lowStock": 0,
  "networkCode": "ShipToHome",(get inventory by network)
  "customAttributes": {
    "isRetrun": true,
    "isBopis": true
  },
  "networkCounters": {
    "softReserve": 10
  },
"virtualCounters": {
    "availableToPurchase": 60,
    "availableBackorder": 50,
    "availablePreorder": 40
  }
}
```

### Query inventory

After you successfully create an inventory, you can query for inventory information either using the Copilot user interface or using the `POST/v3/inventories/actions/find` endpoint.

* While searching for inventory information, you must include SKU and network code (if you have created a network) as query parameters to get the “Available to Purchase” information.
* While searching for an inventory of type BOPIS (Buy Online Pickup In Store), you must include SKU, `locationNum`, and `channelId` to get information for BOPIS.

**Sample request:**

```JSON theme={null}
{
  "skus": [
    "SKU1"
  ],
  "itemIds": [
    127122871
  ],
  "locationNumbers": [
    12
  ],
  "locationTypes": [
    "DC"
  ],
  "segments": [
    "B2B_Special"
  ],
  "region": "North America",
  "networkCodes": [
    "4"
  ]
}
```

**Sample response:**

```JSON theme={null}
{
  "pagination": {
    "limit": 10,
    "offset": 1,
    "count": 1000
  },
  "data": [
    {
      "inventoryId": "723910d81723",
      "sku": "SKU1",
      "itemId": 12345,
      "locationNumber": 12345,
      "region": "North America",
      "channelId": "channel_xyz",
      "vendorId": "vendor1",
      "createdAt": "2022-08-01T18:03:28.483971941Z",
      "updatedAt": "2022-08-01T20:03:28.483971941Z",
      "leadTime": "5 days",
      "type": "primary",
      "hasInfiniteInventory": false,
      "backorderShipmentAt": "2022-08-01T20:03:28.483971941Z",
      "preorderShipmentAt": "2022-08-01T20:03:28.483971941Z",
      "backorderLimit": 50,
      "preorderLimit": 40,
      "safetyStock": 10,
      "lowStock": 10,
      "networkCode": "ShipToHome",
      "counters": {
        "onHand": 100,
        "allocated": 10,
        "shipped": 20
      },
      "customAttributes": {
        "isBopis": true
      },
      "networkCounters": {
        "softReserve": 10
      },
      "virtualCounters": {
        "availableToPurchase": 60
      }
    }
  ]
}
```

### Rules for updating counter quantity

* **In stock:** Use the `onHand` counter in the request body to represent inventory that's currently available in the location to sell.
* **In Stock for BOPIS (Buy Online Pickup In Store) for an SKU in a specified radius of zip code or postal code:**
  * Use the `onHand` counter to represent in-stock inventory.
  * Define BOPIS using the `customAttribute` field while creating or updating inventory.
  * Zip code or postal code is identified based on the location number. A location number is generated for a location for which you provide all details such as name, address, type, zip or postal code, and more information while creating the location using the `create location` endpoint.
* **In Stock for BOPIS in a specified store:**
  * Use the `onHand` counter to represent in-stock inventory.
  * Define BOPIS using the `customAttribute` field while creating or updating inventory. A specific store is identified by the location number.
* **Adjust inventory records by increasing or decreasing counter quantity:**
  * Use the `onHand` counter to represent in-stock inventory.
  * Use the `POST/v3/inventories/actions/find-and-adjust-inventory-counters` endpoint to adjust counter quantity. You can provide the SKU, location, and counter quantity in the request payload to adjust the `onHand` counter quantity. Counter quantity accepts both positive and negative values. Based on the value you specify in the request payload for the counter quantity, the original counter quantity is either decreased or increased. For example, if the original counter quantity is 100, and you specify the counter quantity as "-10" in the request payload, then the updated `onHand` counter becomes 90.
* **Displaying Backorder, Preorder, Safety Stock, and Low Stock on Website:**
  * If the `availableToPurchase` value is greater than zero, then calculate if the `availabletoPurchase` quantity is greater than the `safetyStock` value.
    * If `availableToPurchase` quantity is greater than 0, then display the item as **in-stock**.
    * If `availableToPurchase` quantity is equal to 0 and `availableBackorder` is greater than 0, then display the item as **in-stock-for-backorder**.
    * If *Available* and *Backorder* are both out of stock, and `availableToPreorder` is greater than 0, then display the item as **in-stock-for-preorder**, else display the item as **out-of-stock**.
    * If the item is a `Backorder` or `Preorder` item, then display the expected restock date (backorderDate) or expected product launch date (preOrderDate)
