Copyright © 2005-2022

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

Overview

This guide describes the RESTful API of the OpenWMS.org COMMON Base Service module and its usage. Some general terms and definitions are explained and declared in the first part of the document whereas in the second part the usage of the API is shown in a more use-case-driven approach.

Representation Formats

Basically JSON is used as representation format by default if not otherwise requested or mentioned below. XML format is supported for the index pages as well, but must be requested explicitly. Furthermore a vendor specific JSON format is used to represent resource representations. Therefore it is absolutely required that the Accept header denotes the demanded type. Find the type in the examples below.

Dates in JSON

Date or datetime fields are not treated specially in JSON. Within the scope of this API a date or datetime field is always expected and rendered as JSON String in ISO8601 format with timezone information and milliseconds: yyyy-MM-dd’T’HH:mm:ss.SSSTZD.

Embedded Entities

For the sake of convenience some response entities may included embedded entities or even parts of it. A reference to the actual entity is provided as HAL link as well.

Error Responses

Beside the actual representation of resources, the server may result an error response in JSON format that contains basic information about the error occurred. This information is additional to the standard HTTP status code and may help clients to identify the error cause in order to re-phrase and send the request again.

Currently there are two types of errors with their own response formats.

Server Declined Errors

This kind of errors are sent by the server runtime environment even before the request had a chance to be processed.

An example response looks like this:

{
    "timestamp": 1512400854941,
    "status": 500,
    "error": "Internal Server Error",
    "exception": "org.ameba.oauth2.InvalidTokenException",
    "message": "JWT expired at 2017-12-04T15:04:43Z. Current time: 2017-12-04T15:20:54Z, ...",
    "path": "/v1/transport-units?bk=00000000000000004711"
}

The JSON structure contains the following fields.

Property Name Description

timestamp

When the error occurred on server side

status

The http status of the error

error

A short error text

exception

Internal class name of the Java exception type

message

A more descriptive error text describing the error in detail

path

The part of the URI for the REST resource that was queried

API Declined Errors

Those errors are thrown within the REST API validation and processing logic. For example, if a client request does not match the expected format or has produced an error on server side, the API will decline the request and return a response with status client-side error (4xx).

The structure of the response is aligned to the RFC7808. An example response looks like this:

{
    "message": "LocationGroup with name [NOT_EXISTS] not found",
    "messageKey": "owms.common.common.lg.notFoundByName",
    "obj" : [ "NOT_EXISTS" ],
    "httpStatus" : "404",
    "class" : "String"
}

The JSON structure contains the following fields.

Property Name Description

message

A short error text

messageKey

An unique identifier across the API that can be used to identify and translate the error message on the client side

obj

An array of possible passed arguments to the message

httpStatus

The http status of the error

class

The arguments type

Following message keys are currently used:

Message Key Description Action

not.found

The requested resource has not been found

The resource does not exist anymore or has never existed. The resource identifier must be verified

owms.common.common.tu.notFoundByBK

The TransportUnit does not exist

Verify the identifying attribute passed to the API

owms.common.common.loc.notFoundByName

The requested Location does not exist

Verify the identifying attribute passed to the API

owms.common.common.lg.notFoundByName

The requested LocationGroup does not exist

Verify the identifying attribute passed to the API

owms.common.common.tut.notFoundByName

The requested TransportUnitType does not exist

Verify the identifying attribute passed to the API

Interaction Map

This chapter describes the actions, respectively the flow of actions, an API consumer can perform to achieve the use cases. The COMMON Service API deals essentially with Locations, LocationGroups and TransportUnits therefore those entities are centric elements in the interaction model and can be referenced from the main index page.

Like human readable websites provide a sitemap, a machine readable API can be visualized with an interaction map. A fully automated RESTful maturity-level-3 API offers index resources beside typical business resources. The API entry point is the top-level index resource that is used to navigate to all possible entities with their operations.

common service index

This top-level, or root, index page offers further links to primary resources, like Locations, LocationGroups and TransportUnits.

Resources

A description of all used API resources.

ClassDiagram

Index

The initial HTTP request to retrieve information about all available resources looks like the following. The Index page is a public available resource and does not need any authentication.

GET /index HTTP/1.1
Host: localhost:8080

The Index resource is returned in the response body with the response status of 200-OK. This main Index lists all primary resource entities to follow next.

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 515

{
  "_links" : {
    "account-index" : {
      "href" : "http://localhost:8080/v1/accounts/index"
    },
    "location-index" : {
      "href" : "http://localhost:8080/v1/locations/index"
    },
    "location-group-index" : {
      "href" : "http://localhost:8080/v1/location-groups/index"
    },
    "transport-unit-type-index" : {
      "href" : "http://localhost:8080/v1/transport-unit-types/index"
    },
    "transport-unit-index" : {
      "href" : "http://localhost:8080/v1/transport-units/index"
    }
  }
}

A client application must only know about the agreed link names and follow the corresponding href link to navigate further.

Account

An Account reflects to a customers cost center. A project may know about several cost centers - Accounts. The Account information is usually defined at project setup and does not change at runtime. So it is not foreseen that Account instances are created or deleted through the API.

Account Index

The index with all possible operations on Account resources can be retrieved with an GET request:

GET /v1/accounts/index HTTP/1.1
Host: localhost:8080

The response lists all the operations with a name and the corresponding href link:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 502

{
  "_links" : {
    "accounts-findbypkey" : {
      "href" : "http://localhost:8080/v1/accounts/pKey"
    },
    "accounts-findbyidentifier" : {
      "href" : "http://localhost:8080/v1/accounts?identifier=identifier"
    },
    "accounts-findbyname" : {
      "href" : "http://localhost:8080/v1/accounts?name=name"
    },
    "accounts-finddefault" : {
      "href" : "http://localhost:8080/v1/accounts"
    },
    "accounts-findall" : {
      "href" : "http://localhost:8080/v1/accounts"
    }
  }
}

Find an Account by Persistent Id (pKey)

To look up an Account with its unique persistent identifier, a client needs to send a GET request with the persistent identifier as part of the URI.

Find an Account by pKey:

GET /v1/accounts/1000 HTTP/1.1
Host: localhost:8080

The server responds with the Account resource if it exists:

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.account-v1+json
Content-Length: 177

{
  "links" : [ {
    "rel" : "accounts-findbypkey",
    "href" : "http://localhost:8080/v1/accounts/1000"
  } ],
  "pKey" : "1000",
  "identifier" : "D",
  "name" : "Default"
}
Path Type Description

pKey

String

The persistent technical key of the Account

identifier

String

Unique natural key

name

String

Unique Account name

or with a 404-Not Found if no Account with that persistent identifier exists:

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 189

