Inventory Detail
The Logistics Plus Warehouse Inventory Detail endpoint allows you to retrieve detailed information about your inventory based on serial numbers, quantities, locations, arrival date, and many more properties. Below you will find a table of all fields you can filter, sort, or open string search on.
One of the key differences between this endpoint and the Inventory endpoint is how it handles 'in-progress' inventory movements. LP considers 'in-progress' inventory movements as any order or receipt entered that has not yet been processed by the warehousing team and finalized. Each of the quantities below is affected differently as the orders/receipts are entered and worked on by the warehousing team.
Consider the Following basic Scenarios and how they will affect the quantity fields.
Example Scenarios
A Receive ASN for 5 units of the product 'ABC123' is entered into the system for the warehouse 'EX1'..
availableQuantitywill show as 0 for 'ABC123' at 'EX1' because it has not officially been received by the warehouse yet.unallocatedQuantitywill show as 0 for 'ABC123' at 'EX1' for the same reason.totalQuantitywill show as 5 for 'ABC123' at 'EX1', assuming the ASN has the correct quantity.
The truck arrives at the warehouse and drops off the 5 units of 'ABC123'. The warehousing team puts the product away and marks the Receive ASN as finalized.
availableQuantitywill show as 5 for 'ABC123' at 'EX1' because it is now in the warehouse and available to be picked.unallocatedQuantitywill show as 5 for 'ABC123' at 'EX1' because it is available and there are no current orders for this product.totalQuantitywill show as 5 for 'ABC123' at 'EX1', reflecting the exact quantity available in the warehouse.
An order '123' is placed for 2 units of 'ABC123', but the warehousing team has not yet begun working on it.
availableQuantitywill show as 5 for 'ABC123' at 'EX1' because the pick has not been created or finalized.unallocatedQuantitywill show as 5 for 'ABC123' at 'EX1' because the products from the Receive have not been allocated to this order.totalQuantitywill show as 5 for 'ABC123' at 'EX1', as this is the exact quantity in the warehouse that has not left yet.
The warehousing team begins working on order '123', and the system automatically picks the products from the Receive of 'ABC123'.
availableQuantitywill show as 5 for 'ABC123' at 'EX1' because the pick has not been finalized, and the order can still be canceled.unallocatedQuantitywill show as 3 for 'ABC123' at 'EX1' because 2 units have now been allocated to this order.totalQuantitywill show as 5 for 'ABC123' at 'EX1', as this reflects the exact quantity in the warehouse that has not left yet.
The truck picks up order '123', and the warehousing team finalizes both the pick and the order.
availableQuantitywill show as 3 for 'ABC123' at 'EX1' because the order and pick are now finalized.unallocatedQuantitywill show as 3 for 'ABC123' at 'EX1' because the products are allocated to the finalized order.totalQuantitywill show as 3 for 'ABC123' at 'EX1', reflecting the exact quantity that exists in the warehouse and has not left yet.
An accident happens at the warehouse and 2 of the 3 products are damaged. These products are put into a 'Hold' status. Two separate data segments will begin appearing. The first will show the products that are available for order. The second will be the products that are in held status.
1.For the undamaged and available inventory
availableQuantitywill show as 1 for 'ABC123' at 'EX1' because this is what is left of the original 5 that came in.unallocatedQuantitywill show as 1 for 'ABC123' at 'EX1' because this product has not been allocated to any outbound order yet.totalQuantitywill show as 1 for 'ABC123' at 'EX1', reflecting the exact quantity that exists in the warehouse is available to be used.
2.For the damaged and held inventory
availableQuantitywill show as 0 for 'ABC123' at 'EX1' because none of the held products are available to be used on orders.unallocatedQuantitywill show as 0 for 'ABC123' at 'EX1' because of the same reason.totalQuantitywill show as 2 for 'ABC123' at 'EX1', reflecting the exact quantity of items that are held.
Here are some key fields in the structure to understand:
- The
availableQuantityfield represents the quantity of the product that is available to be picked.
If the inventoryStatus is not AVL, availableQuantity will show 0.
- The
unallocatedQuantityfield represents the quantity of the product that has not been assigned to a specific order. - The
totalQuantityfield represents the quantity of the product that is physically in the warehouse regardless of theinventoryStatus.
Pagination Fields
Serial number, Product Attributes, and Custom Attributes all require configuration before they are able to be utilized.
| Field | Type | Filterable | Sortable | Open Search Compatible | Operators |
|---|---|---|---|---|---|
| WarehouseCode | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| ProductCode | string | ✓ | ✓ | ✓ | Equal, Contains |
| CommodityCode | string | ✓ | ✓ | ✓ | Equal, Contains |
| DocketReference | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| PrimaryReference | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| SecondaryReference | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| InventoryStatus | string | ✓ | ✓ | Equal | |
| TotalQuantity | decimal | ✓ | ✓ | Equal, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, Between, NotBetween | |
| AvailableQuantity | decimal | ✓ | ✓ | Equal, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, Between, NotBetween | |
| ArrivalDate | date | ✓ | ✓ | GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, Between, NotBetween | |
| DaysOnHand | decimal | ✓ | ✓ | Equal, GreaterThan, LessThan, GreaterThanOrEqual, LessThanOrEqual, Between, NotBetween | |
| SerialNumber | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| ProductAttribute1 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| ProductAttribute2 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| ProductAttribute3 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| CustomAttribute1 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| CustomAttribute2 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| CustomAttribute3 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| CustomAttribute4 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| CustomAttribute5 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
| CustomAttribute6 | string | ✓ | ✓ | ✓ | Equal, Contains, BeginsWith, EndsWith |
You can filter and sort the results by any of the fields listed above. You can also paginate the results to retrieve large amounts of data without overwhelming your system.
To use the Inventory Detail endpoint you need to send a POST request to
warehouse/v1/inventory/detail with a body that includes a pagination object.
Example Request
{
"filters": [
{
"field": "WarehouseCode",
"operator": 0, // can be used interchangeably with "Equal"
"arg1": "SIW"
},
{
"field": "PALLET GROUP ID",
"operator": 0,
"arg1": "12345678"
}
],
"sort": {
"sortBy": "WarehouseCode",
"sortDirection": 3
},
"filterString": null,
"page": {
"pageNumber": 1,
"pageSize": 1000
}
}
An example response based on the payload above. This is querying based on a product attribute that is configured to be "PALLET GROUP ID".
Example Response
{
"data": [
{
"productCode": "0101API2",
"productDescription": "APITEST131",
"productUnit": "UNT",
"warehouseCode": "SIW",
"primaryReference": "12345678",
"secondaryReference": "PO00001234",
"docketId": "W00348705",
"location": "FLOOR-1-1-1",
"locationType": "FRE",
"inventoryStatus": "AVL",
"availableQuantity": 10,
"unallocatedQuantity": 10,
"totalQuantity": 10,
"arrivalDate": "2023-05-21T15:37:00Z",
"estimatedArrivalDate": "2023-06-01T10:00:00Z",
"daysOnHand": 164,
"palletId": "W00348705-0001",
"productAttributes": [
{
"type": "string",
"source": "PartAttribute1",
"key": "PALLET GROUP ID",
"value": "12345678"
},
{
"type": "string",
"source": "PartAttribute2",
"key": "PALLET ID",
"value": "12345678"
}
],
"lineAttributes": []
}
],
"id": "2a21f35c551e49279efb85d90854642c",
"resource": [
{
"id": "9af414b0-7203-46eb-bb89-3b4ca1ebc40e",
"type": "PaginationInfo",
"attributes": {},
"data": {
"hasPrevious": false,
"hasNext": false,
"totalPages": 1,
"hits": 1,
"totalHits": 1
}
}
],
"errors": []
}
Pagination Overview
The Pagination class is used to represent and manipulate paginated data. It contains the following properties:
Filters: A list of filters to apply to the data.Sort: ASortobject that specifies how the data should be sorted.Page: APaginateobject that specifies the current page and page size.FilterString: Avaluethat will be used to filter across the defined open search fields. see open search fields section for more detail.
Filter
The Filter class represents a single filter that can be applied to the data. It contains the following properties:
Field: The name of the field to filter on. required.Operator: Theoperatorto use for the filter. defaults to equal.Arg1: The first argument for the filter. required.Arg2: The second argument for the filter. nullable.
It's important to note that the types defined in the specific domain configurations are deserialized by our system. Therefore, you should always pass any arguments for Arg1 or Arg2 as strings.
An Operator defines the different operators that can be used for filters. It contains the following values:
Equal- 0NotEqual- 1LessThan- 2GreaterThan- 3LessThanOrEqual- 4GreaterThanOrEqual- 5Contains- 6NotContains- 7BeginsWith- 8NotBeginsWith- 9EndsWith- 10NotEndsWith- 11In- 12NotIn- 13Between- 14NotBetween- 15
You may pass either "Equal" or 0 to the operator field on the payload. If you pass nothing it will default to 0 (Equal).
Validation Behavior
This section details the validation behavior for the various fields on the 'Filter' object within a pagination request. Each one of these cases will respond with a list of valid values if you happen to pass an invalid value.
Field
For each endpoint that is paginated there will be a set of defined fields that are enabled for filtering. If you pass a field that is not filterable you will receive an invalid request response from the API.
Operator
For each field that is defined there will be a 1 to many operators that are enabled for the field. If you pass an operator that is not enabled for the field you will receive an invalid request response from the API.
Arg
For each field there will be a specific type that it deserializes to once the API receives the paginated request. If you pass "XXX" to a filter for a field that is a number (ie. Quantity) you will receive an invalid request response from the API. Similarly, if you pass something that cannot be parsed into a date for a date field you will receive an invalid request response.
Some fields have certain values that are allowed. For instance, if you pass "XXX" to a field that does not accept that value as an argument, you would receive an invalid request response from the API.
Errors
Invalid filter field: The Field property of a Filter object must be one of the fields that are allowed.
{
"errors": [
{
"status": "400",
"code": "INVALID_REQUEST",
"title": "Field [Pagination.Filters[3].Field] is invalid",
"detail": "The provided value is not valid. you provided 'InvalidField'. Allowed values: (ValidField, AnotherValidField).",
}
]
}
Invalid filter operator: The Operator property of a Filter object must be one of the operators that are allowed for the Field property.
{
"errors": [
{
"status": "400",
"code": "INVALID_REQUEST",
"title": "Field [Pagination.Filters[3].Operator] is invalid",
"detail": "The provided value is not valid for 'ProductCode'. you provided 'Between'. Allowed values: (Equal, Contains).",
}
]
}
Invalid filter argument (Unparsable): The Arg1 and Arg2 properties of a Filter object must be valid values for the Field properties defined type.
{
"errors": [
{
"status": "400",
"code": "INVALID_REQUEST",
"title": "Field [Pagination.Filters[3].Arg2] is invalid",
"detail": "The provided value is not valid for a 'System.Int32' field. you provided 'XXX'.",
}
]
}
Invalid filter allowed value: If the Field property of a Filter object has allowed values, the Arg1 and Arg2 properties must be one of the allowed values.
{
"errors": [
{
"status": "400",
"code": "INVALID_REQUEST",
"title": "Field [Pagination.Filters[0].Arg1] is invalid",
"detail": "The provided value is not valid for 'WarehouseCode'. you provided 'SIX'. Allowed values: (XXX, YYY, ZZZ).",
}
]
}
Sort
The Sort class represents a single sort order that can be applied to the data. It contains the following properties:
SortBy: The name of the field to sort on. required.SortDirection: Thedirectionto sort in, eitherAscendingorDescending. defaults to ascending.
The Direction object defines the different directions that can be used for sorting. It contains the following values:
Ascending- 0Descending- 1
You may pass either "Ascending" or 0 to the field on the payload. If you pass nothing it will default to 0 (Ascending).
Validation Behavior
This section details the validation behavior for the various fields on the Sort object within a pagination request. Each one of these cases will respond with a list of valid values if you happen to pass an invalid value.
SortBy
For each endpoint that is paginated there will be a set of defined fields that are enabled for sorting. If you pass a field that is not sortable you will receive an invalid request response from the API.
SortDirection
While there is no validation for the sort direction, it will default to Ascending if you pass it a value that does not exist or omit the field completely.
Errors
Invalid sort field: The SortBy property of the Sort object must be one of the fields that are configured as sortable.
{
"errors": [
{
"status": "400",
"code": "INVALID_REQUEST",
"title": "Field [Pagination.Sort.sortBy] is invalid",
"detail": "The provided value is not valid. you provided 'InvalidField'. Allowed values: (AValidField).",
}
]
}
Paginate
The Paginate class represents the current page and page size of the paginated data. It contains the following properties:
PageNumber: The current page number.PageSize: The number of items per page.
Validation Behavior
This section details the validation behavior for the various fields on the Paginate object within a pagination request. Each one of these cases will respond with a list of valid values if you happen to pass an invalid value.
PageNumber
If you pass a value that is less than 1 you will receive an invalid request response from the API.
PageSize
For each endpoint there will be a defined minimum and maximum page size. If you pass a number that is outside of that range you will receive an invalid request response from the API.
Errors
Invalid page size: The PageSize property of the Page object must be between 10 and 1000.
{
"errors": [
{
"status": "400",
"code": "INVALID_REQUEST",
"title": "Field [Pagination.Page.PageSize] is invalid",
"detail": "'Page Size' must be between 10 and 1000. You entered 1.",
}
]
}
Invalid page number: The PageNumber property of the Page object must be greater than or equal to 1.
{
"errors": [
{
"status": "400",
"code": "INVALID_REQUEST",
"title": "Field [Pagination.Page.PageNumber] is invalid",
"detail": "'Page Number' must be greater than or equal to '1'.",
}
]
}
Open Search Fields
The FilterString parameter defines the value to search for in the domains defined open search fields.
Each pagination request has access to a defined set of open search fields. For any of those defined open search fields that contain the value provided it will pick up that record.
Example Usage
{
"filters": [
{
"field": "WarehouseCode",
"operator": 0, // can be used interchangeably with "Equal"
"arg1": "SIW"
},
],
"sort": {
"sortBy": "ProductCode",
"sortDirection": 0 // can be used interchangeably with "Ascending"
},
"page": {
"pageNumber": 1,
"pageSize": 10
},
"filterString": "123" // will look through all defined open search fields for anything containing this value.
}