Copyright © 2005-2020

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": "COMMON.LOCATION_GROUP_NOT_FOUND",
    "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

COMMON.BARCODE_NOT_FOUND

The TransportUnit does not exist

Verify the identifying attribute passed to the API

COMMON.LOCATION_NOT_FOUND

The requested Location does not exist

Verify the identifying attribute passed to the API

COMMON.LOCATION_GROUP_NOT_FOUND

The requested LocationGroup does not exist

Verify the identifying attribute passed to the API

COMMON.TRANSPORT_UNIT_TYPE_NOT_FOUND

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 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: 409

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

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/json
Content-Length: 141

[ {
  "links" : [ ],
  "identifier" : "D",
  "name" : "Default"
}, {
  "links" : [ ],
  "identifier" : "A1",
  "name" : "Cost Center FIN"
} ]

Find an Account

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 entity if it exists:

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

{
  "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: 163

{
  "message" : "Account [UNKNOWN] not found",
  "messageKey" : "COMMON.ACCOUNT_NOT_FOUND",
  "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 from the Common Service 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 entity if it exists

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

{
  "identifier" : "D",
  "name" : "Default"
}

Otherwise a 404-Not Found if not exist:

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

{
  "message" : "No default Account exists",
  "messageKey" : "COMMON.ACCOUNT_NO_DEFAULT",
  "httpStatus" : "404"
}

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: 504

{
  "_links" : {
    "location-findbycoordinate" : {
      "href" : "http://localhost:8080/v1/locations?locationPK=AREA/AISLE/X/Y/Z"
    },
    "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"
    }
  }
}

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?locationPK=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/json
Content-Length: 242

{
  "links" : [ ],
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "ZILE",
  "plcCode" : "PLC_0030",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
}

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

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

{
  "message" : "No Location with locationPk [EXT_/9999/9999/9999/9999] found",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

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: 111

{
  "message" : "Invalid location [INVALID_COORDINATE]",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

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 Lift Locations in the Flat Good area, this 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 Lift positions and the server returns both:

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

[ {
  "links" : [ ],
  "pKey" : "798136030917",
  "locationId" : "FGIN/0001/LIFT/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "FGAISLE1LIFT",
  "plcCode" : "PLC_0012",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
}, {
  "links" : [ ],
  "pKey" : "852306856430",
  "locationId" : "FGIN/0002/LIFT/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "FGAISLE2LIFT",
  "plcCode" : "PLC_0015",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
} ]

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

HTTP/1.1 404 Not Found

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/json
Content-Length: 242

{
  "links" : [ ],
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "ZILE",
  "plcCode" : "PLC_0030",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
}

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

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

{
  "message" : "No Location with PLC Code [NOT EXISTS] found",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

Find Locations of 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/json
Content-Length: 490

[ {
  "links" : [ ],
  "pKey" : "171919359409",
  "locationId" : "INIT/0000/0000/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "ZILE",
  "plcCode" : "PLC_0029",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
}, {
  "links" : [ ],
  "pKey" : "113646454019",
  "locationId" : "EXT_/0000/0000/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "ZILE",
  "plcCode" : "PLC_0030",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
} ]

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

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

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/json
Content-Length: 496

[ {
  "links" : [ ],
  "pKey" : "439649733836",
  "locationId" : "FGIN/IPNT/0001/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "IPOINT1",
  "plcCode" : "PLC_0031",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
}, {
  "links" : [ ],
  "pKey" : "227916500906",
  "locationId" : "FGIN/IPNT/0002/0000/0000",
  "accountId" : "D",
  "locationGroupName" : "IPOINT2",
  "plcCode" : "PLC_0032",
  "incomingActive" : true,
  "outgoingActive" : true,
  "plcState" : 0
} ]

Change a Location’s State

Send a HTTP PATCH request with the persistent identifying key of an existing Location along the new state decoded as ErrorCodeVO 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: 123

{
  "message" : "No Location with persistent key [NOTEXISTS] found",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

The ErrorCodeVO 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 or LocationGroup:

Digit Position (RtL) Assigned attribute

20

Location.incomingActive

21

Location.outgoingActive

22

Location.groupStateIn

23

Location.groupStateOut

The following table shows all currently accepted decodings of the ErrorCodeVO.errorCode String that is sent with 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 200 OK

Beside locking the Location for Inbound- and Outbound processing it is also possible to change the PLC state of the Location through this API. Therefor 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 200 OK

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 can be retrieved with the following 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 href link:

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

{
  "_links" : {
    "location-group-findall" : {
      "href" : "http://localhost:8080/v1/location-groups"
    },
    "location-group-findbyname" : {
      "href" : "http://localhost:8080/v1/location-groups?name=FOO"
    },
    "location-group-findbynames" : {
      "href" : "http://localhost:8080/v1/location-groups?names=FOO&names=BAR"
    },
    "location-group-changestate1" : {
      "href" : "http://localhost:8080/v1/location-groups?name=FOO&op=change-state"
    },
    "location-group-changestate2" : {
      "href" : "http://localhost:8080/v1/location-group/UUID?op=change-state&statein=AVAILABLE&stateout=NOT_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: 13733

[ {
  "links" : [ ],
  "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 has no parent. Notice the returned Content-Type is application/hal+json that enables support for hypermedia links.

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"
}

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: 125

{
  "message" : "LocationGroup with name [NOT_EXISTS] does not exist",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

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 identiy 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"
} ]

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:

Table 1. /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:

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

{
  "message" : "LocationGroup with name [NOT_EXISTS] not found",
  "messageKey" : "COMMON.LOCATION_GROUP_NOT_FOUND",
  "obj" : [ "NOT_EXISTS" ],
  "httpStatus" : "404",
  "class" : "String"
}

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 to the request. This is very handy when the subsystem (aka. PLC) sends an error bitmap to the server that can then 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 requires 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
Content-Type: application/x-www-form-urlencoded

type=ALLOCATION_LOCK&mode=IN

Lock Outbound (Dispatching, Allocation, Outfeed)

To lock a Target for outbound, like Allocation and Outfeed, the server requires 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
Content-Type: application/x-www-form-urlencoded

type=ALLOCATION_LOCK&mode=OUT

Lock Inbound & Outbound

To lock a Target for inbound and outbound, like Putaway and Allocation, the server requires 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
Content-Type: application/x-www-form-urlencoded

type=ALLOCATION_LOCK&mode=IN_AND_OUT

Release Lock

To release all locks on a Target and allow any inbound and outbound operation, the server requires 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
Content-Type: application/x-www-form-urlencoded

type=ALLOCATION_LOCK&mode=NONE

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 requires 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
Content-Type: application/x-www-form-urlencoded

reallocation=true&type=OPERATION_LOCK&mode=IN

Lock for outbound Operations

To lock a Target for outbound operations only, the server requires 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
Content-Type: application/x-www-form-urlencoded

type=OPERATION_LOCK&mode=OUT

Lock inbound & outbound Operations

To lock a Target for inbound and outbound operations, the server requires 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
Content-Type: application/x-www-form-urlencoded

type=OPERATION_LOCK&mode=IN_AND_OUT

Release Lock

To release all operational locks on a Target and allow any inbound and outbound operation, the server requires 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
Content-Type: application/x-www-form-urlencoded

type=OPERATION_LOCK&mode=NONE

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 locked for operation it does not process and 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 finishes 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
Content-Type: application/x-www-form-urlencoded

reallocation=true&type=PERMANENT_LOCK&mode=lock

To unlock the same Target with name IPOINT:

POST /v1/targets/IPOINT?type=PERMANENT_LOCK&mode=unlock HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

type=PERMANENT_LOCK&mode=unlock

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: 194

{
  "message" : "The Target with name [FOO] is neither a Location nor a LocationGroup. Other types of Targets are currently not supported",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

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. 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 href link:

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

{
  "_links" : {
    "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 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/json
Content-Length: 232

[ {
  "type" : "PALLET",
  "description" : "Euro pallet",
  "height" : "102",
  "width" : "80",
  "length" : "120"
}, {
  "type" : "BIN",
  "description" : "Plastic bins",
  "height" : "102",
  "width" : "80",
  "length" : "120"
} ]

Find a TransportUnitType by Name

Each TransportUnitType has an unique name by 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/json
Content-Length: 114

{
  "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"
}

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. Used as container to transport items like LoadUnits. 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: 449

{
  "_links" : {
    "transport-unit-findbybarcode" : {
      "href" : "http://localhost:8080/v1/transport-units?bk=00000000000000004711"
    },
    "transport-unit-findbybarcodes" : {
      "href" : "http://localhost:8080/v1/transport-units?bks=00000000000000004711&bks=00000000000000004712"
    },
    "transport-unit-findonlocation" : {
      "href" : "http://localhost:8080/v1/transport-units?actualLocation=EXT_/0000/0000/0000/0000"
    }
  }
}

Create a TransportUnit

Currently the API offers to variants to create a TransportUnit. Both require 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
Content-Type: application/x-www-form-urlencoded

bk=00000000000000004710&actualLocation=EXT_%2F0000%2F0000%2F0000%2F0000&tut=PALLET&strict=false
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 of the TransportUnit. The response contains a link to the newly created resource.

HTTP/1.1 201 Created
Location: http://localhost:8080/v1/transport-units/575364c8-15d1-4340-95bd-c17fffd0d284/

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: 172
Host: localhost:8080

{
  "links" : [ ],
  "barcode" : "4710",
  "actualLocation" : {
    "links" : [ ],
    "locationId" : "EXT_/0000/0000/0000/0000"
  },
  "transportUnitTypeName" : "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 far as the operation succeeds.

HTTP/1.1 201 Created
Location: http://localhost:8080/v1/transport-units/d12cc5a4-0be2-4e15-a2a0-69db280806b4/

Notice the strict attribute. When the client passes true as value for strict the server ensures there is no TransportUnit with the given business key. 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 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: 204

{
  "message" : "TransportUnit with Barcode [00000000000000004711] already exits",
  "messageKey" : "COMMON.TU_EXISTS",
  "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 booked on.

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/hal+json
Content-Length: 542

{
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "pKey" : "896384899357",
    "locationId" : "FGIN/0001/LEFT/0000/0000",
    "accountId" : "D",
    "locationGroupName" : "FGAISLE1LEFT",
    "plcCode" : "PLC_0013",
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0
  },
  "transportUnitTypeName" : "PALLET",
  "length" : 120,
  "width" : 80,
  "height" : 102,
  "actualPlcCode" : "PLC_0013",
  "actualLocationDate" : "2020-10-23T21:31:49.357+0000",
  "createDate" : "2020-10-23T21:31:49.315+0000"
}

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: 150
Host: localhost:8080

{
  "links" : [ ],
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "locationId" : "FGIN/0001/LEFT/0000/0000"
  }
}
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/hal+json
Content-Length: 542

{
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "pKey" : "896384899357",
    "locationId" : "FGIN/0001/LEFT/0000/0000",
    "accountId" : "D",
    "locationGroupName" : "FGAISLE1LEFT",
    "plcCode" : "PLC_0013",
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0
  },
  "transportUnitTypeName" : "PALLET",
  "length" : 120,
  "width" : 80,
  "height" : 102,
  "actualPlcCode" : "PLC_0013",
  "actualLocationDate" : "2020-10-23T21:31:48.829+0000",
  "createDate" : "2020-10-23T21:31:48.699+0000"
}

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: 133

{
  "message" : "TransportUnit with Barcode [00000000000000004710] not found",
  "messageKey" : "not.found",
  "httpStatus" : "404"
}

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: 808

{
  "links" : [ {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationPK=EXT_/0000/0000/0000/0000"
  } ],
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "pKey" : "113646454019",
    "locationId" : "EXT_/0000/0000/0000/0000",
    "accountId" : "D",
    "locationGroupName" : "ZILE",
    "plcCode" : "PLC_0030",
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0
  },
  "transportUnitTypeName" : "PALLET",
  "length" : 120,
  "width" : 80,
  "height" : 102,
  "actualPlcCode" : "PLC_0030",
  "actualLocationDate" : "2020-10-23T21:31:49.123+0000",
  "createDate" : "2020-10-23T21:31:49.123+0000"
}

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: 229

{
  "message" : "TransportUnit with Barcode [00000000000000000999] not found",
  "messageKey" : "COMMON.BARCODE_NOT_FOUND",
  "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.

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

{
  "links" : [ {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationPK=EXT_/0000/0000/0000/0000"
  } ],
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "pKey" : "113646454019",
    "locationId" : "EXT_/0000/0000/0000/0000",
    "accountId" : "D",
    "locationGroupName" : "ZILE",
    "plcCode" : "PLC_0030",
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0
  },
  "transportUnitTypeName" : "PALLET",
  "length" : 120,
  "width" : 80,
  "height" : 102,
  "actualPlcCode" : "PLC_0030",
  "actualLocationDate" : "2020-10-23T21:31:48.921+0000",
  "createDate" : "2020-10-23T21:31:48.921+0000"
}

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: 1625

[ {
  "links" : [ {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationPK=EXT_/0000/0000/0000/0000"
  } ],
  "barcode" : "00000000000000004711",
  "actualLocation" : {
    "links" : [ ],
    "pKey" : "113646454019",
    "locationId" : "EXT_/0000/0000/0000/0000",
    "accountId" : "D",
    "locationGroupName" : "ZILE",
    "plcCode" : "PLC_0030",
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0
  },
  "transportUnitTypeName" : "PALLET",
  "length" : 120,
  "width" : 80,
  "height" : 102,
  "actualPlcCode" : "PLC_0030",
  "actualLocationDate" : "2020-10-23T21:31:48.087+0000",
  "createDate" : "2020-10-23T21:31:48.087+0000"
}, {
  "links" : [ {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationPK=FGIN/IPNT/0001/0000/0000"
  } ],
  "barcode" : "00000000000000004712",
  "actualLocation" : {
    "links" : [ ],
    "pKey" : "439649733836",
    "locationId" : "FGIN/IPNT/0001/0000/0000",
    "accountId" : "D",
    "locationGroupName" : "IPOINT1",
    "plcCode" : "PLC_0031",
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0
  },
  "transportUnitTypeName" : "PALLET",
  "length" : 120,
  "width" : 80,
  "height" : 102,
  "actualPlcCode" : "PLC_0031",
  "actualLocationDate" : "2020-10-23T21:31:48.087+0000",
  "createDate" : "2020-10-23T21:31:48.087+0000"
} ]

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: 815

[ {
  "links" : [ {
    "rel" : "transport-unit-type",
    "href" : "http://localhost:8080/v1/transport-unit-types?type=PALLET"
  }, {
    "rel" : "actual-location",
    "href" : "http://localhost:8080/v1/locations?locationPK=FGIN/IPNT/0001/0000/0000"
  } ],
  "barcode" : "00000000000000004712",
  "actualLocation" : {
    "links" : [ ],
    "pKey" : "439649733836",
    "locationId" : "FGIN/IPNT/0001/0000/0000",
    "accountId" : "D",
    "locationGroupName" : "IPOINT1",
    "plcCode" : "PLC_0031",
    "incomingActive" : true,
    "outgoingActive" : true,
    "plcState" : 0
  },
  "transportUnitTypeName" : "PALLET",
  "length" : 120,
  "width" : 80,
  "height" : 102,
  "actualPlcCode" : "PLC_0031",
  "actualLocationDate" : "2020-10-23T21:31:49.416+0000",
  "createDate" : "2020-10-23T21:31:49.416+0000"
} ]

Add an Error to a TransportUnit

During the handling of TransportUnits, errors or failure situations may occur that make 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 this API to store a new error message for an existing TransportUnit.

POST /v1/transport-unit/error?bk=00000000000000004711&errorCode=bla HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

bk=00000000000000004711&errorCode=bla
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 200 OK