{
  "message" : "Account with PKey [2000] does not exist",
  "messageKey" : "owms.common.common.account.notFoundByPKey",
  "obj" : [ "2000" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find an Account by business key

The name and the identifier of the Account are unique and mandatory attributes. So an Account can be searched for both fields.

Find an Account by name:

GET /v1/accounts?name=Default HTTP/1.1
Host: localhost:8080

or find an Account by identifier:

GET /v1/accounts?identifier=D HTTP/1.1
Host: localhost:8080

The server responds with the Account resource if it exists:

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.account-v1+json
Content-Length: 177

{
  "links" : [ {
    "rel" : "accounts-findbypkey",
    "href" : "http://localhost:8080/v1/accounts/1000"
  } ],
  "pKey" : "1000",
  "identifier" : "D",
  "name" : "Default"
}

or with a 404-Not Found if no Account exists:

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 189

{
  "message" : "Account with name [UNKNOWN] does not exist",
  "messageKey" : "owms.common.common.account.notFound",
  "obj" : [ "UNKNOWN" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find the default Account

At least one Account must exist in the system and must be defined as the default Account. This Account is used when no other account information is available. To get the default Account a GET request must be send to the server

GET /v1/accounts?default=true HTTP/1.1
Host: localhost:8080

The server sends back the Account resource if it exists

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.account-v1+json
Content-Length: 177

{
  "links" : [ {
    "rel" : "accounts-findbypkey",
    "href" : "http://localhost:8080/v1/accounts/1000"
  } ],
  "pKey" : "1000",
  "identifier" : "D",
  "name" : "Default"
}

Otherwise a 404-Not Found if it doesn’t exist

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 133

{
  "message" : "No default Account exists",
  "messageKey" : "owms.common.common.account.noDefaultAccount",
  "httpStatus" : "404"
}

Find all Accounts

To retrieve a list of all existing Accounts a client must send a GET request to the server

GET /v1/accounts HTTP/1.1
Host: localhost:8080

The response contains all existing Accounts

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.account-v1+json
Content-Length: 369

[ {
  "links" : [ {
    "rel" : "accounts-findbypkey",
    "href" : "http://localhost:8080/v1/accounts/1000"
  } ],
  "pKey" : "1000",
  "identifier" : "D",
  "name" : "Default"
}, {
  "links" : [ {
    "rel" : "accounts-findbypkey",
    "href" : "http://localhost:8080/v1/accounts/1001"
  } ],
  "pKey" : "1001",
  "identifier" : "A1",
  "name" : "Cost Center FIN"
} ]

Location

A Location represents a physical or virtual place in a warehouse. Could be something like a storage location in the stock or a location on the conveyor. Even error locations can be represented with the Location. Multiple Locations with same characteristics are grouped to a LocationGroup.

A Location is identified by the 5-tuple coordinate, the LocationID, as well as a persistent key (the pKey). The PLC Code is an additional identifier of a Location that might be null in project setups. It is the identifying name a PLC unit uses in automatic warehouses - not used in manual warehouses.

A Location always belongs to a LocationGroup where the name of that group is stored in the locationGroupName property.

A Location can be a Target to send TransportUnits to, i.e. the target of an automatic TransportOrder or a manual Movement.

Multiple state properties with different meaning exist for a Location. The plcState is exclusively managed by the PLC in automatic warehouses. Any error signaled by the PLC are stored on this field with a value greater than 0. Two other state fields incomingActive and outgoindActive are used to control the material flow control of this Location. If incomingActive is set to false, the particular Location is not considered in Inbound activities, like Putaway. Whereas the outgoindActive can be set to false to lock Outbound operations off this Location.

The API allows to search for Locations and to mutate the Locations state.

Location Index

The Location Index with all possible operations can be retrieved with the following GET request:

GET /v1/locations/index HTTP/1.1
Host: localhost:8080

The response lists all the operations with a name and the corresponding href link:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 1041

{
  "_links" : {
    "location-create" : {
      "href" : "http://localhost:8080/v1/locations"
    },
    "location-updatelocation" : {
      "href" : "http://localhost:8080/v1/locations"
    },
    "location-findbypkey" : {
      "href" : "http://localhost:8080/v1/locations/pKey"
    },
    "location-findbycoordinate" : {
      "href" : "http://localhost:8080/v1/locations?locationId=AREA%2FAISLE%2FX%2FY%2FZ"
    },
    "location-findbycoordinate-wc" : {
      "href" : "http://localhost:8080/v1/locations?area=area&aisle=aisle&x=x&y=y&z=z"
    },
    "location-findbyerpcode" : {
      "href" : "http://localhost:8080/v1/locations?erpCode=ERP_CODE"
    },
    "location-findbyplccode" : {
      "href" : "http://localhost:8080/v1/locations?plcCode=PLC_CODE"
    },
    "location-forlocationgroup" : {
      "href" : "http://localhost:8080/v1/locations?locationGroupNames=LG1&locationGroupNames=LG2"
    },
    "location-changestate" : {
      "href" : "http://localhost:8080/v1/location/pKey?op=change-state&op=change-state"
    }
  }
}

Create a Location

Usually Locations are created as static reference data when the project is setup. It is not intended to create a Location during normal warehouse operation. Warehouse locations are fixed and do only change when the warehouse is extended, therefore it makes less sense to create Locations on the fly or delete them in operation.

Nevertheless there is an API to create a Location via the REST API that might be used for automatic data migration from a legacy system to OpenWMS.org.

A client sends a POST request with the Location representation in the request body

POST /v1/locations HTTP/1.1
Content-Type: application/json
Accept: application/vnd.openwms.common.location-v1+json
Content-Length: 171
Host: localhost:8080

{
  "links" : [ ],
  "locationId" : "FGIN/PICK/WORK/0010/0000",
  "plcCode" : "PICK_20",
  "erpCode" : "PICK_10",
  "type" : "PG",
  "locationGroupName" : "FGWORKPLACE9"
}
Path Type Description

locationId

String

Unique natural key

plcCode

String

PLC code of the Location

erpCode

String

ERP code of the Location

type

String

The name of the LocationType the Location belongs to

locationGroupName

String

The LocationGroup the Location belongs to

If the server has successfully created the Location the response looks like

HTTP/1.1 201 Created
Location: http://localhost:8080/v1/locations/ee45c0b3-0e11-4581-ba28-186da77e68fe/
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 434

{
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/ee45c0b3-0e11-4581-ba28-186da77e68fe"
  } ],
  "ol" : 0,
  "pKey" : "ee45c0b3-0e11-4581-ba28-186da77e68fe",
  "locationId" : "FGIN/PICK/WORK/0010/0000",
  "plcCode" : "PICK_20",
  "erpCode" : "PICK_10",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "PG",
  "locationGroupName" : "FGWORKPLACE9"
}
Path Type Description

pKey

String

The persistent technical key of the Location

locationId

String

Unique natural key

plcCode

String

PLC code of the Location

erpCode

String

ERP code of the Location

incomingActive

Boolean

Whether the Location is enabled for incoming movements (read-only)

outgoingActive

Boolean

Whether the Location is enabled for outgoing movements (read-only)

plcState

Number

The current state, set by the PLC system (read-only)

type

String

The name of the LocationType the Location belongs to

locationGroupName

String

The LocationGroup the Location belongs to

Update an existing Location

It’s also possible to modify an existing Location. Therefore the client sends a PUT request with the full representation of the Location resource, including the necessary identifier fields.

PUT /v1/locations HTTP/1.1
Content-Type: application/json
Accept: application/vnd.openwms.common.location-v1+json
Content-Length: 332
Host: localhost:8080

{
  "links" : [ ],
  "pKey" : "1000",
  "locationId" : "FGIN/CONV/0001/0000/0000",
  "accountId" : "A1",
  "plcCode" : "PICK_20",
  "erpCode" : "PICK_10",
  "sortOrder" : 99,
  "stockZone" : "STOCK",
  "incomingActive" : false,
  "outgoingActive" : false,
  "plcState" : 21,
  "type" : "FG",
  "locationGroupName" : "FGWORKPLACE9"
}
Path Type Description

pKey

String

The persistent technical key of the Location

locationId

String

Unique natural key

accountId

String

The ID of the Account, the Location is assigned to

plcCode

String

PLC code of the Location

erpCode

String

ERP code of the Location

sortOrder

Number

Sort order index used by strategies for putaway, or picking

stockZone

String

Might be assigned to a particular zone in stock

incomingActive

Boolean

Whether the Location is enabled for incoming movements (read-only)

outgoingActive

Boolean

Whether the Location is enabled for outgoing movements (read-only)

plcState

Number

The current state, set by the PLC system (read-only)

type

String

The name of the LocationType the Location belongs to

locationGroupName

String

The LocationGroup the Location belongs to

If the server has updated the Location successfully the response looks like

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 437

{
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/1000"
  } ],
  "ol" : 1,
  "pKey" : "1000",
  "locationId" : "FGIN/CONV/0001/0000/0000",
  "accountId" : "A1",
  "plcCode" : "PICK_20",
  "erpCode" : "PICK_10",
  "sortOrder" : 99,
  "stockZone" : "STOCK",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "FGWORKPLACE9"
}
Path Type Description

pKey

String

The persistent technical key of the Location

locationId

String

Unique natural key

accountId

String

The ID of the Account, the Location is assigned to

plcCode

String

PLC code of the Location

erpCode

String

ERP code of the Location

sortOrder

Number

Sort order index used by strategies for putaway, or picking

stockZone

String

Might be assigned to a particular zone in stock

incomingActive

Boolean

Whether the Location is enabled for incoming movements (read-only)

outgoingActive

Boolean

Whether the Location is enabled for outgoing movements (read-only)

plcState

Number

The current state, set by the PLC system (read-only)

type

String

The name of the LocationType the Location belongs to

locationGroupName

String

The LocationGroup the Location belongs to

Find Location by Persistent Id (pKey)

To lookup a Location identified by it’s technical persistent identifier, a client needs to have the identifier on hand and must send a GET request to the identifying URI:

GET /v1/locations/113646454019 HTTP/1.1
Accept: application/vnd.openwms.common.location-v1+json
Host: localhost:8080

If the Location exists the server responds with

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 421

{
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/113646454019"
  } ],
  "ol" : 29,
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0030",
  "erpCode" : "ERP_0030",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
}

