Download OpenAPI specification:Download
Currently, PUZZLE adds the parameter "Order.Processor" after the computation has been finished.
You should not expect that this parameters to remain. This parameter will be removed in a later release without further notification.
Component | Category | Description |
---|---|---|
Best-Fit Plugin 3.0.0 | Dependency | PUZZLE core version 53.0.0. |
Improvement | Add new optional attribute OrderLine#loadingOrder. | |
Best-Fit Plugin 2.3.0 | Dependency | PUZZLE core version 53.0.0. |
Bug | PUZZLE does not add undocumented parameters to a job, with the exception of the parameter "Order.Processor". | |
Best-Fit Plugin 2.1.0 | Bug | PUZZLE adds undocumented parameters to the attribute parameters of the JSON representation of a job, after PUZZLE has computed solutions for this job. Resolved: PUZZLE now omit most of them. |
Dependency | PUZZLE core version 48.0.0. | |
Best-Fit Plugin 2.0.1 | Improvement | The Best-Fit Plugin offers its own REST API for clients. The Best-Fit REST API is largely identical to the PUZZLE REST API. |
Dependency | PUZZLE core version 47.0.0. |
This PUZZLE Plugin provides the Best-Fit optimization and a REST-API for the Best-Fit optimization. The Best-Fit REST API is largely identical to the PUZZLE REST API. Therefore, this document describes the differences to the PUZZLE REST API.
The introduction section describes the core idea of the PUZZLE REST API.
A PUZZLE Best-Fit optimization distributes all order items of a job to the required number of loading devices and finds the appropriate loading devices for the order by means of a Branch and Bound algorithm. PUZZLE can select the appropriate loading devices from the collection of loading devices specified in the loadingDevices
attribute of the job.
For a job, PUZZLE creates a collection of solutions, which contains a solution for each required loading device. Those solutions consists of the required loading device together with the positions of the order items packed onto the required loading device. For each order item that fits into at least one loading device, the collection of solutions of a job contains the order item in the quantity specified in the order of the job.
For a Best-Fit optimization, PUZZLE minimizes the number of loading devices required as the main criterion and maximizes the volume utilization of the loads onto the loading devices as the secondary criterion, which is far less important. Currently, a client cannot customize these criteria.
The Best-Fit REST API uses the same data objects as the PUZZLE REST API.
PUZZLE ignores the parameter Search.SolutionCount
for a Best-Fit optimization and always returns exactly one collection of loads for a job.
The Best-Fit REST API uses the same state machine as the PUZZLE REST API, only with a Best-Fit specific prefix to the urls.
The Best-Fit REST API supports the same plugins as the PUZZLE REST API.
The Best-Fit REST API has the same errors and error handling as the PUZZLE REST API
This section describes all available HTTP endpoints of the Best-Fit REST API. For each endpoint, this documentation contains an interactive representation of the structure of the request body schema and the response schema below the endpoint description. In addition, the right column contains request and response samples for these structures.
In order to facilitate understanding, the following scenario is included as example.
For a Best-Fit optimization, PUZZLE will compute a collection of loads required to distribute an order consisting of 5 tablets and 5 usb power supplies. For each load, PUZZLE can select between an off-the-shelf FEFCO 0201 carton and a customized carton in which exactly one tablet fits.
The same behavior as for POST /jobs.
PUZZLE considers considers all loading devices in a job for a Best-Fit optimization.
required | object (InputEntityJob) |
{- "job": {
- "parameters": { },
- "order": {
- "orderNumber": "order_23129",
- "orderLines": [
- {
- "orderLineNumber": 10,
- "quantity": 5,
- "orderItem": {
- "number": "tablet_45231",
- "name": "an unbranded tablet",
- "group": "electronic devices",
- "length": 130,
- "width": 120,
- "height": 80,
- "grossWeight": 500,
- "maxWeightOnTop": 10000
}
}, - {
- "orderLineNumber": 20,
- "quantity": 5,
- "orderItem": {
- "number": "usb_power_supply_4484",
- "name": "an unbranded powers supply",
- "group": "electronic devices - accessories",
- "length": 37,
- "width": 51,
- "height": 22,
- "grossWeight": 22,
- "maxWeightOnTop": 1000
}
}
]
}, - "loadingDevices": [
- {
- "type": "FEFCO0201",
- "number": "CARTON_01",
- "name": "off-the-shelf FEFCO0201 carton with 5 cm empty space on each side",
- "length": 400,
- "width": 300,
- "height": 100,
- "materialThickness": 10,
- "lengthOverhang": -50,
- "widthOverhang": -50,
- "maxLoadWeight": 50000,
- "emptyWeight": 500
}, - {
- "type": "FEFCO0201",
- "number": "CARTON_02",
- "name": "adjusted FEFCO0201 carton to ship a single tablet",
- "length": 140,
- "width": 130,
- "height": 85,
- "materialThickness": 10,
- "lengthOverhang": 0,
- "widthOverhang": 0,
- "maxLoadWeight": 50000,
- "emptyWeight": 500
}
]
}
}
{- "jobId": 3
}
The same behavior as for POST /jobs/{jobId}/metadata.
jobId required | integer <int64> >= 1 The Id of the job. |
{- "jobId": 3,
- "state": "DONE",
- "lastUseTimestamp": "2019-04-10T14:10:21+0200",
- "expirationTimestamp": "2019-04-10T19:10:21+0200",
- "timeIntervalUntilExpiration": 17995,
- "orderNumber": "order_23129",
- "errorOccurred": false,
- "errorMessage": ""
}
The same behavior as for POST /jobs/{jobId}/validation.
jobId required | integer <int64> >= 1 The Id of the job. |
language | string Example: language=en The language of the validation messages. A client can specify the language with IETF language tags. If not specified, the system setting language is used. Currently supported languages are German (de) and English (en). |
{- "isValid": true,
- "validationMessages": [ ]
}
The same behavior as for POST /jobs/{jobId}/computation.
jobId required | integer <int64> >= 1 The Id of the job. |
{- "errorMessage": "PUZZLE cannot find job with id 123",
- "additionalInformation": "",
- "errorClass": "de.fraunhofer.iml.puzzle.adapter.execution.Exceptions.Rest.PuzzleJobNotFoundException"
}
The same behavior as for DEL /jobs/{jobId}/computation.
jobId required | integer <int64> >= 1 The Id of the job. |
{- "errorMessage": "PUZZLE cannot find job with id 123",
- "additionalInformation": "",
- "errorClass": "de.fraunhofer.iml.puzzle.adapter.execution.Exceptions.Rest.PuzzleJobNotFoundException"
}
The same behavior as for GET /jobs/{jobId}/summaries.
jobId required | integer <int64> >= 1 The Id of the job. |
[- {
- "solutionId": 1,
- "length": 288,
- "width": 165,
- "height": 80,
- "weight": 1110,
- "volume": 2703570,
- "numberOfPositionedItems": 7,
- "weightUtilization": 2,
- "volumeUtilization": 45,
- "packDensity": 71,
- "loadingDeviceNumber": "CARTON_01"
}, - {
- "solutionId": 2,
- "length": 280,
- "width": 120,
- "height": 80,
- "weight": 1000,
- "volume": 2496000,
- "numberOfPositionedItems": 2,
- "weightUtilization": 2,
- "volumeUtilization": 41,
- "packDensity": 93,
- "loadingDeviceNumber": "CARTON_01"
}, - {
- "solutionId": 3,
- "length": 130,
- "width": 120,
- "height": 80,
- "weight": 500,
- "volume": 1248000,
- "numberOfPositionedItems": 1,
- "weightUtilization": 1,
- "volumeUtilization": 80,
- "packDensity": 100,
- "loadingDeviceNumber": "CARTON_02"
}
]
The same behavior as for GET /jobs/{jobId}/picklists.
jobId required | integer <int64> >= 1 The Id of the job. |
[- {
- "solutionId": 1,
- "loadingDeviceNumber": "CARTON_01",
- "picklist": [
- {
- "orderItemNumber": "tablet_45231",
- "quantity": 2
}, - {
- "orderItemNumber": "usb_power_supply_4484",
- "quantity": 5
}
]
}, - {
- "solutionId": 2,
- "loadingDeviceNumber": "CARTON_01",
- "picklist": [
- {
- "orderItemNumber": "tablet_45231",
- "quantity": 2
}
]
}, - {
- "solutionId": 3,
- "loadingDeviceNumber": "CARTON_02",
- "picklist": [
- {
- "orderItemNumber": "tablet_45231",
- "quantity": 1
}
]
}
]
The same behavior as for GET /jobs/{jobId}.
jobId required | integer <int64> >= 1 The Id of the job. |
{- "parameters": {
- "...": "..."
}, - "order": {
- "orderNumber": "order_23129",
- "orderLines": [
- {
- "orderLineNumber": 10,
- "orderItem": {
- "number": "tablet_45231",
- "length": 130,
- "width": 120,
- "height": 80,
- "grossWeight": 500,
- "group": "electronic devices",
- "heightVerticalPermitted": true,
- "widthVerticalPermitted": false,
- "lengthVerticalPermitted": false,
- "extension": { },
- "name": "an unbranded tablet",
- "maxWeightOnTop": 10000
}, - "quantity": 5,
- "extension": {
- "...": "..."
}
}, - {
- "orderLineNumber": 20,
- "orderItem": {
- "number": "usb_power_supply_4484",
- "length": 37,
- "width": 51,
- "height": 22,
- "grossWeight": 22,
- "group": "electronic devices - accessories",
- "heightVerticalPermitted": true,
- "widthVerticalPermitted": false,
- "lengthVerticalPermitted": false,
- "extension": { },
- "name": "an unbranded powers supply",
- "maxWeightOnTop": 1000
}, - "quantity": 5,
- "extension": {
- "...": "..."
}
}
], - "extension": {
- "...": "..."
}
}, - "loadingDevices": [
- {
- "number": "CARTON_01",
- "type": "FEFCO0201",
- "materialThickness": 10,
- "outerHeight": 140,
- "outerWidth": 320,
- "outerLength": 420,
- "height": 100,
- "width": 300,
- "length": 400,
- "name": "off-the-shelf FEFCO0201 carton with 5 cm empty space on each side",
- "maxLoadWeight": 50000,
- "emptyWeight": 500,
- "lengthOverhang": -50,
- "widthOverhang": -50,
- "extension": {
- "...": "..."
}
}, - {
- "number": "CARTON_02",
- "type": "FEFCO0201",
- "materialThickness": 10,
- "outerHeight": 125,
- "outerWidth": 150,
- "outerLength": 160,
- "height": 85,
- "width": 130,
- "length": 140,
- "name": "adjusted FEFCO0201 carton to ship a single tablet",
- "maxLoadWeight": 50000,
- "emptyWeight": 500,
- "lengthOverhang": 0,
- "widthOverhang": 0,
- "extension": {
- "...": "..."
}
}
], - "solutions": [
- {
- "positions": [
- {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 126,
- "y": 119,
- "z": 0,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 20
}, - {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 126,
- "y": 68,
- "z": 0,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 20
}, - {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 6,
- "y": 52,
- "z": 0,
- "orientation": 2,
- "immutable": false,
- "orderLineNumber": 10
}, - {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 174,
- "y": 52,
- "z": 0,
- "orientation": 2,
- "immutable": false,
- "orderLineNumber": 10
}, - {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 126,
- "y": 17,
- "z": 0,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 20
}, - {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 126,
- "y": 106,
- "z": 22,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 20
}, - {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 126,
- "y": 30,
- "z": 22,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 20
}
], - "id": 1,
- "extension": {
- "...": "..."
}, - "remainder": [
- {
- "orderLineNumber": 10,
- "quantity": 3
}
], - "loadingDeviceNumber": "CARTON_01"
}, - {
- "positions": [
- {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 10,
- "y": 40,
- "z": 0,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 10
}, - {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 160,
- "y": 40,
- "z": 0,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 10
}
], - "id": 2,
- "extension": {
- "...": "..."
}, - "remainder": [
- {
- "orderLineNumber": 10,
- "quantity": 1
}
], - "loadingDeviceNumber": "CARTON_01"
}, - {
- "positions": [
- {
- "type": "item",
- "extension": {
- "...": "..."
}, - "x": 5,
- "y": 5,
- "z": 0,
- "orientation": 1,
- "immutable": false,
- "orderLineNumber": 10
}
], - "id": 3,
- "extension": {
- "...": "..."
}, - "remainder": [ ],
- "loadingDeviceNumber": "CARTON_02"
}
], - "extension": {
- "...": "..."
}
}
The same behavior as for PUT /jobs/{jobId}.
jobId required | integer <int64> >= 1 The Id of the job. |
required | object (InputEntityJob) |
{- "job": {
- "parameters": { },
- "order": {
- "orderNumber": "order_23129",
- "orderLines": [
- {
- "orderLineNumber": 10,
- "quantity": 5,
- "orderItem": {
- "number": "tablet_45231",
- "name": "an unbranded tablet",
- "group": "electronic devices",
- "length": 130,
- "width": 120,
- "height": 80,
- "grossWeight": 500,
- "maxWeightOnTop": 10000
}
}, - {
- "orderLineNumber": 20,
- "quantity": 5,
- "orderItem": {
- "number": "usb_power_supply_4484",
- "name": "an unbranded powers supply",
- "group": "electronic devices - accessories",
- "length": 37,
- "width": 51,
- "height": 22,
- "grossWeight": 22,
- "maxWeightOnTop": 1000
}
}
]
}, - "loadingDevices": [
- {
- "type": "FEFCO0201",
- "number": "CARTON_01",
- "name": "off-the-shelf FEFCO0201 carton with 5 cm empty space on each side",
- "length": 400,
- "width": 300,
- "height": 100,
- "materialThickness": 10,
- "lengthOverhang": -50,
- "widthOverhang": -50,
- "maxLoadWeight": 50000,
- "emptyWeight": 500
}, - {
- "type": "FEFCO0201",
- "number": "CARTON_02",
- "name": "adjusted FEFCO0201 carton to ship a single tablet",
- "length": 140,
- "width": 130,
- "height": 85,
- "materialThickness": 10,
- "lengthOverhang": 0,
- "widthOverhang": 0,
- "maxLoadWeight": 50000,
- "emptyWeight": 500
}
]
}
}
JSON cannot be parsed.
{- "errorMessage": "While parsing the JSON, an error occurred.",
- "errorClass": "public class com.fasterxml.jackson.databind.exc.InvalidTypeIdException",
- "additionalInformation": "Missing type id when trying to resolve subtype of [simple type, class de.fraunhofer.iml.puzzle.coreentity.LoadingDevice]: missing type id property 'type' (for POJO property 'loadingDevices')\n at source: rg.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1004] (through reference chain: de.fraunhofer.iml.puzzle.specification.jobsAPI.models.CreationTask[\"job\"] .fraunhofer.iml.puzzle.coreentity.EntityJob[\"loadingDevices\"]->java.util.ArrayList[0])"
}
The same behavior as for DEL /jobs/{jobId}.
jobId required | integer <int64> >= 1 The Id of the job. |
{- "errorMessage": "PUZZLE cannot find job with id 123",
- "additionalInformation": "",
- "errorClass": "de.fraunhofer.iml.puzzle.adapter.execution.Exceptions.Rest.PuzzleJobNotFoundException"
}
The same behavior as for GET /jobs/{jobId}/prolong.
jobId required | integer <int64> >= 1 The Id of the job. |
{- "errorMessage": "PUZZLE cannot find job with id 123",
- "additionalInformation": "",
- "errorClass": "de.fraunhofer.iml.puzzle.adapter.execution.Exceptions.Rest.PuzzleJobNotFoundException"
}