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.
A Receive ASN for 5 units of the product 'ABC123' is entered into the system for the warehouse 'EX1'..
availableQuantity
will show as 0 for 'ABC123' at 'EX1' because it has not officially been received by the warehouse yet.unallocatedQuantity
will show as 0 for 'ABC123' at 'EX1' for the same reason.totalQuantity
will 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.
availableQuantity
will show as 5 for 'ABC123' at 'EX1' because it is now in the warehouse and available to be picked.unallocatedQuantity
will show as 5 for 'ABC123' at 'EX1' because it is available and there are no current orders for this product.totalQuantity
will 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.
availableQuantity
will show as 5 for 'ABC123' at 'EX1' because the pick has not been created or finalized.unallocatedQuantity
will show as 5 for 'ABC123' at 'EX1' because the products from the Receive have not been allocated to this order.totalQuantity
will 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'.
availableQuantity
will show as 5 for 'ABC123' at 'EX1' because the pick has not been finalized, and the order can still be canceled.unallocatedQuantity
will show as 3 for 'ABC123' at 'EX1' because 2 units have now been allocated to this order.totalQuantity
will 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.
availableQuantity
will show as 3 for 'ABC123' at 'EX1' because the order and pick are now finalized.unallocatedQuantity
will show as 3 for 'ABC123' at 'EX1' because the products are allocated to the finalized order.totalQuantity
will 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
availableQuantity
will show as 1 for 'ABC123' at 'EX1' because this is what is left of the original 5 that came in.unallocatedQuantity
will show as 1 for 'ABC123' at 'EX1' because this product has not been allocated to any outbound order yet.totalQuantity
will 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
availableQuantity
will show as 0 for 'ABC123' at 'EX1' because none of the held products are available to be used on orders.unallocatedQuantity
will show as 0 for 'ABC123' at 'EX1' because of the same reason.totalQuantity
will 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
availableQuantity
field represents the quantity of the product that is available to be picked.infoIf the
inventoryStatus
is notAVL
,availableQuantity
will show 0. - The
unallocatedQuantity
field represents the quantity of the product that has not been assigned to a specific order. - The
totalQuantity
field 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 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.
Below is an example payload:
{
"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".
{
"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
: ASort
object that specifies how the data should be sorted.Page
: APaginate
object that specifies the current page and page size.FilterString
: Avalue
that 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
: Theoperator
to 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 a invalid request response from the API.
Operator
For each field that is defined there will be a 1 to many operators that enabled for the field. If you pass a operator that is not enabled for the field you will receive a 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 a 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 except that value as an argument you would receive a 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
: Thedirection
to sort in, eitherAscending
orDescending
. 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 a 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 then 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 response 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
An example json payload for inventory detail pagination.
{
"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.
}