If no Location resource with the requested persistent identifier exists, the server responds with

HTTP/1.1 404 Not Found
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 190

{
  "message" : "Location with ID [UNKNOWN] does not exist",
  "messageKey" : "owms.common.common.loc.notFoundByPKey",
  "obj" : [ "UNKNOWN" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find Location by Coordinate

Send a HTTP GET request with the 5-tuple coordinate as query parameter to find a Location identified by this coordinate.

GET /v1/locations?locationId=EXT_/0000/0000/0000/0000 HTTP/1.1
Host: localhost:8080

If the Location exists the server responds with

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-opt-v1+json
Content-Length: 421

{
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/113646454019"
  } ],
  "ol" : 29,
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0030",
  "erpCode" : "ERP_0030",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
}

If the Location with the requested coordinate does not exist, the server responds with

HTTP/1.1 404 Not Found
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 224

{
  "message" : "Location with name [EXT_/9999/9999/9999/9999] does not exist",
  "messageKey" : "owms.common.common.loc.notFoundById",
  "obj" : [ "EXT_/9999/9999/9999/9999" ],
  "httpStatus" : "404",
  "class" : "String"
}

If the passed coordinate is not well formatted and rejected by the server the response looks like

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 214

{
  "message" : "The given Location name [INVALID_COORDINATE] is not valid",
  "messageKey" : "owms.common.common.loc.invalidName",
  "obj" : [ "INVALID_COORDINATE" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find Location by Coordinate with Wildcards

The API to search for Locations also accepts typical SQL wildcards in each part of the 5-tuple coordinate. Let’s assume one searches for all elevator Locations in the Flat Good area, a query could look like this

GET /v1/locations?area=FGIN&aisle=00__&x=LIFT&y=0000&z=%25 HTTP/1.1
Host: localhost:8080

In this case the Flat Good area has only 2 elevator positions and the server returns both

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 864

[ {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/798136030917"
  } ],
  "ol" : 11,
  "pKey" : "798136030917",
  "locationId" : "FGIN/0001/LIFT/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0012",
  "erpCode" : "ERP_0012",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "FGAISLE1LIFT"
}, {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/852306856430"
  } ],
  "ol" : 14,
  "pKey" : "852306856430",
  "locationId" : "FGIN/0002/LIFT/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0015",
  "erpCode" : "ERP_0015",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "FGAISLE2LIFT"
} ]

If the search query did not find any Locations the server responds with

HTTP/1.1 404 Not Found

This wildcard query API can also be used to find and return all existing Locations just by not passing any wildcard at all

GET /v1/locations HTTP/1.1
Host: localhost:8080

Find Location by ERP code

Send a HTTP GET request with the ERP code as query parameter to find a Location identified by this ERP code.

GET /v1/locations?erpCode=ERP_0030 HTTP/1.1
Host: localhost:8080

If the Location exists the server responds with

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-opt-v1+json
Content-Length: 421

{
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/113646454019"
  } ],
  "ol" : 29,
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0030",
  "erpCode" : "ERP_0030",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
}

Find Location by PLC code

Send a HTTP GET request with the PLC code as query parameter to find a Location identified by this PLC code.

GET /v1/locations?plcCode=PLC_0030 HTTP/1.1
Host: localhost:8080

If the Location exists the server responds with

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-opt-v1+json
Content-Length: 421

{
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/113646454019"
  } ],
  "ol" : 29,
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0030",
  "erpCode" : "ERP_0030",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
}

If no Location with the requested PLC code exists, the server responds with

HTTP/1.1 404 Not Found
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 205

{
  "message" : "Location with PLC code [NOT EXISTS] does not exist",
  "messageKey" : "owms.common.common.loc.notFoundByPlcCode",
  "obj" : [ "NOT EXISTS" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find Locations that belong to a LocationGroup

Send a HTTP GET request with the name of a LocationGroup as query parameter to find all Locations that belong to this group.

GET /v1/locations?locationGroupNames=ZILE HTTP/1.1
Host: localhost:8080

The server responds with the list of all Locations - the name of the LocationGroup is not validated.

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 848

[ {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/171919359409"
  } ],
  "ol" : 28,
  "pKey" : "171919359409",
  "locationId" : "INIT/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0029",
  "erpCode" : "ERP_0029",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
}, {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/113646454019"
  } ],
  "ol" : 29,
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0030",
  "erpCode" : "ERP_0030",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
} ]

If no Locations exist that belong to the given LocationGroup the server responds:

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 3

[ ]

The server accepts multiple LocationGroup names as request parameter to get a combined list of Locations that belong to groups with name ZILE and FGRECEIVING:

GET /v1/locations?locationGroupNames=ZILE&locationGroupNames=FGRECEIVING HTTP/1.1
Host: localhost:8080

Returns

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 1277

[ {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/917262708951"
  } ],
  "ol" : 2,
  "pKey" : "917262708951",
  "locationId" : "FGIN/CONV/IN__/0001/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0003",
  "erpCode" : "ERP_0003",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "FGRECEIVING"
}, {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/171919359409"
  } ],
  "ol" : 28,
  "pKey" : "171919359409",
  "locationId" : "INIT/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0029",
  "erpCode" : "ERP_0029",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
}, {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/113646454019"
  } ],
  "ol" : 29,
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0030",
  "erpCode" : "ERP_0030",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "ZILE"
} ]

Wildcards in the LocationGroup name are supported if only one LocationGroup name is provided:

GET /v1/locations?locationGroupNames=IP%25 HTTP/1.1
Host: localhost:8080

The response is a list of Locations that belong to a LocationGroup where the name starts with IP (matching the groups IPOINT, IPOINT1 and IPOINT2 in this example:

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-v1+json
Content-Length: 854

[ {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/439649733836"
  } ],
  "ol" : 30,
  "pKey" : "439649733836",
  "locationId" : "FGIN/IPNT/0001/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0031",
  "erpCode" : "ERP_0031",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "IPOINT1"
}, {
  "links" : [ {
    "rel" : "location-findbypkey",
    "href" : "http://localhost:8080/v1/locations/227916500906"
  } ],
  "ol" : 31,
  "pKey" : "227916500906",
  "locationId" : "FGIN/IPNT/0002/0000/0000",
  "accountId" : "D",
  "plcCode" : "PLC_0032",
  "erpCode" : "ERP_0032",
  "sortOrder" : 0,
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0,
  "type" : "FG",
  "locationGroupName" : "IPOINT2"
} ]

Change a Location’s State

Send a HTTP PATCH request with the persistent identifying key of the existing Location along with the new state decoded as errorCode request parameter.

PATCH /v1/location/NOTEXISTS?op=change-state HTTP/1.1
Content-Type: application/json
Content-Length: 30
Host: localhost:8080

{
  "errorCode" : "******00"
}

If the Location with the given persistent key does not exist, the server responds with

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 194

{
  "message" : "Location with ID [NOTEXISTS] does not exist",
  "messageKey" : "owms.common.common.loc.notFoundByPKey",
  "obj" : [ "NOTEXISTS" ],
  "httpStatus" : "404",
  "class" : "String"
}

The errorCode contains a ternary error bitmap that decodes all state information. It is expected as 8-digit String with allowed symbols *|0|1. Each digit is assigned to one of the state attribute of the Location resp. LocationGroup:

Digit Position (RtL) Assigned attribute

20

Location.incomingActive

21

Location.outgoingActive

22

Location.groupStateIn

23

Location.groupStateOut

The following table shows all accepted decodings of the ErrorCodeVO.errorCode String that is sent as part of the request body:

ErrorCode String Description

********

Content is ignored

******00

Release Location for Inbound and Outbound operations

******01

Lock Inbound operation to the Location

******10

Lock Outbound operation from the Location

******11

Lock Inbound and Outbound operation for the Location

In this example a Location identified with the given persistent key is locked for Inbound operations with the following request:

PATCH /v1/location/113646454019?op=change-state HTTP/1.1
Content-Type: application/json
Content-Length: 30
Host: localhost:8080

{
  "errorCode" : "*******1"
}

If the server could lock the Location successfully the response looks like

HTTP/1.1 204 No Content

Beside locking the Location for Inbound- and Outbound processing it is also possible to change the PLC state of the Location through this API. Therefore the ErrorCodeVO data structure contains a property plcState that can be set to a numeric integer value. Usually a PLC state of 0 means the Location is not blocked and available for any operation. A PLC may set the state to a value greater than 0 to signal an error occurred on the Location.

