Employee Utilization Constraint
This constraint can be used to specify targets for the amount of work done by employees, either in FTE hours or in number of shifts. Specifically, it can be used to:
- Set a lower bound on the amount of hours worked by employees in some period.
- Set an ideal target for the amount of hours worked by employees in some period.
- Set a strict upper bound on the amount of hours/shifts worked by employees in some period.
minHours
and idealHours
are treated as targets - the solver will try to assign exactly idealHours
, and will try even harder to assign at least minHours
. maxHours
is treated as a strict upper bound - the solver will never exceed this value.
The minShifts
, idealShifts
, and maxShifts
targets work in the same way.
Employee Utilization Constraint in the request payload
id required | string (constraintId) The id of the constraint should be UNIQUE in the context of constraint type. |
weight | integer (constraintWeightPositive) [ 0 .. 100 ] Describes how much the constraint is taken into account when solving the schedule. The higher the value, the more solver will penalize the constraint violation. None of the weight values make it a hard constraint - even when weight is set to 100 it is not guaranteed that the constraint will be satisfied. The weight value is relative to other constraints. |
object (constraintFairness) Describes how much fairness is taken into account for the constraint. | |
object (employeeUtilizationFilters) | |
object Specifies the target utilization for the constraint. Targets can be specified in number of FTE hours, or in number of shifts worked during the period. | |
object Settings to determine if and how bonus time rules affect the constraint. | |
object Settings to determine if and how default time rules affect the constraint. | |
object (overlapRules) Specify when a scheduled shift should count towards the targets of this constraint. If both minOverlapHours and minOverlapPercentage are specified, shifts will be counted if they satisfy either requirement. If the overlapRules object is not defined, shifts are counted if they have any overlap with the constraint. | |
object (periods) = 1 properties The periods in which the constraint should be applied. The minHours and maxHours will be applied to each period separately. | |
object (scheduleDays) non-empty Deprecated DEPRECATED - Use periods instead. | |
minHours | integer Deprecated DEPRECATED - Use targets instead. |
maxHours | integer Deprecated DEPRECATED - Use targets instead. |
minShifts | integer Deprecated DEPRECATED - Use targets instead. |
maxShifts | integer Deprecated DEPRECATED - Use targets instead. |
employeeIds | Array of strings (constraintEmployeeIds) unique Deprecated DEPRECATED - Use filters instead. |
shiftIds | Array of strings (constraintShiftIds) unique Deprecated DEPRECATED - Use filters instead. |
roleIds | Array of strings unique Deprecated DEPRECATED - Use filters instead. |
{- "id": "string",
- "weight": {
- "example_1": {
- "value": 0,
- "summary": "The constraint is not taken into account when solving the schedule as it has weight 0."
}, - "example_2": {
- "value": 100,
- "summary": "Solver will try its best to satisfy the constraint as it has weight 100."
}
}, - "fairness": {
- "fairnessWeight": {
- "example_1": {
- "value": 0,
- "summary": "The fairness is not taken into account when solving the schedule."
}, - "example_2": {
- "value": 100,
- "summary": "Solver will try its best to make the constraint as fair as possible."
}
}, - "fteAdjustedFairness": false
}, - "filters": {
- "employeeIds": {
- "example_ints": {
- "value": [
- 1,
- 5,
- 3
], - "summary": "The constraint will be applied only to employees with id 1, 5 and 3."
}, - "example_all_employees": {
- "value": [ ],
- "summary": "The constraint will be applied to all defined employees."
}, - "example_string": {
- "value": [
- "Lars Petersen",
- "123qwerty"
], - "summary": "The constraint will be applied to listed employees."
}
}, - "roleIds": [
- "string"
], - "shiftIds": {
- "example_1": {
- "value": [
- "shift_1",
- "shift_2"
], - "summary": "The constraint will be applied only to shifts with id \"shift_1\" or \"shift_2\"."
}, - "example_2": {
- "value": [ ],
- "summary": "The constraint will be applied to all defined shifts."
}
}, - "shiftTypeIds": {
- "example_ids": {
- "value": [
- "shift_type_1",
- "shift_type_2"
], - "summary": "The constraint will be applied only to shift types with id \"shift_type_1\" and \"shift_type_2\"."
}, - "example_all_shift_types": {
- "value": [ ],
- "summary": "The constraint will be applied to all defined shift types."
}
}, - "workTypeIds": {
- "example_1": {
- "value": [
- 0,
- 3
], - "summary": "The constraint will be applied only to work type with id 0 and 3."
}, - "example_2": {
- "value": [ ],
- "summary": "The constraint will be applied to all defined work types."
}
}
}, - "targets": {
- "minHours": 0,
- "idealHours": 0,
- "maxHours": 0,
- "minShifts": 0,
- "idealShifts": 0,
- "maxShifts": 0
}, - "bonusTime": {
- "includeBonusHours": true,
- "averageHoursThreshold": 0,
- "averageHoursCap": 0
}, - "defaultTime": {
- "includeDefaultHours": true,
- "minOverlapHours": 0
}, - "overlapRules": {
- "minOverlapHours": 1,
- "minOverlapPercentage": 1
}, - "periods": {
- "days": {
- "dates": [
- {
- "example_1": {
- "value": "2023-12-24",
- "summary": "The 24th of December 2023."
}
}
]
}
}, - "scheduleDays": {
- "weekDays": {
- "example_1": {
- "value": [
- 1
], - "summary": "All Mondays in the planning horizon."
}
}, - "dayIndexes": {
- "example_1": {
- "value": [
- 0,
- 1,
- 2,
- 3
], - "summary": "First four days of the planning horizon."
}
}, - "dates": {
- "example_1": {
- "value": [
- "2023-12-24",
- "2023-12-25"
], - "summary": "The 24th and 25th of December 2023."
}
}
}, - "minHours": 0,
- "maxHours": 0,
- "minShifts": 0,
- "maxShifts": 0,
- "employeeIds": {
- "example_ints": {
- "value": [
- 1,
- 5,
- 3
], - "summary": "The constraint will be applied only to employees with id 1, 5 and 3."
}, - "example_all_employees": {
- "value": [ ],
- "summary": "The constraint will be applied to all defined employees."
}, - "example_string": {
- "value": [
- "Lars Petersen",
- "123qwerty"
], - "summary": "The constraint will be applied to listed employees."
}
}, - "shiftIds": {
- "example_1": {
- "value": [
- "shift_1",
- "shift_2"
], - "summary": "The constraint will be applied only to shifts with id \"shift_1\" or \"shift_2\"."
}, - "example_2": {
- "value": [ ],
- "summary": "The constraint will be applied to all defined shifts."
}
}, - "roleIds": [
- "string"
]
}
Setting global utilization targets
A simple use case for this constraint is to limit the total amount of FTE hours an employee should receive in the entire planning horizon. Note that none of the targets are required - you can specify only the ones that are relevant to your use case.
The constraint specified below will have the following effects for employee-1
:
- The employee is preferred to work at least 80 hours in the entire planning horizon.
- The employee should ideally work exactly 120 hours in the entire planning horizon.
- The employee may work no more than 160 hours in the entire planning horizon.
{
"id": "euc-1",
"targets": {
"minHours": 80,
"idealHours": 120,
"maxHours": 160
},
"filters": {
"employeeIds": ["employee-1"]
}
}
Setting weekly utilization targets
All targets on the Employee Utilization Constraint are applied to each period separately. Using a recurrent period definition is therefore an easy way of creating a weekly utilization constraint.
The constraint specified below sets a strict upper bound (2) on the number of night shifts an employee can work per week.
{
"id": "euc-1",
"filters": {
"shiftTypeIds": ["night"]
},
"targets": {
"maxShifts": 2
},
"periods": {
"recurrentDefinition": {
"daysPerPeriod": 7
}
}
}