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) Unique identifier for the constraint. |
importance | string (importance) Enum: "NONE" "VERY_LOW" "LOW" "MEDIUM" "HIGH" "VERY_HIGH" The importance of the constraint. The higher the importance, the more the solver will take the constraint into account. |
object (employeeUtilizationFilters) Filters to determine the scope of the constraint. Used to decide which employees and which shifts the constraint should be applied to. Filters use logical OR filtering - an employee or shift is included as long as it is targeted by any of the filters. | |
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. | |
weight | integer (constraintWeightPositive) [ 0 .. 100 ] Deprecated DEPRECATED - Use importance instead. |
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. |
object (constraintFairness) Deprecated DEPRECATED - Use FairnessConstraints instead. |
{- "id": "string",
- "importance": "NONE",
- "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."
}
}
]
}
}, - "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."
}
}, - "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"
], - "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
}
}
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
}
}
}