Set the plcState to 31 (In terms of OSIP this means Location unexpected occupied):

PATCH /v1/location/113646454019?op=change-state HTTP/1.1
Content-Type: application/json
Content-Length: 49
Host: localhost:8080

{
  "errorCode" : "********",
  "plcState" : 31
}

If the server could set the state successfully the response is

HTTP/1.1 204 No Content

Also both is possible in one request, changing the Locations state and the plcState:

PATCH /v1/location/113646454019?op=change-state HTTP/1.1
Content-Type: application/json
Content-Length: 49
Host: localhost:8080

{
  "errorCode" : "******11",
  "plcState" : 31
}

If the server could set both states successfully the response is

HTTP/1.1 204 No Content

LocationType

A LocationType represents the type of a Location. Each Location must belong to one and only one specific LocationType. The type definition basically defines physical dimensions of all Location`s of this type. Usually `LocationTypes are created statically when a project is set up. Types may be changed, but not deleted at runtime, because every Location is assigned to one LocationType only.

LocationType Index

The LocationType Index with all possible operations can be retrieved with the following GET request:

GET /v1/location-types/index HTTP/1.1
Host: localhost:8080

The response lists all the operations with a name and the corresponding href link:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 345

{
  "_links" : {
    "location-types-findbypkey" : {
      "href" : "http://localhost:8080/v1/location-types/pKey"
    },
    "location-types-findbytypename" : {
      "href" : "http://localhost:8080/v1/location-types?typeName=typeName"
    },
    "location-types-findall" : {
      "href" : "http://localhost:8080/v1/location-types"
    }
  }
}

Find a LocationType by its Persistent Id (pKey)

To query a LocationType by it’s technical persistent identifier, a GET request is send to the LocationType resource along with the pKey as part of the URI.

GET /v1/location-types/326981811784 HTTP/1.1
Host: localhost:8080

The server responds with the existing LocationType

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-type-v1+json
Content-Length: 268

{
  "links" : [ {
    "rel" : "location-types-findbypkey",
    "href" : "http://localhost:8080/v1/location-types/326981811784"
  } ],
  "pKey" : "326981811784",
  "type" : "FG",
  "description" : "Flat Good Location",
  "length" : 30,
  "width" : 50,
  "height" : 20
}
Path Type Description

pKey

String

The persistent technical key of the LocationType

type

String

Unique natural key

description

String

A descriptive text of the LocationType

length

Number

The typical length of a Location belonging to this type

width

Number

The typical width of a Location belonging to this type

height

Number

The typical height of a Location belonging to this type

If no LocationType with the given name exists the response looks like

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 193

{
  "message" : "LocationType with ID [UNKNOWN] does not exist",
  "messageKey" : "owms.common.common.lt.notFoundByPKey",
  "obj" : [ "UNKNOWN" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find a LocationType by its name

To query a LocationType by it’s unique name, a GET request is send to the LocationType resource along with the name as query parameter.

GET /v1/location-types?typeName=FG HTTP/1.1
Host: localhost:8080

The server responds with the existing LocationType

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-type-v1+json
Content-Length: 268

{
  "links" : [ {
    "rel" : "location-types-findbypkey",
    "href" : "http://localhost:8080/v1/location-types/326981811784"
  } ],
  "pKey" : "326981811784",
  "type" : "FG",
  "description" : "Flat Good Location",
  "length" : 30,
  "width" : 50,
  "height" : 20
}

If no LocationType with the given name exists the response looks like

HTTP/1.1 404 Not Found

Find all existing LocationTypes

If a client wants to get a list of all existing LocationTypes, a simple GET request to the plural resource is required. Notice that no paging nor sorting is implemented in the API, because the expected retrieved data is less than a hundred entries.

GET /v1/location-types HTTP/1.1
Host: localhost:8080

The server responds with the existing LocationTypes or an empty list:

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.common.location-type-v1+json
Content-Length: 547

[ {
  "links" : [ {
    "rel" : "location-types-findbypkey",
    "href" : "http://localhost:8080/v1/location-types/326981811784"
  } ],
  "pKey" : "326981811784",
  "type" : "FG",
  "description" : "Flat Good Location",
  "length" : 30,
  "width" : 50,
  "height" : 20
}, {
  "links" : [ {
    "rel" : "location-types-findbypkey",
    "href" : "http://localhost:8080/v1/location-types/404376159041"
  } ],
  "pKey" : "404376159041",
  "type" : "PG",
  "description" : "Pallet Good Location",
  "length" : 120,
  "width" : 120,
  "height" : 250
} ]

LocationGroup

A LocationGroup is used to group Locations with same characteristics or to define a warehouse area that can be seen as one cohesive block controlled by one single subsystem.

LocationGroup Index

The index with all possible operations on LocationGroups can be retrieved with a GET request

GET /v1/location-groups/index HTTP/1.1
Host: localhost:8080

The response lists all the operations with a name and the corresponding link

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 690

{
  "_links" : {
    "location-groups-findbyname" : {
      "href" : "http://localhost:8080/v1/location-groups?name=FOO"
    },
    "location-groups-findbynames" : {
      "href" : "http://localhost:8080/v1/location-groups?names=FOO&names=BAR"
    },
    "location-groups-findall" : {
      "href" : "http://localhost:8080/v1/location-groups"
    },
    "location-groups-changestate" : {
      "href" : "http://localhost:8080/v1/location-group/UUID?op=change-state&op=change-state&statein=AVAILABLE&stateout=NOT_AVAILABLE"
    },
    "location-groups-changestate-with-bitmap" : {
      "href" : "http://localhost:8080/v1/location-groups?name=FOO&op=change-state&op=change-state"
    }
  }
}

Find LocationGroup by Name

Send a HTTP GET request with the unique name of the LocationGroup

GET /v1/location-groups?name=FGRECEIVING HTTP/1.1
Host: localhost:8080

Request parameters:

Parameter Description

name

The unique name of the LocationGroup

If the LocationGroup exists the server responds with

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 333

{
  "_links" : {
    "parent" : {
      "href" : "http://localhost:8080/v1/location-groups?name=FGAUTOMATIC"
    }
  },
  "pKey" : "400335177633",
  "name" : "FGRECEIVING",
  "accountId" : "D",
  "parentName" : "FGAUTOMATIC",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}
Path Type Description

pKey

String

The persistent technical key of the LocationGroup

name

String

Unique natural key

accountId

String

The Account identifier the LocationGroup is assigned to

parentName

String

Name of the parent LocationGroup

operationMode

String

The operation mode is controlled by the subsystem and defines the physical mode a LocationGroup is currently able to operate in

groupStateIn

String

State of infeed, controlled by the subsystem only

groupStateOut

String

State of outfeed, controlled by the subsystem only

If the LocationGroup with the given name does not exist, the server responds with

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 202

{
  "message" : "LocationGroup with name [NOT_EXISTS] does not exist",
  "messageKey" : "owms.common.common.lg.notFoundByName",
  "obj" : [ "NOT_EXISTS" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find multiple LocationGroups by Name

Send a HTTP GET request with a list of unique LocationGroup names

GET /v1/location-groups?names=FGRECEIVING&names=IPOINT HTTP/1.1
Host: localhost:8080

Request parameters:

Parameter Description

names

A list of unique names to identify the LocationGroups

The server sends back a list of all LocationGroups or an empty list if no LocationGroups exist.

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 653

[ {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAUTOMATIC"
  } ],
  "pKey" : "400335177633",
  "name" : "FGRECEIVING",
  "accountId" : "D",
  "parentName" : "FGAUTOMATIC",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=ZILE"
  } ],
  "pKey" : "166982377557",
  "name" : "IPOINT",
  "accountId" : "D",
  "parentName" : "ZILE",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
} ]

Find all LocationGroups

To retrieve a list of all existing LocationGroups a client must send a GET request to the server

GET /v1/location-groups HTTP/1.1
Host: localhost:8080

If no LocationGroups exist the returned array is empty otherwise the response looks like

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 13716

