Introduction
Welcome to the adiutaByte API. The goal of the API is to provide an interface for generating plans for various fleet optimization problems. This API description is intended to help setting up your own code to access the adiutaByte API. Currently there are two API endpoints implemented. The first one is for submitting a problem description, for which an optimized plan is then calculated. The second endpoint is for retrieving this finalized plan.
The API uses token-based authentication to protect these endpoints, users are generated on demand. Feel free to contact us for such a personalized access.
Currently the API solely supports JSON formatted data with a schema that is used to validate the data. Non-valid requests are immediately rejected with an error message. In each section a downloadable corresponding JSON schema in the latest version is linked.
Tags
- Features that are planned and not yet implemented are marked with TBA (Example: timeEarliest TBA). These are in a conceptual phase and might still get changed or deleted.
- Some features might not yet work, depending on what application version the plan is being calculated on. Features that are not yet live for all requests are marked with the version they are first introduced on (Example: timeEarliest v1.0.0). To determine the used version, check
Deployment Status
.
Examples in this documentation will use all listed fields regardless of their introduced version, so please check availability before using them.
Restrictions
Certain values on input objects can restrict the general set of available solutions. These include time windows on tasks, workers or shifts, preferences of all kinds, categories, qualifications and many more. Due to the nature of optimization, not all of them can be kept nor is that even intended, as violating a constraint can often lead to vast improvements regarding another metric. Nevertheless there are some constraints the algorithm will keep at all costs, as they are deemed too important to be disregarded.
To differentiate the types of constraints, there will be an occasional Depends on column added to the parameter listing. It can contain a number of different text markers:
- "strict": A constraint that the algorithm either literally cannot violate or can do so but only in a worst-case scenario, for instance to keep another strict constraint. (Example:
qualification
) - An optimization parameter: The constraint depends on the optimization parameter setting. The higher the setting value, the more likely it is for the restriction to be kept. However, unless noted otherwise, it cannot reach the importance level of a strict constraint. (Example:
preferredWorkers
) - Nothing: The parameter either is not a constraint or its importance cannot be influenced via input data settings. (Example:
gender
ordesiredWorker
)
Contact us
If you notice issues or an error with the documentation, if you have questions regarding the API or its documentation or if you're having another related issue, please contact us.
Checking your requests for validity
To check your request json for validity you can download validation scripts here:
production | v1.7.0 | Validator Scripts |
develop | v1.7.0 | Validator Scripts |
experimental | v1.7.0 | Validator Scripts |
Post a new plan
HTTP-Endpoint
This endpoint is used to POST a new problem description for obtaining an optimized plan based on it.
DEVEL | POST https://develop.compute-adiutabyte.de/shift-description |
PROD | POST https://production.compute-adiutabyte.de/shift-description |
Request
Example
{
"meta": {
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
},
"parameters": {
"fairDistribution": 4,
"timeliness": 5,
"workerPrefs": 5,
"workerReduction": 1
},
"tasks": [
{
"date": "2019-12-03",
"duration": 65,
"taskID": 200,
"timeEarliest": "10:00",
"timeLatest": "12:00"
},
{
"date": "2019-12-03",
"duration": 25,
"taskID": 201,
"timeEarliest": "16:00",
"timeLatest": "17:00"
}
],
"workers": [
{
"workerID": 1,
"shifts": [
{
"shiftStart": "08:00",
"shiftEnd": "20:00",
"shiftDate": "2019-12-03",
"shiftID": 1
}
]
}
],
"client": {
"clientID": "{1234-5678-9123}"
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Required | Type | Description |
---|---|---|---|
client | client | Contains information about the client which sends this request. | |
meta | ✔ | meta | Meta information about what to consider in the optimization. |
parameters | ✔ | parameters | Parameters for the optimizer. |
tasks | ✔ | Array<Input Task> |
Array of Tasks to be planned by the optimizer. |
workers | ✔ | Array<Input Worker> |
Array of available Workers. |
history v3.4.0 | History | History data. |
Result
Example of an ID
AAAAAAAAABBBBBBBBBBBBBBBEEEEEEEEEEEEEEEEEDDDDDDDDDD
Posting a plan returns an ID to monitor the planning process and retrieve the solution.
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The plan was accepted but has been submitted at least once before and is either finished or still in calculation. |
201 | CREATED | The plan was accepted and is going to be processed by the optimization procedures. |
403 | FORBIDDEN | Your account is setup to use different clients. The clientID was not given or the clientID was not registered yet. |
409 | CONFLICT | The limit for the user or client has been exceeded. |
422 | UNPROCESSABLE ENTITY | The plan generated by the backend does not match the JSON-schema. Please check the API documentation carefully or contact us to correct this failure. |
500 | INTERNAL SERVER ERROR | Backend failure, please contact us. |
Client Information
Examples:
{
"clientID": "{1234-5678-9123}"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
clientID | string | ✔ | Identifies a specific client. |
Restrictions
- Minimum length: 1.
Meta Information
Examples:
{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
}
{
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03",
"resCategory": false,
"resQualification": false,
"accuracyMode": 1.0,
"outputLanguage": 1,
"minQualificationOfTaskCoverage": 2,
"omnipresentCategoriesOfTaskCoverage": [3,5,6],
"enablePlanSplitting": false,
"allowUnassignedTasks": true,
"followBiorhythm": true,
"minConcurrentSolutions": 1,
"minTaskDuration": 10
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
dateFrom | string (date) | ✔ | Planning horizon start. |
dateTo | string (date) | ✔ | Planning horizon end. |
resCategory | boolean | Activate/Deactivate whether category types should be considered in the optimization. (Default: false) | |
resQualification | boolean | Activate/Deactivate whether qualifications should be considered in the optimization. (Default: false) | |
accuracyMode | number | Manages a solution refinement process. An accuracy > 0.0 can improve the solution significantly but will take longer to calculate, effects increase with higher accuracyMode. (Default: 1.0) | |
outputLanguage | integer (LanguageType) | Defines which language should be used in the output. (Default: German) | |
minQualificationOfTaskCoverage | integer | At each minute between dateFrom at 00:00 and dateTo at 23:59 there shall be least one Worker of this qualification or higher performing a task. |
|
omnipresentCategoriesOfTaskCoverage | Array<integer> |
For each of these categories, at each minute between dateFrom at 00:00 and dateTo at 23:59 there shall be least one Worker with the category performing a task. |
|
enablePlanSplitting | boolean | (Default: true) Enables splitting the plan into disjunct plan parts. This can reduce runtime or improve pre-optimization data adjustment. | |
allowUnassignedTasks | boolean | (Default: false) This option enables an unassignment behavior in the algorithm, meaning it will, if deemed necessary, refuse to assign subsets of tasks to any worker. Examples are scenarios where the only qualified workers are overloaded or there are no workers that can even carry out a task. In the output data this can be recognized by the task missing its assignment data, such as timeScheduled or assignedWorker . The differences to an assigned task are noted in the description for the Output Task. Additionally, the info section will notify of unassignment and, if possible, the reason for it. |
|
followBiorhythm | boolean | Tasks shall be spaced out so that there is at least a 24h time span between the start of consecutive tasks on the same worker. | |
minConcurrentSolutions v3.2.0 | integer | Number of concurrently calculated solutions. Developer feature, use at your own risk! (Default: 1) | |
minTaskDuration v3.10.0 | integer | Minimum value for an Input Task's duration . Task durations with a lower value are being overwritten before the optimization. Profit calculations (e.g. costsPerMinute ), coverage, etc use adjusted values. (Default: 0) |
Notes
- The options
res*
describe which fields from the dataset should be taken into account. More precisely those are:
Optimization Parameters
Examples:
{}
{
"preset": 0,
}
{
"preset": 0,
"fairDistribution": 4,
"timeliness": 5,
"workerPrefs": 5,
"teamPrefs": 5,
"taskPrefs": 5,
"worktimePrefs": 5,
"workerReduction": 1,
"genderPref": 2,
"profitability": 3
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
All parameters (except preset
) are integer numbers between 0 and 9 (inclusive). You only need to pass the ones you want to use, the other will be implicitly set to 0.
Parameter | Type | Required | Description |
---|---|---|---|
preset | integer | Sets the parameters to a predefined preset (details below). Parameters specified in the json-body will override the preset. | |
fairDistribution | integer | Distribute the tasks fairly among the workers. | |
timeliness | integer | Optimize towards satisfying the time windows. | |
workerPrefs | integer | Try to satisfy the workers' preferences. | |
teamPrefs | integer | Try to satisfy preferences in relations between workers. | |
taskPrefs | integer | Try to satisfy preferences set in tasks. | |
worktimePrefs | integer | Try to satisfy working time related restrictions. | |
workerReduction | integer | Reduce the number of necessary workers. | |
genderPref | integer | Try to satisfy any tasks' gender preferences. Setting this parameter to 9 will upgrade the algorithm to consider prefGender a restriction rather than merely a preference. |
|
profitability | integer | Optimize towards high single-worker profitability. |
The following presets are currently available (parameters not listed are set to 0):
ID | Name | Parameter settings |
---|---|---|
0 v3.8.16 | Random | The value timeliness is set to a random value 1 to 9. The values workerPrefs , teamPrefs , taskPrefs , workerReduction , genderPref , profitability , worktimePrefs , fairDistribution are set to a random value 0 to 9. |
Input Task
Examples:
{
"taskID": 200,
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00"
}
{
"taskID": 200,
"externalID": "id123",
"date": "2019-12-03",
"duration": 240,
"timeEarliest": "06:00",
"timeLatest": "12:00",
"timePriority": 2,
"prefWorkers": [1,2],
"antiWorkers": [5,6],
"forbWorkers": [3,4],
"qualification": 3,
"maxQualification": 6,
"categories": [1],
"exchangeableCategories": [2,4],
"preassignedWorker": 2,
"desiredWorker": 2,
"prefGender": 1,
"predecessorTasks": [1,2],
"group": 2,
"revenue": 2.123,
"assignmentPriority": 2,
"initassignedWorker": 1,
"initassignedOrder": 1
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The unassigned task is the incoming task description for the optimizer outlining the restrictions for the optimization.
Parameter | Required | Type | Description | Depends on |
---|---|---|---|---|
taskID | ✔ | integer | The ID of this task. IDs need to be unique among all Tasks. | |
externalID | string | A string to identify the task in the solution. Cannot be used for reference in the input data or the optimizer, it serves as a helping tool for integrations. | ||
date | ✔ | string (date) | The date this task should be planned on. | timeliness |
duration | ✔ | integer | The time in minutes it takes to complete this task. | strict |
timeEarliest | ✔ | string (time) | The earliest possible starting time of this task. | timeliness |
timeLatest | ✔ | string (time) | The latest time at which this task should be finished. | timeliness |
timePriority | integer | The priority of the time window ranging from 0-5. Tasks with high time priority are more likely to get scheduled inside their given time window. Tasks with time priority 0 completely ignore their given time window. | ||
prefWorkers | Array<integer> |
The IDs of preferred workers. | taskPrefs | |
antiWorkers | Array<integer> |
The IDs of workers to which an assignment is undesirable but not strictly forbidden. | taskPrefs | |
forbWorkers | Array<integer> |
The IDs of forbidden workers. | strict | |
qualification | integer | The minimum qualification of the worker required to perform the task (e.g. years of experience). Workers without qualification are not allowed to perform any task with set qualification. | strict | |
maxQualification v3.8.0 | integer | The maximum qualification of the worker allowed to perform the task. Workers without qualification can carry out any task with qualification (as long as the other restrictions are not violated). | strict | |
categories | Array<integer> |
A suitable worker has to fulfill all of these categories. | strict | |
exchangeableCategories | Array<integer> |
A suitable worker has to fulfill at least one of these categories. | strict | |
preassignedWorker | integer | The unique ID of the worker who has to take over this task. v3.6.1 This overrules any other strict restriction, for example, if the worker does not fulfil the qualification requirement, the task will still get assigned to them. | strict | |
desiredWorker | integer | The unique ID of the worker who is desired (strong preference, not influenced by workerPrefs) to take over this task. | ||
prefGender | integer (gender) | The preferred gender for the assigned worker. | genderPrefs, strict if set to 9 | |
precedingTasks | Array<integer> |
v4.0.0 DEPRECATED | strict | |
predecessorTasks | Array<integer> |
The tasks of which one has to be performed right before this task by the same worker as this task. | strict | |
group | integer | A group ID. Tasks with the same group ID get assigned to the same worker. | strict | |
groupOrder | integer | v4.0.0 DEPRECATED | strict | |
revenue | number | The revenue which will be achieved with this task. | ||
initassignedShift | integer | v4.0.0 DEPRECATED | ||
assignmentPriority | integer | A priority for assignment (see allowUnassignedTasks ) ranging 0-5.
|
strict on value 5 | |
initassignedWorker v4.0.0 | integer | The ID of the worker who will be initially assigned. This creates a higher likelihood of the task being assigned to this worker in the solution, especially if the initial assignment stems from a previous solution. | ||
initassignedOrder v4.0.0 | integer | The order within the initially assigned worker's tour. Requires an initassignedWorker or a preassignedWorker . |
Input Worker
Examples:
{
"workerID": 1
}
{
"workerID": 1,
"externalID": "id123",
"qualification": 1,
"categories": [1,2],
"desiredCategory": 12,
"prefCategories": [3],
"prefWeekCategories": [2],
"prefWeekendCategories" : [3],
"prefWorkers": [5,43],
"antiWorkers": [5,43],
"shifts": [
{
"shiftStart": "05:00",
"shiftEnd": "12:00",
"shiftDate": "2019-12-03"
}
],
"gender": 1,
"expectedWorkingMinutes": 9200,
"minWorkingMinutes": 8000,
"maxWorkingMinutes": 12000,
"maxConsecutiveWorkdays": 6,
"minConsecutiveWorkdays": 6,
"prefConsecutiveWorkdays": 6,
"carryoverConsecutiveWorkdays": 0,
"maxConsecutiveOffdays": 2,
"minConsecutiveOffdays": 2,
"prefConsecutiveOffdays": 15,
"carryoverConsecutiveOffdays": 1,
"minBreakMinutesBetweenTasks": 600,
"maxDailyWorkingMinutes": 600,
"minFreeSaturdays": 4,
"minFreeSundays": 5,
"maxWeeklyWorkingMinutes": 3000,
"carryoverWorkingMinutesLastWeek": 50,
"maxTwoWeekWorkingMinutes": 4800,
"carryoverWorkingMinutesSecondLastWeek": 2100,
"dontVary": true,
"costsPerMinute": 1.123,
"costsInitial": 100.12,
"precTaskDate": "2019-12-02",
"precTaskScheduled": "12:00",
"precTaskDuration": 120,
"precNightShifts": 2,
"maxOrderedGroups": 2,
"maxDesiredOrderedGroups": 1,
"maxNightShifts": 3,
"maxDesiredNightShifts": 2,
"minFreeWeekends": 2,
"minDesiredFreeWeekends": 1,
"maxConsecutiveSameTaskStart": 1,
"maxDesiredConsecutiveSameTaskStart": 1,
"maxWeeklyWorkingDays": 1,
"prefWeeklyWorkingDays": 1,
"carryoverWorkingDaysLastWeek": 12,
"minConsecutiveFreeWeekends": 1,
"minDesiredConsecutiveFreeWeekends": 1,
"maxConsecutiveFreeWeekends": 1,
"maxDesiredConsecutiveFreeWeekends": 1,
"minConsecutiveWorkingWeekends": 1,
"minDesiredConsecutiveWorkingWeekends": 1,
"maxConsecutiveWorkingWeekends": 1,
"maxDesiredConsecutiveWorkingWeekends": 1,
"precWeekendWorkingDay": "2019-12-01",
"carryoverConsecutiveWorkingWeekends": 1
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The worker has both optional and required parameters as marked in the following table.
Parameter | Required | Type | Description | Depends on |
---|---|---|---|---|
workerID | ✔ | integer | The ID of the worker. Needs to be unique among all workers. | |
externalID | string | A string to identify the worker in the solution. Cannot be used for reference in the input data or the optimizer, it serves as a helping tool for integrations. | ||
qualification | integer | The qualification of the worker. They are able to take over tasks with the same or lower qualifications. | strict | |
categories | Array<integer> |
The categories the workers can take over. | strict | |
desiredCategory | integer | The worker has a strong preference towards tasks with this category. | ||
prefCategories | Array<integer> |
The task categories preferred by the worker. | workerPrefs | |
prefWeekCategories | Array<integer> |
The task categories preferred by the worker on any week day (Mon-Fri). | workerPrefs | |
prefWeekendCategories | Array<integer> |
The task categories preferred by the worker on any weekend day (Sat, Sun). | workerPrefs | |
prefWorkers | Array<integer> |
The workers that this worker prefers to have simultaneous shifts with. | teamPrefs | |
antiWorkers | Array<integer> |
The workers that this worker prefers to not have simultaneous shifts with. | teamPrefs | |
shifts | Array<Shift> |
The time slots at which a worker can perform exactly one task each. | ||
gender | integer (gender) | The gender type of the worker. | ||
expectedWorkingMinutes | integer | The preferred amount of working time minutes for this worker in the final plan, deviation in both directions will be kept as low as possible. | worktimePrefs | |
minWorkingMinutes | integer | The minimum amount of working time minutes for this worker in the final plan. | ||
maxWorkingMinutes | integer | The maximum amount of working time minutes for this worker in the final plan. | ||
maxConsecutiveWorkdays | integer | Maximum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: no limit | ||
minConsecutiveWorkdays | integer | Minimum number of consecutive workdays. A day is a workday if any work is performed from 00:00 to 23:59. Default: 0 | ||
prefConsecutiveWorkdays | integer | The preferred number of working days in a row. | workerPrefs | |
carryoverConsecutiveWorkdays | integer | The current number of consecutive workdays at the start of the plan. | ||
maxConsecutiveOffdays | integer | Maximum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: no limit | ||
minConsecutiveOffdays | integer | Minimum number of consecutive offdays. A day is an offday if no work is performed from 00:00 to 23:59. Default: 0 | ||
prefConsecutiveOffdays | integer | The preferred number of non-working days in a row. | workerPrefs | |
carryoverConsecutiveOffdays | integer | The current number of consecutive offdays at the start of the plan. | ||
minBreakMinutesBetweenTasks | integer | Minimum number of minutes break between two Tasks that start on different days. Default: 0 | strict | |
maxDailyWorkingMinutes | integer | Maximum number of working minutes per day. Default: no limit | ||
minFreeSaturdays | integer | Minimum number of work-free Saturdays for this worker. | strict | |
minFreeSundays | integer | Minimum number of work-free Sundays for this worker. | strict | |
maxWeeklyWorkingMinutes | integer | Maximum minutes working time for this worker each calendar week (Monday to Sunday). Please note that the week cycle might be independent from the planning horizon, use carryoverWorkingMinutesLastWeek in conflicting cases. |
||
carryoverWorkingMinutesLastWeek | integer | Minutes of worktime already performed by this worker in the week that dateFrom belongs to. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes ! |
||
maxTwoWeekWorkingMinutes | integer | Maximum minutes working time for this worker for every two consecutive calendar weeks (Monday to Sunday). Please note that the week cycle is independent from the planning horizon, use carryoverWorkingMinutesLastWeek and carryoverWorkingMinutesSecondLastWeek in conflicting cases. |
||
carryoverWorkingMinutesSecondLastWeek | integer | Minutes of worktime already performed by this worker in the week prior to the earliest shiftStartpre v3.8.12/ dateFrom v3.8.12 of any Worker in this plan. The value is factored in by maxWeeklyWorkingMinutes and maxTwoWeekWorkingMinutes but not expectedWorkingMinutes ! |
||
dontVary | boolean | A worker with dontVary set to true is "fixed" for the optimizer, meaning they get assigned all tasks (and only those tasks) that have this worker set as preassignedWorker or initassignedWorker in the order of initassignedOrder . That also means that initassignedOrder is required for these tasks. All output information still gets calculated on both worker and task, and the worker and its tasks will be considered in Statistics and Info. |
strict | |
costsPerMinute | number | The costs per minute working time (carrying out tasks) for this worker (e.g. monthly salary converted to minutes). | profitability | |
costsInitial | number | Costs that occur if there is at least one task assigned to the worker. | profitability | |
precTaskDate | string (date) | Date of the last task the worker carried out before the start of this plan. | ||
precTaskScheduled | string (time) | Scheduled time of the last task the worker carried out before the start of this plan. | ||
precTaskDuration | integer | Duration of the last task the worker carried out before the start of this plan. | ||
precNightShifts | integer | Amount of consecutive "night shifts" the worker carried out directly before the start of this plan. Those are Tasks that are scheduled in a way that they overlap with midnight. For more details see below. | ||
maxOrderedGroups | integer | The maximum number of task sets with same group and set group order that can be assigned to this worker. | strict | |
maxDesiredOrderedGroups | integer | A preference for the maximum number of task sets with same group and set group order that can be assigned to this worker. | ||
maxNightShifts | integer | The maximum number of "night shifts" this worker can get assigned. | strict | |
maxDesiredNightShifts | integer | A preference for the maximum number of "night shifts" this worker can get assigned. | ||
minFreeWeekends | integer | The minimum number of completely free weekends with no work on either Saturday or Sunday. See below for annotations. | strict | |
minDesiredFreeWeekends | integer | A preference for the minimum number of completely free weekends with no work on either Saturday or Sunday. See below for annotations. | ||
maxConsecutiveSameTaskStart v3.3.0 | integer | The maximum number of assigned consecutive tasks with the same timeScheduled (v3.5.1 timeScheduled difference of at most 120 min still counts as the same task start). |
strict | |
maxDesiredConsecutiveSameTaskStart v3.3.0 | integer | A desired maximum number of assigned consecutive tasks with the same timeScheduled (v3.5.1 timeScheduled difference of at most 120 min still counts as the same task start). |
||
maxWeeklyWorkingDays v3.3.0 | integer | The maximum number of tasks in one week. Tasks only count for the week they start in (timeScheduled ). |
strict | |
prefWeeklyWorkingDays v3.3.0 | integer | The preferred maximum number of tasks in one week. Tasks only count for the week they start in (timeScheduled ). |
||
carryoverWorkingDaysLastWeek v3.3.0 | integer | Number of already carried-out workdays in the week that dateFrom belongs to. |
||
minConsecutiveFreeWeekends v3.9.0 | integer | The minimum amount of consecutive weekends without any tasks assigned (task starting on either Saturday or Sunday). This restriction does not apply to the end of the planning horizon, there may be less free weekends than set here right before dateTo . Further information regarding weekends below. |
strict | |
minDesiredConsecutiveFreeWeekends v3.9.0 | integer | The desired minimum amount of consecutive weekends without any tasks assigned (task starting on either Saturday or Sunday). This restriction does not apply to the end of the planning horizon, there may be less free weekends than set here right before dateTo . Further information regarding weekends below. |
||
maxConsecutiveFreeWeekends v3.9.0 | integer | The maximum amount of consecutive weekends without any tasks assigned (task starting on either Saturday or Sunday). Further information regarding weekends below. | strict | |
maxDesiredConsecutiveFreeWeekends v3.9.0 | integer | The desired maximum amount of consecutive weekends without any tasks assigned (task starting on either Saturday or Sunday). Further information regarding weekends below. | ||
minConsecutiveWorkingWeekends v3.9.0 | integer | The minimum amount of consecutive weekends with at least one task assigned (task starting on either Saturday or Sunday). Further information regarding weekends below. | strict | |
minDesiredConsecutiveWorkingWeekends v3.9.0 | integer | The desired minimum amount of consecutive weekends with at least one task assigned (task starting on either Saturday or Sunday). Further information regarding weekends below. | ||
maxConsecutiveWorkingWeekends v3.9.0 | integer | The maximum amount of consecutive weekends with at least one task assigned (task starting on either Saturday or Sunday). Further information regarding weekends below. | strict | |
maxDesiredConsecutiveWorkingWeekends v3.9.0 | integer | The desired maximum amount of consecutive weekends with at least one task assigned (task starting on either Saturday or Sunday). Further information regarding weekends below. | ||
precWeekendWorkingDay v3.9.0 | string (date) | The latest working day on a weekend before dateFrom . |
||
carryoverConsecutiveWorkingWeekends v3.9.0 | integer | The amount of consecutive weekends with at least one task performed on either Saturday or Sunday on and before the first complete weekend before dateFrom . See below for explanations. |
Restrictions
- Only one of
carryoverConsecutiveWorkdays
andcarryoverConsecutiveOffdays
is allowed - Only one of
maxConsecutiveSameTaskStart
andmaxDesiredConsecutiveSameTaskStart
is allowed
Notes
Categories specified in
desiredCategory
,prefCategories
,prefWeekCategories
,prefWeekendCategories
are automatically considered valid as if they're listed incategories
.The parameter
precNightShifts
is used for carrying over the biorhythm between different, consecutive plans. As such, the tasks on the days directly before the plan start are relevant. As an example, let the plan start on 2020-05-01:- If on 2020-04-30 no task was scheduled or a task was scheduled that did not overlap with the midnight to 2020-05-01, the value has to be 0.
- If on 2020-04-30 a task was scheduled that overlaps with midnight to 2020-05-01, the value has to be at least 1; exactly 1 if this is not true for 2020-04-29.
- If, additionally to the case above, on 2020-04-29 a task was scheduled that overlaps with midnight to 2020-04-30, the value has to be at least 2; exactly 2 if this is not true for 2020-04-28.
- And so on...
If either
precTaskDate
,precTaskScheduled
, orprecTaskDuration
is set, all of the values have to be set. IfprecNightShifts
is set, all of the three mentioned values have to be set as well.Please note the following behavior regarding free weekend consideration (
minFreeWeekends
,minConsecutiveFreeWeekends
,maxConsecutiveFreeWeekends
, etc):- If the last day of the plan is a Saturday, that weekend will not count as a free weekend.
- For all weekend counters (e.g.
minFreeWeekends
): If the first day of the plan is a Sunday, data fromprecTaskDate
will get used to determine if this starting weekend can be "free" or not. IfprecTaskDate
if is earlier than the Saturday and nothing is assigned on Sunday, the weekend is considered a free weekend for this plan, if either theprecTaskDate
is the Saturday or a task is assigned on Sunday, it is not. If noprecTaskDate
is given, the weekend will not count as a free weekend regardless. - For all consecutive weekend counters (e.g.
minConsecutiveFreeWeekends
): IfprecWeekendWorkingDay
is set, its data will be used to determine the amount of free weekends before plan start. If it isn't set, zero free weekends before the plan will be assumed. If in addition the first day of the plan (dateFrom
) is a Sunday, that weekend will count as a working weekend.
Important edge case behavior for
carryoverConsecutiveWorkingWeekends
:dateFrom
is not a Sunday:carryoverConsecutiveWorkingWeekends
should behave like all carry over data (e.g.carryoverConsecutiveWorkdays
) - its value should be the amount of consecutive working weekends (at least one task performed on Saturday or Sunday) directly before the start of the planning horizon (dateFrom
). If the last weekend beforedateFrom
was free,carryoverConsecutiveWorkingWeekends
should either not be set or 0.dateFrom
is a Sunday, there was a task on the Saturday directly before that (precWeekendWorkingDay
should be set to exactly that Saturday):carryoverConsecutiveWorkingWeekends
must count the weekenddateFrom
is on as a working weekend. E.g. if the last complete weekend beforedateFrom
was a working weekend, the counter should be at 2.dateFrom
is a Sunday but not task was on Saturday: This is the important edge case, since now it's up to the optimizer, whether or not the weekend will be free or not. In this case, the weekenddateFrom
is on must not be considered forcarryoverConsecutiveWorkingWeekends
, the value must act as ifdateFrom
was on Saturday instead. E.g. if Saturday was free but the last two weekends before that Saturday were working weekends,carryoverConsecutiveWorkingWeekends
must be set to 2. This allows the optimizer to carry on with the working weekends streak if it assigns a task on Sunday but also break the streak if it doesn't.
All fields with "carryover data" (
precTaskDate
,carryoverConsecutiveWorkdays
, ...) are not validated against each other. It is the responsibility of the requester to ensure valid and correct data.
Shift
Examples:
{
"shiftDate": "2019-12-03",
"shiftStart": "05:00",
"shiftEnd": "12:00"
}
{
"shiftDate": "2019-12-03",
"shiftStart": "05:00",
"shiftEnd": "12:00",
"shiftPriority": 2
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A shift represents a worker's time slot in which exactly one Task can be carried out. For exceptions see the groupOrder
parameter in Tasks.
Parameter | Required | Type | Description |
---|---|---|---|
shiftID | ✔ | integer | v4.0.0 DEPRECATED |
shiftDate | ✔ | string (date) | The date this time slot is available on. |
shiftStart | ✔ | string (time) | The time this time slot starts. |
shiftEnd | ✔ | string (time) | The time this time slot ends. |
shiftPriority | integer | The priority to assign tasks within the defined shift start/end times ranging from 0-3: irrelevant, neutral, important, very important. (Default: 1) |
History
Introduced in: v3.4.0
{
"workers": [],
"tasks": []
}
{
"workers": [
{
"workerID": 1,
"excludedDays": [
"2023-02-12",
"2023-02-11"
]
}
],
"tasks": [
{
"taskID": 1,
"scheduling": [
{
"date": "2023-01-01",
"assignedWorker": 11,
"assignedWorkerAutomatically": 11,
"actualWorker": 1,
"actualStartTime": "12:30"
}
]
}
],
"additionalTasks": [
{
"taskID": 2,
"date": "2022-12-31",
"timeEarliest": "12:00",
"timeLatest": "12:00",
"duration": 120
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The ShiftPlanner history contains historical data for plan tasks and workers as well as additional tasks that are not part of the optimization but can provide further information for the historical data analysis.
Parameter | Required | Type | Description |
---|---|---|---|
tasks | ✔ | Array<History-Task> |
Tasks which are connected to plan tasks or additional tasks via taskID . |
workers | ✔ | Array<History-Workers> |
Workers which are connected to plan workers via workerID . |
additionalTasks | Array<Input Task> |
Tasks that are not part of this optimization but have historical relevance (for instance they were assigned to a plan worker). |
History-Worker
Introduced in: v3.4.0
{
"workerID": 1
}
{
"workerID": 1,
"excludedDays": [
"2023-02-12",
"2023-02-11"
],
"preferenceFulfilledOn": [
"2023-02-12",
"2023-02-11"
],
"preferenceNotFulfilledOn": [
"2023-02-12",
"2023-02-11"
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A History-Worker is a worker which is also featured in the workers
array of the request, connected via workerID
. It provides further worker-specific information to the history entries.
Parameter | Required | Type | Description |
---|---|---|---|
workerID | ✔ | integer | The ID of this worker, unique among all History-Workers. Has to correspond to a workerID of an Input Worker in the request. |
excludedDays | Array<Date> |
Dates that should be disregarded for historical analysis (e.g. sick days, schooling, ...). | |
preferenceFulfilledOn | Array<Date> |
Days on which a preference was fulfilled. | |
preferenceNotFulfilledOn | Array<Date> |
Days on which a preference was not fulfilled. |
History-Task
Introduced in: v3.4.0
{
"taskID": 2,
"scheduling": [
{
"date": "2022-12-24",
"assignedWorker": 2,
"assignedWorkerAutomatically": 1,
"actualWorker": 1,
"actualStartTime": "12:30"
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A History-Task contains all historical assignments of the task with its taskID
in either the tasks
array of the request or the additionalTasks
array in the request's history.
Parameter | Required | Type | Description |
---|---|---|---|
taskID | ✔ | integer | The ID of this task, unique among all History-Tasks. Has to correspond to a taskID of an Input Task in either the request or additionalTasks . |
scheduling | ✔ | Array<History-Assignment> |
All historical assignments of this task. |
History-Assignment
Introduced in: v3.4.0
{
{
"date": "2022-12-24"
}
}
{
{
"date": "2022-12-24",
"assignedWorker": 11,
"assignedWorkerAutomatically": 11,
"actualWorker": 1,
"actualStartTime": "12:30"
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A History-Assignment contains the data of exactly one historical assignment.
Parameter | Required | Type | Description |
---|---|---|---|
date | ✔ | Date | The date of this assignment. |
assignedWorker | integer | The worker (workerID ) the corresponding task was assigned to in the final planned version. |
|
assignedWorkerAutomatically | integer | The worker the corresponding task was assigned to by the optimizer at the time. | |
actualWorker | integer | The worker the task was actually carried out by, for instance as determined by mobile tracking. | |
actualStartTime | Time | The time the task was actually started, for instance as determined by mobile tracking. |
Check status/retrieve a Plan
HTTP-Endpoint
This endpoint is used to get the status of a plan or retrieve the plan once the calculation has been finished.
DEVEL | GET https://develop.compute-adiutabyte.de/plan/<ID> |
PROD | GET https://production.compute-adiutabyte.de/plan/<ID> |
Request
In the header of the request the field Accept
must be set to application/json
. The <ID>
which was delivered as a result of the post request needs to be given in the URL.
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The plan will be delivered. |
404 | NOT FOUND | The requested ID does not exist. |
406 | NOT ACCEPTABLE | The given Accept parameter in the header could not be used. |
422 | UNPROCESSABLE ENTITY | The plan generated by the backend does not match the JSON-schema. Please contact us to correct this failure. |
423 | LOCKED | The plan is currently optimized. Try again later to check if the calculation has finished. |
500 | INTERNAL SERVER ERROR | An error occured in the backend. Please contact us to check why this has happened. |
Result
Example
{
"meta": {
"dateFrom": "2019-12-03",
"dateTo": "2019-12-03"
},
"parameters": {
"fairDistribution": 4,
"timeliness": 5,
"workerPrefs": 5,
"workerReduction": 1
},
"tasks": [
{
"date": "2019-12-03",
"duration": 65,
"taskID": 200,
"timeEarliest": "10:00",
"timeLatest": "12:00",
"timeScheduled": "13:45",
"assignedWorker": 2,
"assignedShift": 1,
"info": "text",
"finalassignedOrder": 1,
"profit": 1.123
},
{
"date": "2019-12-03",
"duration": 25,
"taskID": 201,
"timeEarliest": "16:00",
"timeLatest": "17:00",
"info": "unassigned task"
}
],
"workers": [
{
"workerID": 1,
"shifts": [
{
"shiftStart": "08:00",
"shiftEnd": "20:00",
"shiftDate": "2019-12-03",
"shiftID": 1
}
],
"info": "text"
}
],
"client": {
"clientID": "{1234-5678-9123}"
},
"statistics": {
"impact": [
{
"label": "Minimum consecutive offdays",
"value": 0.777778
}
],
"unassignedTaskIDs": [1,2,3],
"unassignableTaskIDs": [2,3,4]
},
"info":{
"text": "text",
"feasible": true
},
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The resulting plan mostly extends the Request by the fields marked "Extension" below:
Extension | Parameter | Required | Type | Description |
---|---|---|---|---|
➞ | requestID | string | A unique id to identify the plan. | |
client | client | Contains information about the client, which sent this request. | ||
meta | meta | Meta-information about what to consider in the optimization. | ||
parameters | parameters | Parameters for the optimization. | ||
tasks | ✔ | Array<Output Task> |
Array of assigned tasks. | |
workers | ✔ | Array<Output Worker> |
Array of available workers. | |
➞ | statistics | ✔ | statistics | Some statistics about the plan. |
➞ | info | ✔ | info | Some textual information about the plan. |
➞ | backendVersion | ✔ | Backend Version | Used validation/ calculation version. |
Error Result
Example
{
"requestID": "id32013",
"error_msg": " |-| ERROR: Task #12 has itself assigned as preceding task. (129) |-| contact email: support@adiutabyte.de",
"version": "1.0.0",
"type": "error",
"errorID": 129,
"taskID": 12,
"backendVersion": {
"schema": "v0.49.9",
"version": "v2.25.12",
"rev": "abcde12"
},
"additionalErrors": [
{
"errorID": 129,
"error_msg": " |-| ERROR: Task #13 has itself assigned as preceding task. (129) |-| contact email: support@adiutabyte.de",
"taskID": 13
}
]
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
If your request contains errors which leads to unsatisfiable plans or an internal error occurred, you will receive a error response instead of a plan.
Parameter | Required | Type | Description |
---|---|---|---|
requestID | string | A unique id to identify the plan request. | |
error_msg | ✔ | string | Contains a textual description of the error. |
version | ✔ | string | Currently always set to "1.0.0". |
type | ✔ | string | Currently always set to "error". |
errorID | ✔ | integer | A unique ID for identifying the error cause. |
taskID | integer | If the error occurred by a specific task, its ID will be referenced. | |
taskExternalID v4.1.0 | string | The externalID corresponding to the taskID (if set). |
|
workerID | integer | If the error occurred by a specific worker, their ID will be referenced. | |
workerExternalID v4.1.0 | string | The externalID corresponding to the workerID (if set). |
|
backendVersion | ✔ | Backend Version | Used validation/ calculation version. |
additionalErrors v3.10.0 | Array<Object> |
During validation, errors do not necessarily terminate the program instantly. Instead they are collected and output in this list (the first validation error being output in the "main section" of the error result, each following in additionalErrors ). This is handy if there are multiple invalid tasks/workers/..., as all of these issues get caught during validation and output here. However, later entries in the additionalErrors list may be less reliable, since they could be based on an earlier failed validation and not be a problem with the input data (e.g. duplicated taskID s might lead to issues with precedingTasks ). |
The objects in additionalErrors
contain the following fields:
Parameter | Required | Type | Description |
---|---|---|---|
error_msg | ✔ | string | All fields exactly like in the "main" description above. |
errorID | ✔ | integer | |
taskID | integer | ||
taskExternalID v4.1.0 | string | ||
workerID | integer | ||
workerExternalID v4.1.0 | string |
The error_msg
gets translated based on language settings.
Type of error | errorID range |
---|---|
Internal errors (bugs). Please contact us so that we can fix the issue. |
|
Input object is missing required data or the given data is invalid for a required element. |
|
Input data fails validation (basic correctness or plausibility). Please check the error_msg for details! |
|
Error-ID
A list of errorID
values and explanations can be found here.
Backend Version
Examples:
{
"schema": "v0.0.0"
}
{
"schema": "v0.0.0",
"version": "v0.0.0",
"rev": "abde12"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
Parameter | Type | Required | Description |
---|---|---|---|
schema | version | ✔ | The json schema version used for validating input and output. |
version | version | The backend version used for calculating the result. | |
rev | string | An internal key for the backed version used for calculating the result. |
Output Task
Examples:
{
... // See Input Task
"timeScheduled": "13:45",
"assignedWorker": 2,
"assignedShift": 1,
"info": "text",
"finalassignedOrder": 1,
"profit": 1.123
}
{
... // See Input Task
"info": "text"
}
production | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) | ||
develop | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) | ||
experimental | v1.7.0 | JSON-Schema (unassigned) |
JSON-Schema (assigned) |
The json schema for the Output Task extends the schema of the Input Task by all the fields marked "Extension" in the table below. If allowUnassignedTasks
was set to true, an "unassigned version" of the output task can be returned which is missing all assignment data.
Extension | Parameter | Required if assigned | Required if unassigned | Type | Description |
---|---|---|---|---|---|
All fields unchanged from Input-Task. | |||||
➞ | timeScheduled | ✔ | string (time) | The planned time to start this task by the assigned worker. | |
➞ | assignedWorker | ✔ | integer | The ID of the assigned worker who will take over this task. | |
➞ | assignedShift | ✔ | integer | v4.0.0 DEPRECATED | |
➞ | info | ✔ | ✔ | string | may contain some information about the worker. |
➞ | finalassignedOrder | ✔ | integer | The order number on the assigned worker starting with number 1 . |
|
➞ | profit | ✔ | number | The profit the task creates ($revenue - costs$). |
Output Worker
Examples:
{
... // Same as Input Worker
}
{
... // See Input Worker
"info": "text"
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The json schema for the Output Worker extends the schema of the Input Worker by all the fields marked "Extension" in the table below:
Extension | Parameter | Required | Type | Description |
---|---|---|---|---|
All fields unchanged from Input-Worker. | ||||
➞ | info | string | Some textual information about the worker. |
Statistics
Examples:
{
"impact": [
{
"label": "Minimum consecutive offdays",
"value": 0.777778
}
],
"timeWindowViolationTaskIDs": [1,2,3],
"unassignedTaskIDs": [1,2,3],
"unassignableTaskIDs": [2,3,4],
"history": {
"workers": [
{
"workerID": 1,
"weeklyShifts": [
{
"weekday": 0,
"shiftStart": "10:00",
"shiftEnd": "14:00",
"workPreferenceFactor": -0.25
}
],
"minConsecutiveWorkdays": 1,
"maxConsecutiveWorkdays": 1,
"minConsecutiveOffdays": 1,
"maxConsecutiveOffdays": 1,
"minFreeSaturdays": 1,
"minFreeSundays": 1,
"minFreeWeekends": 1,
"maxWeeklyWorkingDays": 1,
"maxNightShifts": 1,
"maxConsecutiveSameTaskStart": 1,
"preferenceFactor": 1.5
}
]
}
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The statistics
provide some general data for evaluating the result. They are based on the adjusted data that the optimization is performed on. Differences to the tasks'/workers' input data are noted in their respective info
fields.
Parameter | Type | Required | Description |
---|---|---|---|
impact | Array<Object<label: string, value: number>> |
✔ | Contains all restriction types and gives a percentage (0.0-1.0) evaluation of each restriction's final influence on the algorithmic optimization and plan result. This can be used to detect logical problems in the input data, i.e. too restrictive time windows, an unrealistic amount of free Saturday/ Sunday preferences or a large amount of worker preferences that just cannot be fulfilled. However, please note that when a restriction is listed in impact with a value greater zero, it does not mean that there even is a way to erase its impact. For instance, if costsPerMinute are set, worktime costs will always be featured unless the total amount of working time is zero or the profitability option is set to zero. You can find all possible labels here. |
timeWindowViolationTaskIDs | Array<integer> |
taskIDs of all tasks not assigned within their given time window. |
|
unassignedTaskIDs | Array<integer> |
taskIDs of all tasks that were not assigned during optimization. |
|
unassignableTaskIDs | Array<integer> |
taskIDs of all tasks that were not assigned during optimization because there is no assignment possible (meaning they would fail input validation if unassigned tasks were not allowed). |
|
history v3.4.0 | Object | All data determined from the history. |
The history
entry contains the data from the history analysis:
Parameter | Type | Required | Description |
---|---|---|---|
workers | Array | ✔ | Historical data for each worker. |
Each entry in workers
has the following fields.
Parameter | Type | Required | Description |
---|---|---|---|
workerID | integer | ✔ | Unique id to connect the worker to a worker in the workers array of the request. |
weeklyShifts | Array<WeekdayStatisticsData> |
Data per weekday. | |
minConsecutiveWorkdays | integer | See minConsecutiveWorkdays . |
|
maxConsecutiveWorkdays | integer | See maxConsecutiveWorkdays . |
|
minConsecutiveOffdays | integer | See minConsecutiveOffdays . |
|
maxConsecutiveOffdays | integer | See maxConsecutiveOffdays . |
|
minFreeSaturdays | integer | See minFreeSaturdays . |
|
minFreeSundays | integer | See minFreeSundays . |
|
minFreeWeekends | integer | See minFreeWeekends /minDesiredFreeWeekends . |
|
maxWeeklyWorkingDays | integer | See maxWeeklyWorkingDays /prefWeeklyWorkingDays . |
|
maxNightShifts | integer | See maxNightShifts /maxDesiredNightShifts . |
|
maxConsecutiveSameTaskStart | integer | See maxConsecutiveSameTaskStart /maxDesiredConsecutiveSameTaskStart . |
|
preferenceFactor | number | A factor for the historical fairness towards this worker regarding preferences. Is < 1.0 if the worker's preferences were favored, is > 1.0 if the worker was discriminated against. |
WeekdayStatisticsData
are objects with data for a weekday:
Parameter | Type | Required | Description |
---|---|---|---|
weekday | Weekday | ✔ | The weekday the data corresponds to. |
shiftStart | Time | The time the worker usually started to work. | |
shiftStart | Time | The time the worker usually end their work, | |
workPreferenceFactor | number | The preference towards working on that weekday. Values < 0 mean the worker should not work, values > 0 mean they should. |
Info
Examples:
{
"text": "text",
"feasible": true
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The info
texts provide some textual context to the solution. They are based on the adjusted data that the optimization is performed on. Differences to the tasks'/workers' input data are noted in their respective info
fields.
Parameter | Required | Type | Description |
---|---|---|---|
text | ✔ | string | Some general information about the plan. |
feasible v3.5.0 | ✔ | boolean | Set to false if any strict restrictions are violated in the solution. |
All text in text
gets translated based on language setting.
Additional Validation
Every request must adhere to the defined schemas or it cannot be processed. However, even if it does, there might still be issues with the contained data. For that reason, a content validation is performed after accepting the request, the details of which are listed below.
There are multiple times a validation is performed on the input data. If an issue is found, the corresponding error message will tell you exactly at which step the validation failed:
- Validation of raw input data, excluding data excluded by
resCategory
orresQualification
. - Validation of input data after removing all unassignable tasks (this is only relevant is
allowUnassignedTasks
is set to true). - Validation of history adjusted data (this is only relevant if a
history
is included in the input data) - Validation after adjusting data (if
enablePlanSplitting
is true, the error message will tell you which subset of data had the issue).
If allowUnassignedTasks
is set to true, the first of these validations is allowed to fail some validations (the list below will tell you which). In this case the task is simply removed from calculation. You can determine these unassignable tasks from their info
section in the output or the array unassignableTasks
in statistics
.
List of all content requirements
errorID | allowed to fail | Requirement |
---|---|---|
121 | taskID must be unique among all tasks. |
|
122 | workerID must be unique among all workers. |
|
123 | Task time windows must be large enough that duration fits inside. |
|
124 | ✔ | Task sets which have to be assigned to the same worker must have a worker that is not forbidden for any of them via any strict restriction. |
126 | For certain task chains which have a fixed order (e.g. predecessorTasks chains), if one task in the chain is assigned to a dontVary- or dontAlter-Worker, all of them must be. |
|
127 | Task time windows must be large enough that minTaskDuration fits inside (if set). |
|
1200 | ✔ | Tasks must have a worker that is not forbidden via any strict restriction v3.10.1 and a fitting (time windows overlap) shift on such a worker. Task with an assignment to a dontVary-Worker are exempt. |
1201 removed in v4.0.0 | Tasks must not have themselves as one of their precedingTasks . |
|
1202 removed in v4.0.0 | For each entry in precedingTasks , a task with that taskID must exist. |
|
1203 | Tasks must not have themselves as one of their predecessorTasks . |
|
1204 | shiftEnd must not be before shiftStart |
|
1205 removed in v4.0.0 | If allowUnassignedTasks is false, there must not be more tasks than shifts. |
|
1207 | A worker with a fitting qualification for qualificationCoverage must exist. |
|
1208 | A worker with a fitting entry in categories for each entry in categoryCoverage must exist. |
|
1209 | It is not allowed for multiple task to have exactly one entry in predecessorTasks and have it be the same value. |
|
1210 removed in v4.0.0 | There must not be two tasks with the same group and groupOrder (if both are set). |
|
1211 removed in v4.0.0 | If a groupOrder is set, a group must be set as well. |
|
1212 removed in v4.0.0 | If an initassignedShift is set, a shift with this shiftID must exist. |
|
1213 removed in v4.0.0 | If a task is initassigned to a shift belonging to a dontVary worker, no other task can be initassigned to that shift unless the two of them belong to the same group and they both have a groupOrder . |
|
1214 removed in v4.0.0 | shiftID must be unique among all shifts. |
|
1215 removed in v3.10.1 | ✔ | Tasks must have a fitting (time windows overlap) shift on an allowed worker. |
1216 | Certain task chains which have a fixed order (e.g. tasks with group and groupOrder ) and that are assigned to a dontVary- or dontAlter-Worker must have their chain order reflected their initassignedShift . |
|
1217 | Either none or all of precTaskDate , precTaskScheduled , precTaskDuration must be set. precNightShifts requires all of these three values to be set. |
|
1218 | (Worker/ Shift) shiftStart and shiftEnd must not be earlier than dateFrom at 00:00, shiftDate must not be later than dateTo . (Task) timeEarliest and timeLatest must not be earlier than dateFrom at 00:00, date must not be later than dateTo . |
|
1220 v4.0.0 | If a task has an initassignedWorker , that worker must exist. |
|
1221 v4.0.0 | If a task has an initassignedOrder , it must have an initassignedWorker or preassignedWorker . |
|
1222 v4.0.0 | A task with set preassignedWorker and set initassignedWorker where one of the workers has dontVary set to true, must have the same value in both fields. |
|
1223 v4.0.0 | A task assigned to a dontVary -Worker via preassignedWorker or initassignedWorker must have an initassignedOrder . |
|
1224 v4.0.0 | All tasks assigned to the same dontVary -Worker via preassignedWorker or initassignedWorker must have a different initassignedOrder . |
|
1225 v4.1.2 | If there is exactly one entry in predecessorTasks , a task with that ID must exist. |
|
1502 | workerID s of history workers must be unique among all history workers. |
|
1503 | taskID s of history tasks must be unique among all history tasks. |
|
1504 | No date in excludedDays must be equal or later than dateFrom . |
|
1505 | taskID s of history tasks have to refer to a task among the objects in tasks or the history tasks. |
|
1506 | taskID s must be unique among the additional tasks. |
|
1507 | There must not be two tasks from the additional tasks and planning tasks with the same taskID . |
Examples
The following examples shall provide a starting point to build from when using the API for the first time. If you'd like to see one added, please contact us.
Posting/ Retrieving a plan
The example to the right provides a simple javascript template to post/get a request/response. Authentication details can be found here.
require('cross-fetch/polyfill');
const fetch = require('cross-fetch');
const AmazonCognitoIdentity = require('amazon-cognito-identity-js');
// authentication
const userPool = new AmazonCognitoIdentity.CognitoUserPool({
UserPoolId: "[myUserPoolId]", // see authentication page
ClientId: "[myClientId]" // see authentication page
});
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
Username: "[myUserName]", // see login details of your adiutaByte account
Password: "[myPassword]"
});
const cognitoUser = new AmazonCognitoIdentity.CognitoUser({
Username: "[myUserName]", // see login details of your adiutaByte account
Pool: userPool
});
const token = await new Promise((resolve, reject) => cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
const thisToken = result.getIdToken().getJwtToken();
resolve(thisToken);
},
onFailure: function (err) {
console.log(err);
reject();
}
}));
// posting a request
const headers = {
'Content-Type': 'application/json',
'Authorization': token
};
const request = {
meta: {
dateFrom: "2019-12-03",
dateTo: "2019-12-03"
},
parameters: {},
tasks: [
{
date: "2019-12-03",
duration: 65,
taskID: 200,
timeEarliest: "10:00",
timeLatest: "12:00"
}
],
workers: [
{
workerID: 1,
shifts: [
{
shiftID: 1,
shiftStart: "03:00",
shiftEnd: "12:00",
shiftDate: "2019-12-03"
}
]
}
]
};
const postOptions = {
method: 'post',
headers: new Headers(headers),
body: JSON.stringify(request)
};
const postURL = `https://[env].compute-adiutabyte.de/shift-description`; // see endpoint section
const ID = await new Promise((resolve, reject) => fetch(postURL, postOptions)
.then(async res => {
if (res.ok) {
const data = await res.json();
console.log("Successfully posted request! ID:", data);
resolve(data);
}
else {
console.error("Error while posting request:", res.status);
reject();
}
}));
// get solution
let status = 423;
while (status === 423) {
const getURL = `https://[env].compute-adiutabyte.de/plan/${ID}`; // see endpoint section
const getOptions = {
method: 'get',
headers: new Headers(headers)
};
const solution = await new Promise((resolve, reject) => fetch(getURL, getOptions)
.then(async res => {
status = res.status;
resolve(res);
}));
if (status === 200) {
const solutionText = await solution.text();
console.log("Solution:", JSON.parse(solutionText));
break;
}
else if (status !== 423) {
console.error("Error while getting solution:", status);
break;
}
await new Promise(resolve => setTimeout(resolve, 5000));
}
Common plan for scheduling
The following json template can be used as a starting point when creating plans for any time span.
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Locked Workers
If only a subset and tasks and workers shall be optimized, it usually suffices to not include theses in your request. However, if those already calculated workers shall be included in info
/statistics
, there is a way to "lock" these workers for the algorithm (a common use case is re-optimizing a subsection of workers/tasks from a previous request - either to improve the solution or because changes have been made).
All locked workers that shall not receive additional tasks, the flag dontVary
needs to be set to true. Any task that is already assigned to this worker needs to have its initassignedWorker
or preassignedWorker
set to the worker this task is supposed to be assigned to. Additionally it needs to be set at which position in the worker's tour the task should be positioned (initassignedOrder
). The request then looks like this:
production | v1.7.0 | Input-File |
develop | v1.7.0 | Input-File |
experimental | v1.7.0 | Input-File |
Common data types
Integers/Numbers
Examples:
{
"integer_u32": 12,
"integer_s32": -12,
"number_u32" : 7.184535,
"number_s32" : -7.184535,
"number_u64" : 7.184535,
"number_s64" : -7.184535,
"fraction" : 0.2
}
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
The following ranges get used for values of type integer/ number:
ID | Name | Range |
---|---|---|
integer_u32 | integer | $0 \leq x \leq 2147483647$ |
integer_s32 | integer | $-2147483648 \leq x \leq 2147483647$ |
number_u32 | number | $0 \leq x \leq 3.4e+38$ |
number_s32 | number | $-3.4e+38 \leq x \leq 3.4e+38$ |
number_u64 | number | $0 \leq x \leq 1.7e+308$ |
number_s64 | number | $-1.7e+308 \leq x \leq 1.7e+308$ |
fraction | number | $0 \leq x \leq 1$ |
Please refer to the respective linked json schema to determine which type of integer/number gets used.
Date
Examples:
"2018-01-10"
"2019-12-03"
"2020-05-23"
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A string consisting of three parts following the pattern "YYYY-MM-DD"
:
"YYYY"
: year AD, $ 2010 \leq x \leq 2099 $"MM"
: month, $ 1 \leq x \leq 12 $"DD"
: day, $ 1 \leq x \leq 31 $
Time
Examples:
"06:59"
"15:59"
"1230:33"
"-39:12"
"03:01"
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
A string of either format "hh:mm"
or "-hh:mm"
:
"hh"
: hours, $ 0 \leq x \leq 10^{10} -1 $"mm"
: minutes, $ 0 \leq x \leq 59 $ with exactly 2 digits
All times are interpreted in 24-hour notation and relative to midnight ("00:00"
) of a certain defined date. Those dates are:
shiftDate
for any Time values in Shiftdate
for any Time values in Input Task and Output Task.
This means that the following times applied to the respective date (in Date format) are equivalent:
"2021-05-21"
at"07:25"
"2021-05-20"
at"31:25"
"2021-05-19"
at"55:25"
"2021-05-22"
at"-16:35"
"2021-05-23"
at"-40:35"
Input data containing only identical dates and no time of format "-hh:mm"
will not result in output data containing times of format "-hh:mm"
.
GenderType
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 3$.
GenderTypeID | Description |
---|---|
0 | Not provided |
1 | Male |
2 | Female |
3 | Other |
LanguageType
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 1$.
LanguageTypeID | Description |
---|---|
0 | German |
1 | English |
Weekday
Introduced in: v3.4.0
production | v1.7.0 | JSON-Schema |
develop | v1.7.0 | JSON-Schema |
experimental | v1.7.0 | JSON-Schema |
An integer in the range $0 \leq x \leq 6$.
value | Description |
---|---|
0 | Sunday |
1 | Monday |
2 | Tuesday |
3 | Wednesday |
4 | Thursday |
5 | Friday |
6 | Saturday |
Conventions
- All number values of times (task durations, working time limits, ...) use the unit minutes.
- Days start at 00:00 and end at 23:59.
- Tasks always count towards the date they are assigned on. For example, a task assigned Fri 23:00 - Sat 02:00 will only count towards Friday for all relevant counters:
maxDailyWorkingMinutes
,minFreeWeekends
, ...
Deployment Status
ShiftPlanner Version | API Schema Validation Version | |
---|---|---|
production | v4.2.4 | v1.7.0 |
develop | v4.2.4 | v1.7.0 |
experimental | v4.2.4 | v1.7.0 |
Getting the deployed version
Introduced in: v3.9.0
Aside from checking this page, you can also get the deployed versions via a GET request.
HTTP-Endpoint
DEVEL | GET https://develop.compute-adiutabyte.de/shift-version |
PROD | GET https://production.compute-adiutabyte.de/shift-version |
Result
{
"version": "v3.9.15",
"schema": "v0.78.0",
"meta-data": "v15",
"api-scripts": "v1.5.0"
}
Parameter | Type | Description |
---|---|---|
version | version | The backend version used for calculating results. |
schema | version | The json schema version used for validating input and output. |
meta_data | version | The meta data version used to determine client specific behavior. |
api_scripts | version | The api script version. |
Status-Codes
Number | Code | Description |
---|---|---|
200 | OK | The version data will be delivered. |
500 | INTERNAL SERVER ERROR | An error occurred in the backend. Please contact us to check why this has happened. |
Deprecation Warnings
v4.0.0
- In Input Task: Removed
precedingTasks
. - In Input Task: Removed
groupOrder
. - In Input Task: Removed
initassignedShift
. - In Input Worker: Changed the requirements of
dontVary
, frominitassignedShift
to a combination ofinitassignedWorker
andinitassignedOrder
. - In Shift: Removed
shiftID
. - In Output Task: Removed
assignedShift
.
Changelog
2024-01-23
- In Error Result: Added
workerExternalID
with tagv4.1.0
. - In Error Result: Added
taskExternalID
with tagv4.1.0
.
2024-01-07
- Added section Checking your requests for validity.
2023-12-03
- Added deprecation warnings for
v4.0.0
. - Added section Deprecation Warnings.
- In Input Task: Deprecated
precedingTasks
with tagv4.0.0
. - In Input Task: Deprecated
groupOrder
with tagv4.0.0
. - In Input Task: Deprecated
initassignedShift
with tagv4.0.0
. - In Input Task: Added
initassignedWorker
with tagv4.0.0
. - In Input Task: Added
initassignedOrder
with tagv4.0.0
. - In Input Worker: Updated description for
dontVary
. - In Shift: Deprecated
shiftID
with tagv4.0.0
. - In Output Task: Deprecated
assignedShift
with tagv4.0.0
. - In Additional Validation: Added validations 1220-1224 with tag
v4.0.0
, marked validations 1201, 1202, 1205, 1210 - 1214 as removed with tagv4.0.0
. - In Examples: Updated examples to work with
v4.0.0
.
2023-11-23
- In Additional Validation: Marked validation 1215 as being removed in
v3.10.1
. - In Additional Validation: Updated validation 1200 with tag
v3.10.1
.
2023-11-11
- In Error Result: Added
additionalErrors
with tagv3.10.0
.
2023-10-18
- In Additional Validation: Added validations 1502-1507.
2023-10-16
- Added Additional Validation.
2023-09-12
- In Meta Information: Added
minTaskDuration
with tagv3.10.0
.
2023-08-29
- In Input Worker: Added
carryoverConsecutiveWorkingWeekends
with tagv3.9.0
. - In Examples: Added Posting/Retrieving a plan.
- Some minor restructuring.
2023-08-13
- In Input Worker: Added
minConsecutiveWorkingWeekends
with tagv3.9.0
. - In Input Worker: Added
minDesiredConsecutiveWorkingWeekends
with tagv3.9.0
. - In Input Worker: Added
maxConsecutiveWorkingWeekends
with tagv3.9.0
. - In Input Worker: Added
maxDesiredConsecutiveWorkingWeekends
with tagv3.9.0
. - In Output Worker: Added
minConsecutiveWorkingWeekends
with tagv3.9.0
. - In Output Worker: Added
minDesiredConsecutiveWorkingWeekends
with tagv3.9.0
. - In Output Worker: Added
maxConsecutiveWorkingWeekends
with tagv3.9.0
. - In Output Worker: Added
maxDesiredConsecutiveWorkingWeekends
with tagv3.9.0
.
2023-08-09
- In Deployment Status: Added
Getting the deployed version
with tagv3.9.0
. - In Input Worker: Added
minConsecutiveFreeWeekends
with tagv3.9.0
. - In Input Worker: Added
minDesiredConsecutiveFreeWeekends
with tagv3.9.0
. - In Input Worker: Added
maxConsecutiveFreeWeekends
with tagv3.9.0
. - In Input Worker: Added
maxDesiredConsecutiveFreeWeekends
with tagv3.9.0
. - In Input Worker: Added
precWeekendWorkingDay
with tagv3.9.0
. - In Output Worker: Added
minConsecutiveFreeWeekends
with tagv3.9.0
. - In Output Worker: Added
minDesiredConsecutiveFreeWeekends
with tagv3.9.0
. - In Output Worker: Added
maxConsecutiveFreeWeekends
with tagv3.9.0
. - In Output Worker: Added
maxDesiredConsecutiveFreeWeekends
with tagv3.9.0
. - In Output Worker: Added
precWeekendWorkingDay
with tagv3.9.0
.
2023-08-02
2023-07-05
- In Input Worker: Changed description of field
minBreakMinutesBetweenTasks
with tagv3.8.35
. - In Statistics: Fixed
shiftStart
,shiftEnd
(inhistory
->weeklyShifts
) being marked "required".
2023-05-25
2023-05-12
- Added Examples.
- In Error Result: Added section "Error-ID".
2023-05-08
- In Optimization Types: Renamed
Unassigned Task
toInput Task
. - In Optimization Types: Renamed
Assigned Task
toOutput Task
. - In Optimization Types: Renamed
Unassigned Worker
toInput Worker
. - In Optimization Types: Renamed
Assigned Worker
toOutput Worker
.
2023-05-03
- In Error Result: Updated error code ranges with tag
v3.8.21
.
2023-04-22
- Added Deployment Status.
2023-04-14
- In Optimization Parameters: Added preset
Random
(value: 0) with tagv3.8.16
.
2023-04-03
- In Conventions: Added convention.
- In Unassigned Task: Fixed description of
timePriority
. - In Meta Information: Changed description of
minQualificationOfTaskCoverage
with tagv3.8.12
. - In Meta Information: Changed description of
omnipresentCategoriesOfTaskCoverage
with tagv3.8.12
.
2023-03-30
- In Meta Information: Changed
resQualification
to optional with tagv2.37.0
. - In Meta Information: Changed
resCategories
to optional with tagv2.37.0
.- Both these field have been optional since
v2.37.0
. However, this change was not documented in the API description at the time.
- Both these field have been optional since
2023-03-24
- In Unassigned Task: Added
maxQualification
with tagv3.8.0
. - In Assigned Task: Added
maxQualification
with tagv3.8.0
.
2023-03-14
- Created standalone ShiftPlanner documentation.
2023-03-13
- Moved Shift to Optimization Types.
- In Unassigned Task: Changed description of
preassignedWorker
with tagv3.6.1
. - In Unassigned Worker: Changed description of
maxConsecutiveSameTaskStart
with tagv3.5.1
. - In Unassigned Worker: Changed description of
maxDesiredConsecutiveSameTaskStart
with tagv3.5.1
.