[ {
  "pKey" : "412130127821",
  "name" : "ZILE",
  "accountId" : "D",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=ZILE"
  } ],
  "pKey" : "623275915496",
  "name" : "Flatgood_AREA",
  "accountId" : "D",
  "parentName" : "ZILE",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=Flatgood_AREA"
  } ],
  "pKey" : "709819670512",
  "name" : "FGAUTOMATIC",
  "accountId" : "D",
  "parentName" : "Flatgood_AREA",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAUTOMATIC"
  } ],
  "pKey" : "400335177633",
  "name" : "FGRECEIVING",
  "accountId" : "D",
  "parentName" : "FGAUTOMATIC",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAUTOMATIC"
  } ],
  "pKey" : "811754978035",
  "name" : "FGCONV",
  "accountId" : "D",
  "parentName" : "FGAUTOMATIC",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAUTOMATIC"
  } ],
  "pKey" : "212290962584",
  "name" : "FGSTOCK",
  "accountId" : "D",
  "parentName" : "FGAUTOMATIC",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSTOCK"
  } ],
  "pKey" : "53242834266",
  "name" : "FGAISLE1",
  "accountId" : "D",
  "parentName" : "FGSTOCK",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAISLE1"
  } ],
  "pKey" : "688238147532",
  "name" : "FGAISLE1LIFT",
  "accountId" : "D",
  "parentName" : "FGAISLE1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAISLE1"
  } ],
  "pKey" : "154549927614",
  "name" : "FGAISLE1LEFT",
  "accountId" : "D",
  "parentName" : "FGAISLE1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAISLE1"
  } ],
  "pKey" : "108758840458",
  "name" : "FGAISLE1RIGHT",
  "accountId" : "D",
  "parentName" : "FGAISLE1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSTOCK"
  } ],
  "pKey" : "101671979671",
  "name" : "FGAISLE2",
  "accountId" : "D",
  "parentName" : "FGSTOCK",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAISLE2"
  } ],
  "pKey" : "730288310794",
  "name" : "FGAISLE2LIFT",
  "accountId" : "D",
  "parentName" : "FGAISLE2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAISLE2"
  } ],
  "pKey" : "379640903941",
  "name" : "FGAISLE2LEFT",
  "accountId" : "D",
  "parentName" : "FGAISLE2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAISLE2"
  } ],
  "pKey" : "209483120518",
  "name" : "FGAISLE2RIGHT",
  "accountId" : "D",
  "parentName" : "FGAISLE2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGAUTOMATIC"
  } ],
  "pKey" : "585607846471",
  "name" : "FGSHIPPING",
  "accountId" : "D",
  "parentName" : "FGAUTOMATIC",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING"
  } ],
  "pKey" : "881973001220",
  "name" : "FGSHIPPING1",
  "accountId" : "D",
  "parentName" : "FGSHIPPING",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING1"
  } ],
  "pKey" : "18642707784",
  "name" : "FGWORKPLACE1",
  "accountId" : "D",
  "parentName" : "FGSHIPPING1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING1"
  } ],
  "pKey" : "925145263549",
  "name" : "FGWORKPLACE2",
  "accountId" : "D",
  "parentName" : "FGSHIPPING1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING1"
  } ],
  "pKey" : "346661868774",
  "name" : "FGWORKPLACE3",
  "accountId" : "D",
  "parentName" : "FGSHIPPING1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING"
  } ],
  "pKey" : "753422186594",
  "name" : "FGSHIPPING2",
  "accountId" : "D",
  "parentName" : "FGSHIPPING",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING2"
  } ],
  "pKey" : "258953718288",
  "name" : "FGWORKPLACE4",
  "accountId" : "D",
  "parentName" : "FGSHIPPING2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING2"
  } ],
  "pKey" : "424924693864",
  "name" : "FGWORKPLACE5",
  "accountId" : "D",
  "parentName" : "FGSHIPPING2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING2"
  } ],
  "pKey" : "909419439040",
  "name" : "FGWORKPLACE6",
  "accountId" : "D",
  "parentName" : "FGSHIPPING2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING2"
  } ],
  "pKey" : "687300567810",
  "name" : "FGWORKPLACE7",
  "accountId" : "D",
  "parentName" : "FGSHIPPING2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING2"
  } ],
  "pKey" : "860334844801",
  "name" : "FGWORKPLACE8",
  "accountId" : "D",
  "parentName" : "FGSHIPPING2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=FGSHIPPING2"
  } ],
  "pKey" : "224868263942",
  "name" : "FGWORKPLACE9",
  "accountId" : "D",
  "parentName" : "FGSHIPPING2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=Flatgood_AREA"
  } ],
  "pKey" : "264924505336",
  "name" : "FGMANUAL",
  "accountId" : "D",
  "parentName" : "Flatgood_AREA",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=Flatgood_AREA"
  } ],
  "pKey" : "281343921750",
  "name" : "FGCANBAN",
  "accountId" : "D",
  "parentName" : "Flatgood_AREA",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=ZILE"
  } ],
  "pKey" : "166982377557",
  "name" : "IPOINT",
  "accountId" : "D",
  "parentName" : "ZILE",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=IPOINT"
  } ],
  "pKey" : "782120388022",
  "name" : "IPOINT1",
  "accountId" : "D",
  "parentName" : "IPOINT",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=IPOINT"
  } ],
  "pKey" : "24417670340",
  "name" : "IPOINT2",
  "accountId" : "D",
  "parentName" : "IPOINT",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=ZILE"
  } ],
  "pKey" : "878177817968",
  "name" : "PALLET_AREA",
  "accountId" : "D",
  "parentName" : "ZILE",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PALLET_AREA"
  } ],
  "pKey" : "306784420810",
  "name" : "PPICKING",
  "accountId" : "D",
  "parentName" : "PALLET_AREA",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PALLET_AREA"
  } ],
  "pKey" : "43608343999",
  "name" : "PHIGHBAY",
  "accountId" : "D",
  "parentName" : "PALLET_AREA",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PHIGHBAY"
  } ],
  "pKey" : "500576747031",
  "name" : "PAISLE1",
  "accountId" : "D",
  "parentName" : "PHIGHBAY",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PAISLE1"
  } ],
  "pKey" : "483875811636",
  "name" : "PAISLE1LIFT",
  "accountId" : "D",
  "parentName" : "PAISLE1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PAISLE1"
  } ],
  "pKey" : "443011357014",
  "name" : "PAISLE1LEFT",
  "accountId" : "D",
  "parentName" : "PAISLE1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PAISLE1"
  } ],
  "pKey" : "332530824417",
  "name" : "PAISLE1RIGHT",
  "accountId" : "D",
  "parentName" : "PAISLE1",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PHIGHBAY"
  } ],
  "pKey" : "999057994469",
  "name" : "PAISLE2",
  "accountId" : "D",
  "parentName" : "PHIGHBAY",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PAISLE2"
  } ],
  "pKey" : "995126472754",
  "name" : "PAISLE2LIFT",
  "accountId" : "D",
  "parentName" : "PAISLE2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PAISLE2"
  } ],
  "pKey" : "48562833846",
  "name" : "PAISLE2LEFT",
  "accountId" : "D",
  "parentName" : "PAISLE2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
}, {
  "links" : [ {
    "rel" : "parent",
    "href" : "http://localhost:8080/v1/location-groups?name=PAISLE2"
  } ],
  "pKey" : "673781181265",
  "name" : "PAISLE2RIGHT",
  "accountId" : "D",
  "parentName" : "PAISLE2",
  "operationMode" : "INFEED_AND_OUTFEED",
  "groupStateIn" : "AVAILABLE",
  "groupStateOut" : "AVAILABLE"
} ]

Each LocationGroup has a link to its parent LocationGroup except the root LocationGroup that doesn’t have that link.

Change a LocationGroup’s State

A LocationGroup has an inbound and an outbound state, sometimes also referred as infeed or outfeed state. Both states can be set to AVAILABLE or NOT_AVAILABLE independent from each other. Is a LocationGroup not available for infeed, then no transports towards this LocationGroup are created, similar is true for the outbound state.

To change the state of a LocationGroup a PATCH request on the identified resource is accepted

PATCH /v1/location-group/400335177633?statein=NOT_AVAILABLE&stateout=NOT_AVAILABLE&op=change-state HTTP/1.1
Host: localhost:8080

Request path variables ./v1/location-group/{pKey}

Parameter Description

pKey

The persistent key of the LocationGroup

Request parameters

Parameter Description

statein

The infeed state to set

stateout

The outfeed state to set

op

The operation mode must be set to 'change-state'

If the state change operation could be processed successfully, the server responds with

HTTP/1.1 200 OK

If the resource can’t be identified the server response looks like: Unresolved directive in 6-location-group.adoc - include::/home/runner/work/org.openwms.common.service/org.openwms.common.service/target/generated-snippets/lg/shall_change_state_pkey_404/http-response.adoc[]

Instead of passing both state values for inbound and outbound directly as query parameters it is also possible to encode the state into a 8-digit bitmap field and pass it with the request. This is very handy when the subsystem (aka. PLC) sends an error bitmap to the server that is directly passed to the API.

PATCH /v1/location-groups?name=IPOINT&op=change-state HTTP/1.1
Content-Type: application/json
Content-Length: 30
Host: localhost:8080

{
  "errorCode" : "******11"
}

Request parameters:

Parameter Description

name

The unique name of the LocationGroup

op

The operation mode must be set to 'change-state'

The server response is:

HTTP/1.1 200 OK

Target

A Target is a Location or a group of Locations (LocationGroup) where a TransportUnit may be sent to.

A Target can be locked for inbound/outbound, for operation or permanently. When the Target is locked for inbound, no new TransportUnit movements (TransportOrders in automatic warehouses) are created to this Target (like a Putaway lock). In contrast, no movements can be created away from this Target if it is locked for outbound (like Allocation). Locking inbound/outbound has no impact on the operation mode of the Target. So the Target may still process existing orders, even if it is locked for inbound/outbound.

The operation mode of a Target is controlled separately. If the Targets is in PERMANENT operation mode it stops all operations and does no longer process any commands or telegrams.

Inbound/Outbound Locking

Locking a Target for Inbound/Outbound operation is controlled with a HTTP POST request against the URI /v1/targets/ALLOCATION_LOCK with a set of query parameters.

HTTP Verb Query Param type Query Param mode Description

POST

ALLOCATION_LOCK

IN

Lock the Target for Inbound allocation

POST

ALLOCATION_LOCK

OUT

Lock the Target for Outbound allocation

POST

ALLOCATION_LOCK

IN_AND_OUT

Lock the Target for Inbound and Outbound allocation

POST

ALLOCATION_LOCK

NONE

Release the Target for all kind of allocation

Lock Inbound (Putaway, Infeed)

To lock a Target to be not considered in inbound, like Putaway, the server expects a HTTP POST request with the lock type type=ALLOCATION_LOCK and the mode=IN.

POST /v1/targets/IPOINT?type=ALLOCATION_LOCK&mode=IN HTTP/1.1
Host: localhost:8080

Lock Outbound (Dispatching, Allocation, Outfeed)

To lock a Target for outbound, like Allocation and Outfeed, the server expects a HTTP POST request with the lock type type=ALLOCATION_LOCK and the mode=OUT.

POST /v1/targets/IPOINT?type=ALLOCATION_LOCK&mode=OUT HTTP/1.1
Host: localhost:8080

Lock Inbound & Outbound

To lock a Target for inbound and outbound, like Putaway and Allocation, the server expects a HTTP POST request with the lock type type=ALLOCATION_LOCK and the mode=IN_AND_OUT.

POST /v1/targets/IPOINT?type=ALLOCATION_LOCK&mode=IN_AND_OUT HTTP/1.1
Host: localhost:8080

Release Lock

To release all locks on a Target and allow any inbound and outbound operation, the server expects a HTTP POST request with the lock type type=ALLOCATION_LOCK and the mode=NONE.

POST /v1/targets/IPOINT?type=ALLOCATION_LOCK&mode=NONE HTTP/1.1
Host: localhost:8080

Response: Success

In any of the previous cases the server responds with the following success message.

HTTP/1.1 200 OK

Locking Operational Processing

A Target could also be locked for operation only but not for further Allocation. This means, the Target is active and looks available in warehouse counting and order allocation but is currently out-of-order and not ready to execute any (physical) operation. This is useful for planned short term locks, where a Target is taken out of operation but should still be considered by the system.

Like the infeed/outfeed locking an operational lock can be set to different modes.

HTTP Verb Query Param type Query Param mode Description

POST

OPERATION_LOCK

IN

Lock the Target for all inbound operations

POST

OPERATION_LOCK

OUT

Lock the Target for all outbound operations

POST

OPERATION_LOCK

IN_AND_OUT

Lock the Target for all inbound and outbound operations

POST

OPERATION_LOCK

NONE

Release the Target for all kind of operations

Lock for inbound Operations

To lock a Target for inbound operations only, the server expects a HTTP POST request with the lock type type=OPERATION_LOCK and the mode=IN.

POST /v1/targets/IPOINT?reallocation=true&type=OPERATION_LOCK&mode=IN HTTP/1.1
Host: localhost:8080

Lock for outbound Operations

To lock a Target for outbound operations only, the server expects a HTTP POST request with the lock type type=OPERATION_LOCK and the mode=OUT.

POST /v1/targets/IPOINT?type=OPERATION_LOCK&mode=OUT HTTP/1.1
Host: localhost:8080

Lock inbound & outbound Operations

To lock a Target for inbound and outbound operations, the server expects a HTTP POST request with the lock type type=OPERATION_LOCK and the mode=IN_AND_OUT.

POST /v1/targets/IPOINT?type=OPERATION_LOCK&mode=IN_AND_OUT HTTP/1.1
Host: localhost:8080

Release Lock

To release all operational locks on a Target and allow any inbound and outbound operation, the server expects a HTTP POST request with the lock type type=OPERATION_LOCK and the mode=NONE.

POST /v1/targets/IPOINT?type=OPERATION_LOCK&mode=NONE HTTP/1.1
Host: localhost:8080

Response: Success

In any of the previous cases the server responds with the following success message.

HTTP/1.1 200 OK

Locking / Unlocking a Target for Allocation and Processing

If a Target is locked for operation it does not process requests anymore. In case of a physical Target, like a Crane, no new movements are accepted and the Crane will stop working. This depends on the implemented Crane strategy. The Crane could stop immediately or after it has finished the current operation.

To permanently lock or unlock a Target for allocation and processing send a HTTP POST request with the name of the Target to the server. Locking the Target allows an optional flag to signal a re-allocation of already assigned movements and orders.

In this example the Target is a LocationGroup with the name IPOINT that gets locked. The server is requested to re-allocate existing orders.

POST /v1/targets/IPOINT?reallocation=true&type=PERMANENT_LOCK&mode=lock HTTP/1.1
Host: localhost:8080

Request parameters:

Parameter Description

reallocation

true to trigger an order re-allocation, or false if not

type

The lock type

mode

The operation mode

To unlock the same Target with name IPOINT:

POST /v1/targets/IPOINT?type=PERMANENT_LOCK&mode=unlock HTTP/1.1
Host: localhost:8080

Response: Success

If the server has successfully locked or unlocked the Target the response is:

HTTP/1.1 200 OK

Response: Target does not exist

If the given Target (FOO) does not exist the server responds with:

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 188

{
  "message" : "LocationGroup with name [FOO] does not exist",
  "messageKey" : "owms.common.common.lg.notFoundByName",
  "obj" : [ "FOO" ],
  "httpStatus" : "404",
  "class" : "String"
}

TransportUnit

A TransportUnit is an item like a box, a toad, a bin or a pallet that is moved within a warehouse and can carry goods. It is moved between Locations.

TransportUnit Index

The index with all possible operations can be retrieved with the following GET request:

GET /v1/transport-units/index HTTP/1.1
Host: localhost:8080

The response lists all the operations with a name and the corresponding href link:

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 1312

{
  "_links" : {
    "transport-unit-createtuwithbody" : {
      "href" : "http://localhost:8080/v1/transport-units?bk=%7BtransportUnitBK%7D&strict=true"
    },
    "transport-unit-createtuwithparams" : {
      "href" : "http://localhost:8080/v1/transport-units?bk=%7BtransportUnitBK%7D&actualLocation=%7BactualLocation%7D&tut=%7BtransportUnitType%7D&strict=true"
    },
    "transport-unit-findbypkey" : {
      "href" : "http://localhost:8080/v1/transport-units/1"
    },
    "transport-unit-findbybarcode" : {
      "href" : "http://localhost:8080/v1/transport-units?bk=%7BtransportUnitBK%7D"
    },
    "transport-unit-findbybarcodes" : {
      "href" : "http://localhost:8080/v1/transport-units?bks=%7BtransportUnitBK-1%7D&bks=%7BtransportUnitBK-n%7D"
    },
    "transport-unit-findonlocation" : {
      "href" : "http://localhost:8080/v1/transport-units?actualLocation=%7BactualLocation.locationId%7D"
    },
    "transport-unit-block" : {
      "href" : "http://localhost:8080/v1/transport-units/block?bk=%7BtransportUnitBK%7D"
    },
    "transport-unit-unblock" : {
      "href" : "http://localhost:8080/v1/transport-units/available?bk=%7BtransportUnitBK%7D"
    },
    "transport-unit-qc" : {
      "href" : "http://localhost:8080/v1/transport-units/quality-check?bk=%7BtransportUnitBK%7D"
    }
  }
}

Create a TransportUnit

Currently the API offers two variants to create a TransportUnit. Both expect a HTTP POST request sent to the same context path but with different request parameters.

The simplest way to create a TransportUnit is to just pass the mandatory fields of a TransportUnit to the API

POST /v1/transport-units?bk=00000000000000004710&actualLocation=EXT_/0000/0000/0000/0000&tut=PALLET&strict=false HTTP/1.1
Host: localhost:8080
Parameter Description

bk

The identifying Barcode of the TransportUnit

actualLocation

The Location where to book on the TransportUnit initially

tut

The name of the TransportUnitType assigned to the TransportUnit

strict

If true, the service fails if the TransportUnit already exist, if false it does not fail and returns the existing one

The server stores a TransportUnit instance with the given values and default values for other fields. The response contains a link to the newly created resource as HTTP Location header attribute

HTTP/1.1 201 Created
Location: http://localhost:8080/v1/transport-units/cda36f7e-8c33-42f8-a93b-c16a79452a54/
Content-Type: application/vnd.openwms.transport-unit-v1+json
Content-Length: 1297

{
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-units/cda36f7e-8c33-42f8-a93b-c16a79452a54"
  }, {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationId=EXT_%2F0000%2F0000%2F0000%2F0000"
  } ],
  "ol" : 0,
  "pKey" : "cda36f7e-8c33-42f8-a93b-c16a79452a54",
  "barcode" : "00000000000000004710",
  "actualLocation" : {
    "links" : [ ],
    "ol" : 30,
    "pKey" : "113646454019",
    "locationId" : "EXT_/0000/0000/0000/0000",
    "accountId" : "D",
    "plcCode" : "PLC_0030",
    "erpCode" : "ERP_0030",
    "sortOrder" : 0,
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0,
    "type" : "FG",
    "locationGroupName" : "ZILE"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "ol" : 0,
    "pKey" : "1000",
    "type" : "PALLET",
    "description" : "Euro pallet",
    "height" : "102",
    "width" : "80",
    "length" : "120"
  },
  "weight" : {
    "@class" : "org.openwms.core.units.api.Weight",
    "unitType" : [ "org.openwms.core.units.api.WeightUnit", "G" ],
    "magnitude" : 0
  },
  "actualLocationDate" : 1656105445174,
  "createDate" : 1656105445198
}

In a second approach the client may pass the structure of the TransportUnit to create as request body to the API

POST /v1/transport-units?bk=00000000000000004710&strict=false HTTP/1.1
Content-Type: application/json
Content-Length: 170
Host: localhost:8080

{
  "barcode" : "4710",
  "actualLocation" : {
    "links" : [ ],
    "locationId" : "EXT_/0000/0000/0000/0000"
  },
  "transportUnitType" : {
    "type" : "PALLET"
  }
}
Parameter Description

bk

The identifying Barcode of the TransportUnit

strict

If true, the service fails if the TransportUnit already exist, if false it does not fail and returns the existing one

Like before the server responds with a link to the newly created resource as soon as the operation succeeds.

HTTP/1.1 201 Created
Location: http://localhost:8080/v1/transport-units/349b6fdf-ba98-482f-beee-50728dece85e/

Notice the strict attribute. When the client passes true as value the server ensures there that no TransportUnit with the given business key exists befor. When the attribute is omitted or set to false no such validation happens and the reference to an already existing TransportUnit or the newly created one is returned. If the API call fails because a TransportUnit with the given Barcode exists, the response looks like

HTTP/1.1 409 Conflict
Content-Type: application/hal+json
Content-Length: 223

{
  "message" : "TransportUnit with Barcode [00000000000000004711] already exits",
  "messageKey" : "owms.common.common.tu.alreadyExists",
  "obj" : [ "00000000000000004711" ],
  "httpStatus" : "409",
  "class" : "String"
}

If the request is invalid or contains invalid fields the server responds with

HTTP/1.1 400 Bad Request

Move a TransportUnit

To move a TransportUnit from it’s current Location to a new Location, simply call the API with the identifying Barcode and the new Location where the TransportUnit shall be moved to.

PATCH /v1/transport-units?bk=00000000000000004711&newLocation=FGIN/0001/LEFT/0000/0000 HTTP/1.1
Host: localhost:8080
Parameter Description

bk

The identifying Barcode of the TransportUnit

newLocation

The target Location where to move the TransportUnit to

The server returns the updated TransportUnit instance.

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-v1+json
Content-Length: 1076

{
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-units/1"
  }, {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationId=FGIN%2F0001%2FLEFT%2F0000%2F0000"
  } ],
  "ol" : 2,
  "pKey" : "1",
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "ol" : 13,
    "pKey" : "896384899357",
    "locationId" : "FGIN/0001/LEFT/0000/0000",
    "accountId" : "D",
    "plcCode" : "PLC_0013",
    "erpCode" : "ERP_0013",
    "sortOrder" : 0,
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0,
    "type" : "FG",
    "locationGroupName" : "FGAISLE1LEFT"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "ol" : 0,
    "pKey" : "1000",
    "type" : "PALLET",
    "description" : "Euro pallet",
    "height" : "102",
    "width" : "80",
    "length" : "120"
  },
  "actualLocationDate" : 1656105446522,
  "createDate" : 1656105446464
}

Modify a TransportUnit

Already existing TransportUnits can be modified by some degree. Not every attribute is allowed to change but most of the non-identifying ones can be changed. For example it is not foreseen to change the Barcode of an existing TransportUnit, nor the internal persistent key. The date when the TransportUnit has been recently moved is only changed together with the actualLocation.

Send a HTTP PUT request to the server together with the TransportUnit as part of the request body

PUT /v1/transport-units?bk=00000000000000004711 HTTP/1.1
Content-Type: application/json
Content-Length: 223
Host: localhost:8080

{
  "pKey" : "1",
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "locationId" : "FGIN/0001/LEFT/0000/0000"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "type" : "PL"
  }
}
Parameter Description

bk

The identifying Barcode of the TransportUnit

If the server saved the changes, the response contains the updated representation of the TransportUnit

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-v1+json
Content-Length: 1076

{
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-units/1"
  }, {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationId=FGIN%2F0001%2FLEFT%2F0000%2F0000"
  } ],
  "ol" : 2,
  "pKey" : "1",
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "ol" : 13,
    "pKey" : "896384899357",
    "locationId" : "FGIN/0001/LEFT/0000/0000",
    "accountId" : "D",
    "plcCode" : "PLC_0013",
    "erpCode" : "ERP_0013",
    "sortOrder" : 0,
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0,
    "type" : "FG",
    "locationGroupName" : "FGAISLE1LEFT"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "ol" : 0,
    "pKey" : "1000",
    "type" : "PALLET",
    "description" : "Euro pallet",
    "height" : "102",
    "width" : "80",
    "length" : "120"
  },
  "actualLocationDate" : 1656105445724,
  "createDate" : 1656105445563
}

In case no TransportUnit with the Barcode exists the server returns an error

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 244

{
  "message" : "TransportUnit with Barcode [00000000000000004710] does not exist",
  "messageKey" : "owms.common.common.tu.notFoundByBK",
  "obj" : [ {
    "value" : "00000000000000004710"
  } ],
  "httpStatus" : "404",
  "class" : "Barcode"
}

Find by Barcode

Find a TransportUnit by its unique Barcode.

GET /v1/transport-units?bk=00000000000000004711 HTTP/1.1
Host: localhost:8080
Parameter Description

bk

The identifying Barcode of the TransportUnit

If the TransportUnit has been found the server returns a JSON representation

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-v1+json
Content-Length: 1068

{
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-units/1"
  }, {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationId=EXT_%2F0000%2F0000%2F0000%2F0000"
  } ],
  "ol" : 1,
  "pKey" : "1",
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "ol" : 29,
    "pKey" : "113646454019",
    "locationId" : "EXT_/0000/0000/0000/0000",
    "accountId" : "D",
    "plcCode" : "PLC_0030",
    "erpCode" : "ERP_0030",
    "sortOrder" : 0,
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0,
    "type" : "FG",
    "locationGroupName" : "ZILE"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "ol" : 0,
    "pKey" : "1000",
    "type" : "PALLET",
    "description" : "Euro pallet",
    "height" : "102",
    "width" : "80",
    "length" : "120"
  },
  "actualLocationDate" : 1656105446274,
  "createDate" : 1656105446274
}

In case a TransportUnit with the requested Barcode == 9999 does not exist the response looks like

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 244

{
  "message" : "TransportUnit with Barcode [00000000000000000999] does not exist",
  "messageKey" : "owms.common.common.tu.notFoundByBK",
  "obj" : [ {
    "value" : "00000000000000000999"
  } ],
  "httpStatus" : "404",
  "class" : "Barcode"
}

Also the short form of a Barcode can be passed to the API and the server implementation adjusts the given Barcode to the configured style, like it is left or right aligned and padded.

GET /v1/transport-units?bk=4711 HTTP/1.1
Host: localhost:8080

Find by multiple Barcodes

Also multiple Barcodes can be passed to the API in order to search for multiple TransportUnits.

GET /v1/transport-units?bks=00000000000000004711&bks=00000000000000004712&bks=00000000000000004713 HTTP/1.1
Host: localhost:8080
Parameter Description

bks

A set of identifying Barcodes of the TransportUnit to search for

This returns an array with the TransportUnits found

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-v1+json
Content-Length: 2181

[ {
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-units/1"
  }, {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationId=EXT_%2F0000%2F0000%2F0000%2F0000"
  } ],
  "ol" : 1,
  "pKey" : "1",
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "ol" : 29,
    "pKey" : "113646454019",
    "locationId" : "EXT_/0000/0000/0000/0000",
    "accountId" : "D",
    "plcCode" : "PLC_0030",
    "erpCode" : "ERP_0030",
    "sortOrder" : 0,
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0,
    "type" : "FG",
    "locationGroupName" : "ZILE"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "ol" : 0,
    "pKey" : "1000",
    "type" : "PALLET",
    "description" : "Euro pallet",
    "height" : "102",
    "width" : "80",
    "length" : "120"
  },
  "actualLocationDate" : "2022-06-24T21:17:24Z",
  "createDate" : "2022-06-24T21:17:24Z"
}, {
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-units/2"
  }, {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationId=FGIN%2FIPNT%2F0001%2F0000%2F0000"
  } ],
  "ol" : 1,
  "pKey" : "2",
  "barcode" : "00000000000000004712",
  "actualLocation" : {
    "links" : [ ],
    "ol" : 30,
    "pKey" : "439649733836",
    "locationId" : "FGIN/IPNT/0001/0000/0000",
    "accountId" : "D",
    "plcCode" : "PLC_0031",
    "erpCode" : "ERP_0031",
    "sortOrder" : 0,
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0,
    "type" : "FG",
    "locationGroupName" : "IPOINT1"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "ol" : 0,
    "pKey" : "1000",
    "type" : "PALLET",
    "description" : "Euro pallet",
    "height" : "102",
    "width" : "80",
    "length" : "120"
  },
  "actualLocationDate" : "2022-06-24T21:17:24Z",
  "createDate" : "2022-06-24T21:17:24Z"
} ]

Find TransportUnits on a Location

Search and return all TransportUnits that are currently booked on a given Location.

GET /v1/transport-units?actualLocation=FGIN/IPNT/0001/0000/0000 HTTP/1.1
Host: localhost:8080
Parameter Description

actualLocation

The Location to find all TransportUnits booked on

The TransportUnit with Barcode == 00000000000000004712 is returned

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-v1+json
Content-Length: 1093

[ {
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-units/2"
  }, {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationId=FGIN%2FIPNT%2F0001%2F0000%2F0000"
  } ],
  "ol" : 1,
  "pKey" : "2",
  "barcode" : "00000000000000004712",
  "actualLocation" : {
    "links" : [ ],
    "ol" : 30,
    "pKey" : "439649733836",
    "locationId" : "FGIN/IPNT/0001/0000/0000",
    "accountId" : "D",
    "plcCode" : "PLC_0031",
    "erpCode" : "ERP_0031",
    "sortOrder" : 0,
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0,
    "type" : "FG",
    "locationGroupName" : "IPOINT1"
  },
  "state" : "AVAILABLE",
  "transportUnitType" : {
    "ol" : 0,
    "pKey" : "1000",
    "type" : "PALLET",
    "description" : "Euro pallet",
    "height" : "102",
    "width" : "80",
    "length" : "120"
  },
  "actualLocationDate" : "2022-06-24T21:17:26Z",
  "createDate" : "2022-06-24T21:17:26Z"
} ]

Add an Error to a TransportUnit

During the handling of TransportUnits, errors or failure situations may occur that makes it necessary to store some kind of error message for further analysis. Therefore each TransportUnit has a history of error messages attached that can be populated with new messages. A client simple calls an API to add a new error message to an existing TransportUnit.

POST /v1/transport-unit/error?bk=00000000000000004711&errorCode=bla HTTP/1.1
Host: localhost:8080
Parameter Description

bk

The identifying Barcode of the TransportUnit

errorCode

The error text

The server acknowledges the request and stores the error message asynchronously

HTTP/1.1 204 No Content

TransportUnitType

A TransportUnitType is a type of a certain TransportUnit. Typically to store some static attributes of TransportUnits, such as the length, the height, or the weight of TransportUnits. This way it is possible to group and characterize TransportUnits.

TransportUnitType Index

The index with all possible operations can be retrieved with the following GET request

GET /v1/transport-unit-types/index HTTP/1.1
Host: localhost:8080

The response lists all the operations with a name and the corresponding link

HTTP/1.1 200 OK
Content-Type: application/hal+json
Content-Length: 388

{
  "_links" : {
    "transport-unit-types-findbypkey" : {
      "href" : "http://localhost:8080/v1/transport-unit-types/%7BpKey%7D"
    },
    "transport-unit-types-findtransportunittype" : {
      "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
    },
    "transport-unit-types-findall" : {
      "href" : "http://localhost:8080/v1/transport-unit-types"
    }
  }
}

Find a TransportUnitType by Persistent Id (pKey)

An existing TransportUnitType can be looked up by it’s persistent key (pKey)

GET /v1/transport-unit-types/1000 HTTP/1.1
Host: localhost:8080

If the TransportUnitType exists the response is

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-type-v1+json
Content-Length: 194

{"links":[{"rel":"self","href":"http://localhost:8080/v1/transport-unit-types/1000"}],"ol":0,"pKey":"1000","type":"PALLET","description":"Euro pallet","height":"102","width":"80","length":"120"}

If no TransportUnitType with the given pKey exist the server responds with

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 199

{
  "message" : "TransportUnitType with ID [UNKNOWN] does not exist",
  "messageKey" : "owms.common.common.tut.notFoundByPKey",
  "obj" : [ "UNKNOWN" ],
  "httpStatus" : "404",
  "class" : "String"
}

Find a TransportUnitType by Name

Each TransportUnitType has an unique name with that it can be identified. Query the resource with a type parameter

GET /v1/transport-unit-types?type=PALLET HTTP/1.1
Host: localhost:8080

If the TransportUnitType exists the response looks like

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-type-v1+json
Content-Length: 194

{"links":[{"rel":"self","href":"http://localhost:8080/v1/transport-unit-types/1000"}],"ol":0,"pKey":"1000","type":"PALLET","description":"Euro pallet","height":"102","width":"80","length":"120"}

If no TransportUnitType with the given name exist the server sends a 404-NOT FOUND

HTTP/1.1 404 Not Found
Content-Type: application/hal+json
Content-Length: 122

{
  "message" : "No TransportUniType with type [NOT_EXISTS] found",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

Find all TransportUnitTypes

To retrieve a list of all existing TransportUnitTypes a client must send a GET request to the server

GET /v1/transport-unit-types HTTP/1.1
Host: localhost:8080

The response contains all existing TransportUnitTypes

HTTP/1.1 200 OK
Content-Type: application/vnd.openwms.transport-unit-type-v1+json
Content-Length: 512

[ {
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-unit-types/1000"
  } ],
  "ol" : 0,
  "pKey" : "1000",
  "type" : "PALLET",
  "description" : "Euro pallet",
  "height" : "102",
  "width" : "80",
  "length" : "120"
}, {
  "links" : [ {
    "rel" : "self",
    "href" : "http://localhost:8080/v1/transport-unit-types/1001"
  } ],
  "ol" : 0,
  "pKey" : "1001",
  "type" : "BIN",
  "description" : "Plastic bins",
  "height" : "102",
  "width" : "80",
  "length" : "120"
} ]