Employee Shift Scheduling User Guide

1. Terms

Term Description

Employee

Employee that can be assigned to a shift.

Contract

Employee contract that defines settings specific to a group of employees (e.g. maximum number of minutes worked per month).

Shift

Unit of work that has to be covered by an employee. Each shift has a start and end time and can have various requirements (e.g. skills required).

Global rules configuration

Configuration of global rules that apply to all employees and shifts (e.g. fairness configuration).

2. Architecture

Under the hood, the application includes Timefold Enterprise Solver - scalable optimization engine that can solve complex constraint satisfaction problems.

Employee Shift Scheduling model has been formulated using Timefold Solver SDK.

REST API layer is defined on top of the model and serves as a communication point with the engine. It provides a stable interface that allows to manage lifecycle of the optimization problem, from submitting it to retrieving the final solution.

2.1. Typical user workflow

2.1.1. Create problem dataset

Create problem dataset using predefined model schema that follows OpenAPI specification. The application provides several out-of-the-box examples that can be used as a starting point.

Example 1. List sample datasets REST API endpoint call

GET /v1/demo-data

Example 2. Get sample dataset REST API endpoint call

GET /v1/demo-data/{dataset_name}

2.1.2. Submit dataset

Submit the unsolved dataset using the REST API. The application validates the input and returns a unique identifier of the problem. The solving process is scheduled and eventually starts.

Example 3. Submit problem dataset REST API endpoint call

POST /v1/schedules

2.1.3. Get current best solution and check status

Check the current best solution and receive information about the solving process. The solution contains optimized employee shift schedule. Use id attribute returned by submit dataset step.

Example 4. Check status REST API endpoint call

GET /v1/schedules/{id}

2.1.4. Terminate solving

Terminate the solving process and receive the current best solution. Use id attribute returned by submit dataset step.

Example 5. Terminate solving REST API endpoint call

DELETE /v1/schedules/{id}

2.1.5. Get all solving processes

Get info about the status of all solving processes.

Example 6. Terminate solving REST API endpoint call

GET /v1/schedules

3. Input structure

Input payload consists of a model input representing a schedule and a configuration

3.1. Configuration

3.1.1. Run configuration

The run configuration is shared across all models. Below is an example of a run configuration.

"config": {
  "run": {
    "name": "run name",
    "termination": {
      "spentLimit": "PT5M",
      "unimprovedSpentLimit": "PT10S"
    },
    "maxThreadCount": "1",
    "tags": []
  },
  "model": {
    "overrides": {
      <model-specific configurations>
    }
  }
}

A run configuration has two fields: the run and the model.

The run has four fields:

  • name - The run name (if empty, it will be generated).

  • termination - The termination properties, which contains the maximum duration to keep the solver running (spentLimit) and the maximum unimproved score duration (unimprovedSpentLimit) (if the score has not improved during this period, the solver will terminate). If null, no maximum duration or maximum unimproved score duration will be set.

  • maxThreadCount - The maximum thread count, which indicates the maximum number of threads to be used for solving. If not provided, 1 will be used.

  • tags - The tags, which are a set of optional tags to be assigned to the job.

The model is a model-specific field, that contains additional global model configuration attributes.

3.2. Concepts

3.2.1. Employee contract period rule

Employee contract can define multiple rules that are assessed over either a built-in or a custom period.

The period rule can optionally define a ruleValidityDateTimeSpan to limit the rule to a specific time span. The validity date time span uses the employee’s zone offset to determine the start and end time of the rule. To learn more about time zones and daylight saving time, see Timezones and Daylight Saving Time (DST).

The following example shows a rule that requires an employee to work no more than 6 hours a day, but only during December 2024:

{
  "period" : "DAY",
  "minutesWorkedMax" : 360,
  "ruleValidityDateTimeSpan": {
    "start": "2024-12-01T00:00:00",
    "end": "2025-01-31T00:00:00"
  }
}

3.2.2. Model configuration

Provides an optional configuration of the model, for example specifying the weight of constraints.

3.2.2.1. Constraint weight overrides

Every constraint has a default weight of 1, meaning that all constraints are equally important. Use this to express preference of some constraints over others. For example, in order to express that the employee pairing constraint is more important than the rest of the constraints, set the value of the employeeIsPairedWithPreferredEmployeeWeight attribute to 10. In order to turn off a constraint, set the value of the corresponding attribute to 0.

"config": {
  "overrides": {
     "employeeIsPairedWithPreferredEmployeeWeight": 10,
     "employeeWorksDuringPreferredTimeWeight": 0
  }
}

3.3. Model input

Contains the schedule to be solved. This includes employees, shifts and other data.

3.3.1. Employee

Employee that can be assigned to a shift.

Id Required Format Description Example

Id

true

string

Unique string identifier of the employee.

"id": "Elsa Green"

Contracts

false

array

Identifiers of employee contracts.

"contracts": [ "Default Contract" ]

Priority

false

integer

Employee priority. Employee preferences are more likely to be satisfied for employees with higher priority.

"priority": "NORMAL"

Cost group

false

string

Cost group of the employee. In conjunction with the cost group of the shift, it is used to calculate the cost of the shift assignment.

"costGroup": "Senior 1"

Location

false

array

Location of the employee.

"location": [51.0441461, 3.7336349]

Skills

false

array

List of employee skills, optionally including date time spans when a particular skill is valid. They are checked against the required and preferred skills of a shift.

"skills": [ { "id": "LCSW cert", "validityDateTimeSpans": [ { "start": "2023-12-11T00:00:00Z", "end": "2024-01-11T00:00:00Z" } ] } ]

Tags

false

array

List of employee tags. They provide additional information that can be used to filter out specific employees (e.g. in balance shifts constraints).

"tags": [ "Part time" ]

Preferred shift tags

false

array

List of preferred shift tags. They express a preference to assign the employee to a shift with given tags. The tags and their types need to be configured as documented in Tags and tag types.

"preferredShiftTags": [ "Department A", "Team X" ]

Required shift tags

false

array

List of required shift tags. They express a requirement to assign the employee to a shift with given tags. The tags and their types need to be configured as documented in Tags and tag types.

"requiredShiftTags": [ "Department A" ]

Prohibited risk factors

false

array

List of prohibited risk factors. Employees cannot be assigned to a shift that has any of their prohibited risk factors (e.g. selected employees cannot be exposed to COVID-19 shift).

"prohibitedRiskFactors": [ "COVID-19" ]

Preferred pairings

false

array

List of preferred employee pairings. Use to express preference of employees to work together at the same time, optionally only for shifts with specific tags.

"preferredPairings": [ { "pairedEmployee": "Elsa Li", "onlyForShiftTags": [ "afternoon" ] } ]

Unpreferred pairings

false

array

List of unpreferred employee pairings. Use to express non-preference of employees to work together at the same time, optionally only for shifts with specific tags.

"unpreferredPairings": [ { "pairedEmployee": "Elsa Li", "onlyForShiftTags": [ "afternoon" ] } ]

Required pairings

false

array

List of required employee pairings. Use to express requirement of employees to work together at the same time, optionally only for shifts with specific tags.

"requiredPairings": [ { "pairedEmployee": "Elsa Li", "onlyForShiftTags": [ "afternoon" ] } ]

Prohibited pairings

false

array

List of prohibited employee pairings. Use to prevent employees from working together at the same time, optionally only for shifts with specific tags.

"prohibitedPairings": [ { "pairedEmployee": "Elsa Li", "onlyForShiftTags": [ "afternoon" ] } ]

Preferred time spans

false

array

List of preferred time spans. Use to express time spans where employee prefers to work, optionally only for shifts with specific tags.

"preferredTimeSpans": [ { "start": "2023-11-08T00:00:00Z", "end": "2023-11-09T00:00:00Z", "includeShiftTags": [ "Location London" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" } ]

Unpreferred time spans

false

array

List of unpreferred time spans. Use to express time spans where employee does not prefer to work, optionally only for shifts with specific tags.

"unpreferredTimeSpans": [ { "start": "2023-11-08T00:00:00Z", "end": "2023-11-09T00:00:00Z", "includeShiftTags": [ "Location London" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" } ]

Unavailable time spans

false

array

List of unavailable time spans. Use to express time spans where employee cannot work (e.g. time off), optionally only for shifts with specific tags.

"unavailableTimeSpans": [ { "start": "2023-11-08T00:00:00Z", "end": "2023-11-09T00:00:00Z", "includeShiftTags": [ "Location London" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" } ]

Available time spans

false

array

List of available time spans. Use to express time spans the employee is available to work, optionally only for shifts with specific tags.

"availableTimeSpans": [ { "start": "2023-11-08T00:00:00Z", "end": "2023-11-09T00:00:00Z", "includeShiftTags": [ "Location London" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" } ]

Time zone offset

false

array

The employee time zone offset to UTC.

Taken into account by employee period rules, see Timezones and Daylight Saving Time (DST).

The default value is "Z" for UTC+0.

"availableTimeSpans": [ { "start": "2023-11-08T00:00:00Z", "end": "2023-11-09T00:00:00Z", "includeShiftTags": [ "Location London" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" } ]

3.3.2. Employee contract

Employee contract that defines settings specific to a group of employees (e.g. maximum number of minutes worked per month).

Id Required Format Description Example

Id

true

string

Unique string identifier of the contract.

"id": "Default Contract"

Consecutive days worked rules

false

array

Rules for minimum, or maximum consecutive days worked. Use this to control how many days in a row an employee with this contract are minimally (or maximally) required (or preferred) to work. The rule can optionally define a shiftTypeTagCategories attribute to work with sequences of shifts having the same tag, for example "morning" and "night". The shift must always have at most one tag defined by the shiftTypeTagCategories attribute, meaning that the shift cannot have both "morning" and "night" tags.

"consecutiveDaysWorkedRules": [ { "id": "min3Max5ConsecutiveICUDays" "minimum": 3, "maximum": 5, "satisfiability": "REQUIRED", "includeShiftTags": [ "ICU" ] "excludeShiftTags": null, "shiftTagMatches": "ALL", "shiftTypeTagCategories": null } ]

Period rules

false

array

Rules tied to a period (e.g. DAY, WEEK, MONTH, SCHEDULE). Use this to express preference / requirement of employees to work a certain number of minutes / shifts / shift types / days in a period, optionally only for shifts with specific tags. The rule can optionally define a shiftTypeTagCategories attribute to work with groups of shifts having the same tag, for example "morning" and "night". The shift must always have at most one tag defined by the shiftTypeTagCategories attribute, meaning that the shift cannot have both "morning" and "night" tags. Use this to express minimum, or maximum unique shift types that an employee works in a period, for example a preference to work only "morning" shifts. The period rule can optionally define a ruleValidityDateTimeSpan to limit the rule to a specific time span. To learn more about period rule validity, please see the Employee contract period rule.

"periodRules": [ { "id": "max480ICUMinutesPerDay", "period": "DAY", "satisfiability": "REQUIRED", "includeShiftTags": [ "ICU" ] "excludeShiftTags": null, "shiftTagMatches": "ALL", "minutesWorkedMin": null, "minutesWorkedMax": 480, "shiftsWorkedMin": null, "shiftsWorkedMax": null, "daysWorkedMin": null, "daysWorkedMax": null, "shiftTypesTagCategories": null, "shiftTypesWorkedMin": null, "shiftTypesWorkedMax": null, "locationsWorkedMax": null }

Avoid shift close to day off request rules

false

array

Rules tied to shifts near a day off. Use this to express preference / requirement of employees to avoid certain shifts before / after a day off, optionally only for shifts with specific tags.

"avoidShiftCloseToDayOffRequestRules": [ { "id": "noNightAndMorningShiftsNearDayOff", "prohibitedPriorShiftTags": [ "NIGHT" ], "prohibitedAfterShiftTags": [ "MORNING", "DEPARTMENT_A" ], "shiftTagMatches": "ANY", "satisfiability": "REQUIRED" } ]

Minutes between shifts rules

false

array

Settings for the minimum, or maximum minutes between shifts. Use this to control how much time off an employee is required/preferred to have between consecutive shifts, optionally only for shifts with specific tags. The rule can optionally define a minimumConsecutivePriorShifts attribute to work with a daily sequence of prior shifts. Use this to express minimum or maximum minutes between a sequence of shifts and another shift, for example a need to take 48 hours off after a sequence of "night" shifts. The current implementation supports values 1 (default), or 2 for minimumConsecutivePriorShifts attribute.

"minutesBetweenShiftsRules": [ { "id": "min600MinutesBetweenNightAndICUShift", "requiredPriorShiftTags": [ "NIGHT" ], "requiredAfterShiftTags": [ "ICU" ], "minimumConsecutivePriorShifts": 1, "shiftTagMatches": "ANY", "satisfiability": "REQUIRED", "minimumMinutesBetweenShifts": 600, "maximumMinutesBetweenShifts": null } ]

Minimize gaps between shifts rules

false

array

Settings for minimizing the gaps between shifts. Use this to prefer assigning employees to shifts that are close to each other, optionally only for shifts with specific tags.

"minimizeGapsBetweenShiftsRules": [ { "id": "minimizeGapsBetweenShiftsRule", "requiredPriorShiftTags": [ "split-shift" ], "requiredAfterShiftTags": [ "split-shift" ], "shiftTagMatches": "ANY", "maximumMinutesBetweenSplitShifts": 120 } ]

Daily shift pairing rules

false

array

Settings for shifts that require pairing with another shift on the same or a different day. Use this to control what shifts are required/preferred to be paired for the employee, optionally only for shifts with specific tags.

"dailyShiftPairingRules": [ { "id": "noAfternoonShiftWithMorningShiftNextDay", "shiftTags": [ "AFTERNOON", ], "pairedShiftTags": [ "MORNING" ], "dayOffset": 1, "shiftTagMatches": "ANY", "satisfiability": "PROHIBITED" } ]

Single day shift sequence pattern rules

false

array

Settings for shift sequence patterns that span across a single day. Use this to specify a sequence of shifts that should, or should not follow each other on the same day, optionally only for shifts with specific tags.

"singleDayShiftSequencePatternRules": [ { "id": "earlyShiftFollowedByLateShift", "satisfiability": "REQUIRED", "pattern": [ { "includeShiftTags": [ "Early" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" }, { "includeShiftTags": [ "Late" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" } ] } ]

Multi day shift sequence pattern rules

false

array

Settings for shift sequence patterns that span across multiple days. Use this to specify chain of shifts that should, or should not follow each other on consecutive days, optionally only for shifts with specific tags. You can configure two types of patterns using type attribute: ON and OFF. ON pattern requires that employee works on the specified day, while OFF pattern requires that employee does not work on the specified day. In case there are multiple shifts on a single day, you can configure the pattern to match all the shifts, or any of the shifts using shiftMatches attribute.

"multiDayShiftSequencePatternRules": [ { "id": "earlyOffLateOffPattern", "satisfiability": "REQUIRED", "pattern": [ { "type": "ON", "includeShiftTags": [ "Early" ], "excludeShiftTags": null, "shiftTagMatches": "ALL", "shiftMatches": "ALL" }, { "type": "OFF", }, { "type": "ON", "includeShiftTags": [ "Late" ], "excludeShiftTags": null, "shiftTagMatches": "ALL" }, { "type": "OFF" } ] } ]

Allow overlapping shifts rules

false

array

Rules tied to shift overlap. Use this to allow employees to work overlapping shifts with specified tags.

"allowOverlappingShiftsRules": [ { "id": "allowOverlapWithOnCallShift", "includeShiftTags": [ "On call" ] "excludeShiftTags": null, "shiftTagMatches": "ALL" } ]

3.3.3. Shift

Unit of work that has to be covered by an employee. Each shift has a start and end time and can have various requirements (e.g. skills required).

Name Required Format Description Example

Id

true

string

Unique string identifier of the shift.

"icu-afternoon-10-11-2023"

Start

true

string, ISO-8601

Start time of the shift.

"start": "2023-11-11T09:00:00Z"

End

true

string, ISO-8601

End time of the shift.

"end": "2023-11-11T17:00:00Z"

Cost group

false

string

Cost group of the shift. In conjunction with the cost group of the employee, it is used to calculate the cost of the shift assignment.

"costGroup": "Project A long shift"

Location

false

array

Location of the shift.

"location": [51.0441461, 3.7336349]

Required skills

false

array

List of required shift skills. Only an employee that has all of the shift’s required skills can be assigned to a shift.

"requiredSkills": [ "Nurse" ]

Preferred skills

false

array

List of preferred shift skills. An employee that has more of the shift’s preferred skills will be preferred over an employee with less of the shift’s preferred skills when assigning this shift.

"preferredSkills": [ "Volunteer" ]

Risk factors

false

array

List of risk factors associated with this shift. An employee cannot be assigned to a shift that is associated with any of their prohibited risk factors (for instance, selected employees cannot be exposed to COVID-19 shift).

"riskFactors": [ "COVID-19" ]

Tags

false

array

List of shift tags. Use to express additional shift data (e.g. shift type, department).

"tags": [ "AFTERNOON", "DEPARTMENT_A" ]

Preferred employees

false

array

List of preferred shift employees. Use to express employees that are preferred to work on a shift.

"preferredEmployees": [ "Elsa Green" ]

Unpreferred employees

false

array

List of preferred shift employees. Use to express employees that are unpreferred to work on a shift.

"unpreferredEmployees": [ "Elsa Green" ]

Prohibited employees

false

array

List of prohibited shift employees. Use to express employees that are prohibited to work on a shift.

"prohibitedEmployees": [ "Elsa Green" ]

Assignment priority

false

int

Deprecated - use priority field. Defines priority for shift assignment where 1 is the highest priority and 5 is the lowest priority.

"assignmentPriority": 2

Priority

false

string

Defines priority for shift assignment. There are 10 built-in priorities where "1" is the highest priority and "10" is the lowest priority. Default built-in priority is "10". These built-in priorities use exponential penalty weights, where priority "1" is 10 times more important than priority "2", priority "2" is 10 times more important than priority "3" and so on. Optionally, you can override these weights, or define custom priorities in the unassigned shift rule. In case the custom priorities are used, there is no default value for the priority attribute, and you need to provide a value.

"priority": "5"

Pinned

false

boolean

Shift pin. Use to fix shift assignment to a specific employee / no employee (employee attribute).

"pinned": false

Employee

false

reference

Employee assigned to the shift. Can be changed by the solver depending on the value of pinned attribute.

"employee": "Amy Smith"

3.3.4. Global rules configuration

Configuration of global rules that apply to all employees and shifts (e.g. fairness configuration).

Name Required Format Description Example

Balance time worked rules

false

array

Configuration of balance time worked rules. Use to make sure the number of minutes worked across shifts, that match the conditions specified, is balanced across employees. The rule takes historic data into account. Use the employeeToPublishedMinutesWorked attribute to specify the number of minutes worked by each employee in the past.

"balanceTimeWorkedRules": [ { "id": "balanceNightShiftTimeWorkedForPartTimeEmployees", "includeEmployeeTags": null, "excludeEmployeeTags": [ "Part time" ], "employeeTagMatches": "ALL", "includeShiftTags": [ "NIGHT" ], "excludeShiftTags": null, "shiftTagMatches": "ALL", "employeeToPublishedMinutesWorked": { "Elsa Green": 9600 } } ]"

Balance shift count rules

false

array

Configuration of balance shift count rules. Use to make sure the number of shifts worked, that match the conditions specified, is balanced across employees. The rule takes historic data into account. Use the employeeToPublishedShiftCount attribute to specify the number of shifts worked by each employee in the past.

"balanceShiftCountRules": [ { "id": "balanceNightShiftCountForPartTimeEmployees", "includeEmployeeTags": null, "excludeEmployeeTags": [ "Part time" ], "employeeTagMatches": "ALL", "includeShiftTags": [ "NIGHT" ], "excludeShiftTags": null, "shiftTagMatches": "ALL", "employeeToPublishedShiftCount": { "Elsa Green": 20 } } ]"

Hourly demand rules

false

array

Configuration of hourly demand rules. Rules tied to hourly demand. Use this to express global preference, or a requirement to fulfill "
"a certain number of shifts in hourly intervals, optionally only for shifts with specific tags.

"minimumMaximumShiftsPerHourlyDemand": [ { "id": "HourlyDemand", "includeShiftTags": [ "Location A" ], "demandDetails": [ { "startDateTime": "2024-05-01T00:00:00Z", "endDateTime": "2024-05-01T01:00:00Z", "minDemand": 20 }, { "startDateTime": "2024-05-01T01:00:00Z", "endDateTime": "2024-05-01T02:00:00Z", "minDemand": 22 } ] } ]

Costs rule

false

array

Configuration of costs rule. Use this to make sure the total costs of shift assignments are in the required range.

Please see Timezones and Daylight Saving Time (DST) when working with multiple time zones or DST.

"costsRules": [ { "id": "max10kPerPayPeriod", "period": "PAY_PERIOD", "includeShiftTags": null, "excludeShiftTags": null, "shiftTagMatches": "ALL", "satisfiability": "PREFERRED", "employeeShiftCostDetails": [ { "employeeCostGroup": "EMPLOYEE_COST_GROUP_A", "shiftCostGroup": "SHIFT_COST_GROUP_A", "cost": 20 }, { "employeeCostGroup": "EMPLOYEE_COST_GROUP_B", "shiftCostGroup": "SHIFT_COST_GROUP_A", "cost": 50 }, { "employeeCostGroup": "EMPLOYEE_COST_GROUP_A", "shiftCostGroup": "SHIFT_COST_GROUP_B", "cost": 20 }, { "employeeCostGroup": "EMPLOYEE_COST_GROUP_B", "shiftCostGroup": "SHIFT_COST_GROUP_B", "cost": 80 } ], "totalCostsMin": null, "totalCostsMax": 10000, "zoneOffset": "Z" } ]

Minimum maximum number of shifts worked per period

false

array

Rules tied to a period (e.g. DAY, WEEK, MONTH, SCHEDULE). Use this to express a global preference, or a requirement to work a certain number of shifts in a period, optionally only for shifts with specific tags.

Please see Timezones and Daylight Saving Time (DST) when working with multiple time zones or DST.

"minimumMaximumShiftsPerPeriod": [ { "id": "min3ShiftsPerDay", "period": "DAY", "satisfiability": "PREFERRED", "includeEmployeeTags": [ "Full-Time" ], "includeShiftTags": [ "ICU" ], "shiftsWorkedMin": 3, "zoneOffset": "Z" }

Disruption rules

false

array

Configuration of disruption rules. Use this to make sure the disruptions caused by resolving an existing problem are minimized.

`"disruptionRules": [ { "id": "minimizeDisruptionShortTerm", "start": "2024-05-01", "end": "2024-05-14", "multiplier": 3 }, { "id": "minimizeDisruptionLongTerm", "start": "2024-05-15", "end": "2024-07-01", "multiplier": 1 } ]

Shift tag match rules

false

array

Configuration of shift tag match rules. Use this to express a requirement, or a preference of an employee to work specific shift types.

"shiftTagMatchRules": [ { "id": "matchOrgUnit", "satisfiability": "PREFERRED", "tagTypeMatchMultipliers": { "Team": 1000000, "Department": 1000 } } ]

Unassigned shift rule

false

object

Configuration of unassigned shift rule. Use this to configure the priorities of shift assignments and configure custom priorities. See Unassigned shift rule for more information.

"unassignedShiftRule": { "id": "unassignedShiftRule", "priorityWeights": [ { "priority": "1", "weight": 100 }, { "priority": "2", "weight": 10 }, { "priority": "custom", "weight": 1 } ] }

3.3.5. Schedule Parameterization

3.3.5.1. Periods

Configuration for periods used in the schedule. The following builtin periods are available:

  • DAY: Spans a single day and occurs on every day being scheduled.

  • WEEK: Spans 7 days, starting at the specified weekStart in the Schedule Parameterization. Repeats for every week being scheduled (including partial weeks).

  • MONTH: Spans the entire month. Has a variable amount of days depending on the days in the month. Repeats for every month being scheduled (including partial months).

  • SCHEDULE: Spans the entire schedule.

  • MONDAY: A single day span that repeats for each Monday being scheduled.

  • TUESDAY: A single day span that repeats for each Tuesday being scheduled.

  • WEDNESDAY: A single day span that repeats for each Wednesday being scheduled.

  • THURSDAY: A single day span that repeats for each Thursday being scheduled.

  • FRIDAY: A single day span that repeats for each Friday being scheduled.

  • SATURDAY: A single day span that repeats for each Saturday being scheduled.

  • SUNDAY: A single day span that repeats for each Sunday being scheduled.

Name Required Format Description Example

Week Start

false

string, Weekday ALLCAPS

The day each week inside the WEEK period should start on.

"TUESDAY"

Periods

false

array

List of custom periods. Each custom period has an id used to identify it in period rule, and a list of date spans that the custom period covers. The date spans can vary in duration, and do not need to be continuous. The boundaries of the date spans are inclusive.

"periods": [ { "id": "PAY_PERIOD", "dateSpans": [ { "start": "2023-01-01", "end": "2023-01-15" } ]}]

Travel configuration

false

object

Travel configuration. Every employee can define location. Similarly, shifts can define location. Together with travel configuration, these attributes are used to calculate travel related rules, such as maximum distance between an employee and a shift.

The configuration can exclude some of the shifts from the maximum travel distance limit, based on the employee’s requiredShiftTags and preferredShiftTags attributes.

For example, we want to enforce a limit of 100 km between an employee and a shift, but we want to exclude shifts that belong to the same team as the employee.

"travelConfiguration": { "maxEmployeeToShiftTravelDistanceInMeters": 100000, "minMinutesBetweenShiftsInDifferentLocations": 240, "excludeMatchingShiftTagTypes": ["Team"] }

3.3.6. Tags and tag types

Tags provide additional data to domain objects, such as employees and shifts. An example of a tag could be country 'Belgium', department 'A', or employment type 'Contractor'.

Tags can be used to filter out specific employees or shifts in rules. Imagine a case where we want to apply Balance time worked constraints, but exclude external contractors and one-off shifts from the consideration. We follow a convention of using includeEmployeeTags, or excludeEmployeeTags to filter out employees, and using includeShiftTags, or excludeShiftTags to filter out shifts in the rules. These basic filters don’t require the user to enumerate all the tags and their categories explicitly in the input payload as a part of top-level tags and tagTypes collection.

Tags can be grouped into tag types. An example of a tag type could be 'Country', 'Department', or 'Employment type'. Some rules, such as Employee works shift with matching preferred shift tags, or configuration objects as Travel configuration require additional tag information, meaning the user needs to enumerate all referenced tags and their categories explicitly in the input payload as a part of top-level tags and tagTypes collection.

3.3.7. Tags

Name Required Format Description Example

Id

true

string

Unique string identifier of the tag.

"id": "Belgium"

Tag type

true

string

Identifiers of the tag type.

"tagType": "Country"

3.3.8. Tag types

Name Required Format Description Example

Id

true

string

Unique string identifier of the tag type.

"id": "Country"

4. Constraints

4.1. Hard constraints

4.1.1. Required skill missing

Employee possesses several skills. Shift can define one or more required skills. The constraint triggers if the employee does not have all the skills required by the shift. The skills need to be valid for the whole duration of the shift. Use the skill’s validityDateTimeSpans attribute to define the validity of a skill.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023",
  "missingSkills": [
    "Nurse"
  ]
}

4.1.2. Overlapping shift

The constraint triggers if multiple shifts assigned to the same employee overlap. Employee contract can define several allow overlapping shift rules.

If defined, only shifts containing tags defined by the allow overlapping shift rule’s includeShiftTags attribute can overlap with other shifts. With shiftTagMatches set to ALL, all tags defined by the overlapping shift rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the overlapping shift rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the allow overlapping shift rule’s excludeShiftTags attribute can overlap with other shifts. With shiftTagMatches set to ALL, all tags defined by the overlapping shift rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the overlapping shift rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Score analysis justification example:

{
  "shift1": "icu-afternoon-10-11-2023",
  "shift2": "icu-afternoon-10-11-2023",
  "employee": "Beth Jones"
}

4.1.3. Minutes worked per period not in required range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of minutes worked by the employee in a period is below the value of the period rule’s minutesWorkedMin, or above the value of period rule minutesWorkedMax.

  2. Value of period rule satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by the period rule’s includeShiftTags attribute are included in the total number of minutes worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule’s excludeShiftTags attribute are included in the total number of minutes worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax480MinutesPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "minutesWorked": 600
}

4.1.4. Shifts worked per period not in required range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of shifts assigned to the employee in a period is below the value of the period rule’s shiftsWorkedMin, or above the value of period rule shiftsWorkedMax.

  2. Value of period rule satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by the period rule’s includeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule’s excludeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax1ShiftPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "shiftsWorked": 2
}

4.1.5. Locations worked per period not in required range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. The number of the shift locations assigned to the employee in a period is above the value of the period rule’s locationsWorkedMax.

  2. The value of the period rule’s satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of locations worked. With shiftTagMatches set to ALL, all tags defined by the period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule excludeShiftTags attribute are included in the total number of locations worked. With shiftTagMatches set to ALL, all tags defined by the period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s locationsWorkedPerPeriodNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax1LocationPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "locationsWorked": 2
}

4.1.6. Days worked per period not in required range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of days when a shift is assigned to the employee in a period is below the value of the period rule’s daysWorkedMin, or above the value of the period rule’s daysWorkedMax.

  2. Value of the period rule’s satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by period rule excludeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The day is considered worked if the employee is assigned to at least one shift that starts on that day. Shifts that start on the previous day and end on the current day are not considered.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax4DaysWorkedPerWeek",
  "dateSpan": {
    "start": "2023-11-13T00:00:00Z",
    "end": "2023-11-20T00:00:00Z"
  },
  "daysWorked": 5
}

4.1.7. Shift types worked per period not in required range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of unique shift types assigned to the employee in a period is below the value of the period rule’s shiftTypesWorkedMin, or above the value of the period rule’s shiftTypesWorkedMax.

  2. A shift has exactly one tag defined by the shiftTypeTagCategories attribute. The value of this tag defines the shift type.

  3. Value of the period rule’s satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by period rule excludeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The day is considered worked if the employee is assigned to at least one shift that starts on that day. Shifts that start on the previous day and end on the current day are not considered.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax2MorningShiftsWorkedPerWeek",
  "dateSpan": {
    "start": "2023-11-13T00:00:00Z",
    "end": "2023-11-20T00:00:00Z"
  },
  "shiftTypesWorked": 4
}

4.1.8. Consecutive days worked not in required range for employee

Employee contract can define several consecutive days worked rules`. The constraint triggers if all conditions below apply:

  1. Number of consecutive days when a shift is assigned to the employee in a period is below the value of consecutive days worked rule minimum, or above the value of consecutive days worked rule maximum.

  2. Value of the period rule’s satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by the rule’s includeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by consecutive days worked rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by consecutive days worked rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the rule’s excludeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by consecutive days worked rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by consecutive days worked rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

If defined, shifts containing a tag defined by the rule’s shiftTypeTagCategories form a sequence based on the value of the tag, for example a sequence of consecutive "morning" shifts. The shift must always have at most one tag defined by the rule’s shiftTypeTagCategories attribute.

The day is considered worked if the employee is assigned to at least one shift that starts on that day. Shifts that start on the previous day and end on the current day are not considered. In case there are no shifts that satisfy the rule’s filters, not attaining the minimum does cause the constraint violation.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "consecutiveDaysWorkedRule": "BethMax2ConsecutiveMorningDaysWorked",
  "shiftTypeTagCategory": "Morning",
  "sequenceStartDate": "2023-11-13",
  "sequenceEndDate": "2023-11-27"
}

4.1.9. Shifts worked per period not in required range

Global rules configuration can define one or more minimum or maximum number of shifts worked per period. This is useful to express a global requirement to fulfill a certain number of shifts in a period, optionally only for shifts, or employees with specific tags. The constraint triggers if all conditions below apply:

  1. Number of shifts assigned in a period is below the value of the rule’s shiftsWorkedMin, or above the value of the rule’s shiftsWorkedMax.

  2. Value of period rule satisfiability attribute is set to REQUIRED.

If defined, only employees containing tags defined by rule’s includeEmployeeTags attribute are included in the total number of shifts worked. With employeeTagMatches set to ALL, all tags defined by the rule’s includeEmployeeTags attribute have to be present in the employee. With employeeTagMatches set to ANY, at least one tag defined by the rule’s includeEmployeeTags attribute has to be present in the employee.

If defined, only employees not containing tags defined by the rule’s excludeEmployeeTags attribute are included in the total number of shifts worked. With employeeTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the employee. With employeeTagMatches set to ANY, any of the tags defined by the rule’s excludeEmployeeTags attribute cannot be present in the employee.

The rule can define either includeEmployeeTags or excludeEmployeeTags, not both.

If defined, only shifts containing tags defined by the period rule’s includeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule’s excludeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Configuration example for a requirement to staff at most 3 administrative shifts per day, including only full time employees.

"minimumMaximumShiftsPerPeriod": [
  {
    "id": "AtMost3AdministrativeShiftsPerDay",
    "period": "DAY",
    "includeEmployeeTags": ["Full-time"],
    "includeShiftTags": ["Administrative"],
    "shiftsWorkedMax": 3
}

Score analysis justification example:

{
  "periodRule": "AtMost3AdministrativeShiftsPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "shiftsWorked": 4
}

4.1.10. Costs per period not in required range

Global rules configuration can define one or more costs rules. The constraint makes sure the total costs of shift assignments, that match tags specified, are in the required range.

The employee defines a cost group. The shift defines a cost group. The costs rule requires a list of employee shift cost details that expresses the cost of assigning the employee to the shift.

The constraint triggers if all conditions below apply:

  1. Total costs of shifts assigned in a period is below the value of the costs rule’s totalCostsMin, or above the value of the costs rule’s totalCostsMax.

  2. Value of the period rule’s satisfiability attribute is set to REQUIRED.

Note you need to define the cost detail for each employee cost group and shift cost group combination that should be included in the total costs. Undefined employee cost group and shift cost group combinations are not included in the total costs.

If defined, only employees containing tags defined by the rule’s includeEmployeeTags attribute are included in the total costs. With employeeTagMatches set to ALL, all tags defined by the rule’s includeEmployeeTags attribute have to be present in the employee. With employeeTagMatches set to ANY, at least one tag defined by the rule’s includeEmployeeTags attribute has to be present in the employee.

If defined, only employees not containing tags defined by the rule’s excludeEmployeeTags attribute are included in the total costs. With employeeTagMatches set to ALL, all tags defined by the rule’s excludeEmployeeTags attribute cannot be present in the employee. With employeeTagMatches set to ANY, any of the tags defined by the rule’s excludeEmployeeTags attribute cannot be present in the employee.

The rule can define either includeEmployeeTags or excludeEmployeeTags, not both.

If defined, only shifts containing tags defined by the rule’s includeShiftTags attribute are included in the total costs. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the rule’s excludeShiftTags attribute are included in the total costs. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Score analysis justification example:

{
  "costsRule": "Max20kPerMonth",
  "dateSpan": {
    "start": "2023-11-01T00:00:00Z",
    "end": "2023-12-01T00:00:00Z"
  },
  "cost": 22000
}

4.1.11. Employee is not paired with required employee

Employee can define several required employee pairings. The pairings express employees that have to work together at the same time. The constraint triggers for each shift assigned to the employee that does not overlap with a shift assigned to the required employee.

Score analysis justification example:

{
  "employee1": "Beth Jones",
  "employee2": "Ann Green",
  "shift": "icu-afternoon-10-11-2023",
  "employeePairing": {
    "pairedEmployee": "Ann Green",
    "onlyForShiftTags": [
      "Training"
    ]
  }
}

4.1.12. Employee is paired with prohibited employee

Employee can define several prohibited employee pairings. The pairings express employees that cannot work together at the same time. The constraint triggers for each shift assigned to the employee that overlaps with a shift assigned to the prohibited employee.

Score analysis justification example:

{
  "employee1": "Beth Jones",
  "employee2": "Ann Green",
  "shift1": "icu-afternoon-10-11-2023",
  "shift2": "standard-afternoon-10-11-2023",
  "employeePairing": {
    "pairedEmployee": "Ann Green",
    "onlyForShiftTags": [
      "High risk"
    ]
  }
}

4.1.13. Employee has prohibited risk factor associated with shift

Employee can define several prohibited risk factors. Shift can define one or more risk factors. The constraint triggers if the employee is assigned to a shift that contains one or more risk factors defined by the employee.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023",
  "riskFactors": [
    "COVID-19"
  ]
}

4.1.14. Prohibited employee assigned

Shift can define one or more prohibited employees. The constraint triggers if the shift is assigned to one of the employees listed in the shift’s prohibited employees collection.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023"
}

4.1.15. Employee works during unavailable time

Employee can define several unavailable time spans. The span defines a period when the employee cannot work (e.g. time off). The constraint triggers if the employee is assigned to a shift that matches optional shift tag criteria and overlaps with one or more unavailable time spans defined by the employee.

If defined, only shifts containing tags defined by unavailable time for employee includeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the unavailable time for employee includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the unavailable time for employee includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by preferred time for employee excludeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the unavailable time for employee excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the unavailable time for employee excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023",
  "overlappingTimeSpans": [
    {
      "start": "2023-11-10T12:00:00Z",
      "end": "2023-11-10T16:00:00Z"
    }
  ]
}

4.1.16. Employee does not work during available time

Employee can define several available time spans. If defined, the spans defines the only periods when the employee is available. Otherwise, the employee is available to be scheduled for the entire schedule (except when prohibited by unavailable time spans). The constraint triggers if the employee is assigned to a shift that is not contained by one or more available time spans defined by the employee that matches the optional shift tag criteria.

If defined, only shifts containing tags defined by available time for employee includeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the unavailable time for employee includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the unavailable time for employee includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by preferred time for employee excludeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the unavailable time for employee excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the unavailable time for employee excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023"
}

4.1.17. Employee works shifts with non-matching required shift tags

Global rules configuration can define one or more shift tag match rules. The constraint makes sure the employees are assigned to the shifts based on their shift type requirement.

Imagine an organization that contains multiple departments. Each department contains multiple teams. We want to create a schedule for shifts that belong to specific departments and teams. For example a shift in Department A. Employees also belong to specific departments and can only work shifts within their department. For example an employee has to work in Department A, not in Department Y

We define a tag hierarchy as described in section Tags and tag types:

"tagTypes": [
      {
        "id": "Department"
      }
    ],
    "tags": [
      {
        "id": "Department A",
        "tagType": "Department"
      },
      {
        "id": "Department B",
        "tagType": "Department"
      }
    ]

We define shifts that reference some of the tags:

"shifts": [
      {
        "id": "ShiftDepartmentA",
        "start": "2025-11-10T12:00:00Z",
        "end": "2025-11-10T16:00:00Z",
        "tags": [ "Department A" ]
      },
      {
        "id": "ShiftDepartmentB",
        "start": "2025-11-11T12:00:00Z",
        "end": "2025-11-11T16:00:00Z",
        "tags": [ "Department B" ]
      }
    ]

We define employees that express requirement to work shifts with some of the tags. This is done via the requiredShiftTags attribute:

"employees": [
      {
        "id": "EmployeeTeamX",
        "contracts": [ "Full time employee" ],
        "requiredShiftTags": [ "Department A" ]
      },
            {
        "id": "EmployeeDepartmentB",
        "contracts": [ "Full time employee" ],
        "requiredShiftTags": [ "Department B" ]
      }
    ]

We define a rule that validates that employees assigned to shifts that match their required tags. The rule states that whenever a shift is assigned to an employee and the required tag does not match the shift tags, we penalize such assignments.

For example, EmployeeDepartmentA has a required shift tag Department A. If they are assigned to the shift ShiftDepartmentA which has the tag Department A (tag type Department), we don’t penalize such assignments. If they are assigned to the shift ShiftDepartmentB which has the tag Department B (tag type Department), we penalize such assignments.

"shiftTagMatchRules": [
        {
          "id": "MatchDepartment",
          "satisfiability": "REQUIRED"
        }
      ]

The constraint triggers if all the conditions below apply:

  1. An employee that defines requiredShiftTags is assigned to a shift that defines tags and some of the tags are included in both collections.

  2. The value of the period rule’s satisfiability attribute is set to REQUIRED.

Score analysis justification example:

{
  "rule": "MatchDepartment",
  "employee": "EmployeeDepartmentA",
  "shift": "ShiftDepartmentB",
  "nonMatchingTags": [ "Department A" ]
}

4.1.18. Employee has prohibited shift near day off request

Employee contract can define several avoid shift close to day off request rules. The rules define types of shifts that should be avoided before / after a day off. The constraint triggers if all conditions below apply:

  1. Shift is assigned to the employee in a day preceding a day off and the shift contains one or more tags defined by the rule prohibitedPriorShiftTags attribute.

  2. Shift is assigned to the employee in a day following a day off and the shift contains one or more tags defined by the rule prohibitedAfterShiftTags attribute.

  3. Value of the period rule’s satisfiability attribute is set to PROHIBITED.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-evening-10-11-2023",
  "avoidShiftCloseToDayOffRequestRule": "noEveningShiftBeforeDayOff"
}

4.1.19. Minutes between shifts not in required range for employee

Employee contract can define several minutes between shifts rules. The constraint triggers if all the conditions below apply:

If the value of minimumConsecutivePriorShifts attribute is set to 1:

  1. The employee is assigned to two shifts and the duration between the first shift’s end and the second shift’s start is either below the minimum or above the maximum specified in the rule.

  2. Value of minutes between rule’s satisfiability attribute is set to REQUIRED.

If the value of minimumConsecutivePriorShifts attribute is set to 2:

  1. The employee is assigned to a consecutive daily sequence of two shifts and other shift. The duration between the end of the first sequence defined by shift’s end and the other shift’s start is either below the minimum or above the maximum specified in the rule.

  2. Value of minutes between rule’s satisfiability attribute is set to REQUIRED.

  3. Value of requiredPriorShiftTags needs to be specified to identify the prior sequence, for example a sequence of night shifts.

If defined, only shifts containing tags defined by minutes between shifts rule’s requiredPriorShiftTags attribute can be the first shift. With shiftTagMatches set to ALL, all tags defined by the minutes between shifts rule’s requiredPriorShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the minutes between shifts rule’s requiredPriorShiftTags attribute has to be present in the shift.

If defined, only shifts containing tags defined by minutes between shifts rule’s requiredAfterShiftTags attribute can be the first shift. With shiftTagMatches set to ALL, all tags defined by the minutes between shifts rule’s requiredAfterShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the minutes between shifts rule’s requiredAfterShiftTags attribute has to be present in the shift.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift1": "icu-morning-10-11-2023",
  "shift2": "icu-afternoon-10-11-2023",
  "minutesBetweenShiftsRule": "minimum600minutes",
  "violationInMinutes": 120
}

4.1.20. Employee does not have required daily shift pairing

Employee contract can define several daily shift pairings. The constraint triggers if all the conditions below apply:

  1. The employee is assigned to a shift matching the rule’s shiftTags and is not assigned to a shift matching the rule’s pairedShiftTags on a day defined by the rule’s dayOffset attribute. The offset is applied to a date of the first shift and can be both positive, or negative.

  2. Value of the daily shift pairing rule’s satisfiability attribute is set to REQUIRED.

With shiftTagMatches set to ALL, all tags defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute have to be present in the shift to match. With shiftTagMatches set to ANY, at least one tag defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute has to be present in the shift.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-morning-10-11-2023",
  "dailyShiftPairingRule": "saturdayWithSunday"
}

4.1.21. Employee has prohibited daily shift pairing

Employee contract can define several daily shift pairings. The constraint triggers if all the conditions below apply:

  1. The employee is assigned to a shift matching the rule’s shiftTags and is assigned to a shift matching the rule’s pairedShiftTags on a day defined by the rule’s dayOffset attribute. The offset is applied to a date of the first shift and can be both positive, or negative.

  2. Value of the daily shift pairing rule’s satisfiability attribute is set to PROHIBITED.

With shiftTagMatches set to ALL, all tags defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute have to be present in the shift to match. With shiftTagMatches set to ANY, at least one tag defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute has to be present in the shift.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift1": "icu-late-friday",
  "shift2": "icu-early-saturday",
  "dailyShiftPairingRule": "lateFridayNotWithEarlySaturday"
}

4.1.22. Employee does not work required single day shift sequence pattern

Employee contract can define several single day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee does not work the exact sequence of shifts on a particular day, as declared in the rule’s pattern attribute. Number of shifts the employee works on given day needs to match the size of the pattern.

  2. Value of the single day shift sequence pattern rule’s satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the single day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

Use the constraint configuration’s employeeDoesNotWorkSingleDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequence": {
    "matchElements": [
      {
        "shift": "ICU-Morning",
        "matchType": "MATCH"
      },
      {
        "shift": "ICU-Night",
        "matchType": "NO_MATCH"
      }
    ]
  },
  "patternRule": "MorningAfternoon"
}

4.1.23. Employee works prohibited single day shift sequence pattern

Employee contract can define several single day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee works the exact sequence of shifts on a particular day, as declared in the rule’s pattern attribute. Number of shifts the employee works on given day needs to match the size of the pattern.

  2. Value of the single day shift sequence pattern rule’s satisfiability attribute is set to PROHIBITED.

If defined, only shifts containing tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the single day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

Use the constraint configuration’s employeeWorksProhibitedSingleDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequence": {
    "matchElements": [
      {
        "shift": "ICU-Morning",
        "matchType": "MATCH"
      },
      {
        "shift": "ICU-Afternoon",
        "matchType": "MATCH"
      }
    ]
  },
  "patternRule": "MorningAfternoon"
}

4.1.24. Employee does not work required multi day shift sequence pattern

Employee contract can define several multi day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee does not work the exact sequence of shifts, or day offs, spanning across consecutive days, as declared in the rule’s pattern attribute.

  2. Value of the multi day shift sequence pattern rule’s satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the multi day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

In case there are multiple shifts on the same day, use the pattern element’s shiftMatches attribute to define the matching behavior. With shiftMatches set to ALL, all shifts need to match the tag criteria of the pattern element on that particular day. With shiftMatches set to ANY, any shift needs to match the tag criteria of the pattern element on that particular day. The default value of shiftMatches attribute is ALL.

Use the constraint configuration’s employeeDoesNotWorkRequiredMultiDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequences": [
    {
      "matchElements": [
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Late",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Night",
          "matchType": "NO_MATCH"
        }
      ]
    }
  ],
  "patternRule": "EarlyEarlyNightNight"
}

4.1.25. Employee works prohibited multi day shift sequence pattern

Employee contract can define several multi day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee works the exact sequence of shifts, or day offs, spanning across consecutive days, as declared in the rule’s pattern attribute.

  2. Value of the multi day shift sequence pattern rule’s satisfiability attribute is set to PROHIBITED.

If defined, only shifts containing tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the multi day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

In case there are multiple shifts on the same day, use the pattern element’s shiftMatches attribute to define the matching behavior. With shiftMatches set to ALL, all shifts need to match the tag criteria of the pattern element on that particular day. With shiftMatches set to ANY, any shift needs to match the tag criteria of the pattern element on that particular day. The default value of shiftMatches attribute is ALL.

Use the constraint configuration’s employeeWorksProhibitedMultiDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequences": [
    {
      "matchElements": [
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Late",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Late",
          "matchType": "MATCH"
        }
      ]
    }
  ],
  "patternRule": "EarlyEarlyNightNight"
}

4.1.26. Maximum employee to shift travel distance exceeded

Schedule parametrization can define travel configuration. The constraint makes sure the maximum travel distance between the employee location and shift location does not exceed the maxEmployeeToShiftTravelDistanceInMeters limit defined in the travel configuration. The configuration allows you to exclude some of the shifts from the maximum travel distance limit, based on the employee’s requiredShiftTags and preferredShiftTags attributes. For example, we want to enforce a limit of 100 km between an employee and a shift, but we want to exclude shifts that belong to the same team as the employee.

The constraint triggers if all the following conditions apply:

  1. Shift’s location is defined.

  2. Employee’s location is defined.

  3. _object_attributes_schedule_parameterization_travel_configuration[Travel configuration] is defined in the schedule parametrization.

  4. The distance between employee location and shift location exceeds the maxEmployeeToShiftTravelDistanceInMeters limit in travel configuration.

  5. If excludeMatchingShiftTagTypes is configured, there is no match between the employee’s preferredShiftTags, or requiredShiftTags and the shift’s tags for those excluded shift type tags.

If defined, only shifts containing tags defined by the travel configuration’s includeShiftTags attribute are included in the maximum travel distance check. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the travel configuration’s excludeShiftTags attribute are included in the maximum travel distance check. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, but not both.

Configuration example to set the maximum employee travel distance to 40km for all shifts.

"travelConfiguration": {
    "maxEmployeeToShiftTravelDistanceInMeters": 40000
}

Configuration example to set the maximum employee travel distance to 40km for ICU shifts.

"travelConfiguration": {
    "includeShiftTags": ["ICU"],
    "maxEmployeeToShiftTravelDistanceInMeters": 40000
}

Configuration example to set the maximum employee travel distance to 40km for ICU shifts, or Cardiology shifts.

"travelConfiguration": {
    "includeShiftTags": ["ICU", "Cardiology"],
    "shiftTagMatches": "ANY",
    "maxEmployeeToShiftTravelDistanceInMeters": 40000
}

Score analysis justification example:

"justification": {
  "shift": "ICU-shift-location-A",
  "employee": "Ann Green",
  "distanceInMeters": 42000
}

4.1.27. Minimum time between shifts including travel not met

Schedule parametrization can define travel configuration. The constraint makes sure the minimum number of minutes between shifts that have different locations and are assigned to the same employee follows the minMinutesBetweenShiftsInDifferentLocations limit defined in the travel configuration.

The constraint triggers if all conditions below apply:

  1. Shift’s location is defined.

  2. Employee’s location is defined.

  3. _object_attributes_schedule_parameterization_travel_configuration[Travel configuration] is defined in the schedule parametrization.

  4. The number of minutes between two shifts at different locations, that are assigned to the same employee, is below the minMinutesBetweenShiftsInDifferentLocations limit defined in travel configuration.

If defined, only shifts containing tags defined by the travel configuration’s includeShiftTags attribute are included in the maximum travel distance check. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the travel configuration’s excludeShiftTags attribute are included in the maximum travel distance check. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, but not both.

Configuration example to set the minimum number of minutes between any employee’s shifts in different locations to 240 minutes.

"travelConfiguration": {
    "minMinutesBetweenShiftsInDifferentLocations": 240
}

Configuration example to set the minimum number of minutes between employee’s ICU shifts in different locations to 240 minutes.

"travelConfiguration": {
    "includeShiftTags": ["ICU"],
    "minMinutesBetweenShiftsInDifferentLocations": 240
}

Configuration example to set the minimum number of minutes between employee’s ICU shifts, or Cardiology shifts in different locations to 240 minutes.

"travelConfiguration": {
    "includeShiftTags": ["ICU", "Cardiology],
    "shiftTagMatches": "ANY",
    "minMinutesBetweenShiftsInDifferentLocations": 240
}

Score analysis justification example:

"justification": {
  "shift1": "ICU-shift-location-A",
  "shift2": "ICU-shift-location-B",
  "employee": "Ann Green"
}

4.2. Medium constraints

4.2.1. Unassigned shift

The constraint penalizes shifts that are not assigned to any employee. The size of the penalty depends on the shift’s priority. High priority shifts are more likely to be assigned, compared to low priority shifts.

The model defines 10 built-in priorities, where 1 is the highest priority and 10 is the lowest priority. The default built-in priority is 10. These built-in priorities use exponential penalty weights, where priority 1 is 10 times more important than priority 2, priority 2 is 10 times more important than priority 3 and so on. Optionally, you can override these weights, or define custom priorities in the unassigned shift rule. In case the custom priorities are used, there is no default value for the priority attribute, and you need to provide a value.

You can also define the assignment priority by setting the shift’s assignmentPriority attribute. This feature has been deprecated as of 0.25.0. The payload should be updated to use the priority attribute instead. If both priority and assignmentPriority attributes are used in the dataset, a validation error is thrown. If the unassigned shift rule is configured and assignmentPriority is used in the dataset, a validation error is thrown.

Consider a case with two morning shifts:

  • Morning-head-nurse with high assignment priority 1

  • Morning-trainee-nurse with lower assignment priority 5

Whenever the solver is unable to assign both shifts, since that would lead to a hard score violation, it might decide to keep one of the shifts unassigned. In the example above, it potentially leaves 'Morning-trainee-nurse' shift unassigned, since it has a lower assignment priority.

Score analysis justification example:

"justification": {
  "shift": "Morning-trainee-nurse"
}

If 10 built-in priorities are not enough, you can define custom priority levels. These custom priorities are defined in the priorityWeights attribute of the unassigned shift rule. The weights of the priorities need to be defined in descending order, where the first element of the array has the highest weight. All priorities referenced in the dataset need to be defined in the priorityWeights attribute and their weight need to be configured.

"unassignedShiftRule": {
  "id": "unassignedShiftRule",
  "priorityWeights": [
    {
      "priority": "1",
      "weight": 20
    },
    {
      "priority": "2",
      "weight": 19
    },
    ...
    {
      "priority": "20",
      "weight": 1
    }
  ]
}

4.2.2. Shifts worked not in required hourly demand range

Global rules configuration can define one or more minimum maximum shifts per hourly demand rules. The constraint makes sure the total number of shift assignments in hourly intervals, that match tags specified, are in the required range, optionally only for shifts with specific tags.

The constraint triggers if all conditions below apply:

  1. Number of shifts worked in a hourly demand interval is below the value of the demand rule’s minDemand, or above the value of demand rule’s maxDemand.

  2. Value of the demand rule’s satisfiability attribute is set to REQUIRED.

If defined, only shifts containing tags defined by the period rule’s includeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule’s excludeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Use the constraint configuration’s shiftsWorkedNotInRequiredHourlyDemandRangeWeight attribute to update the weight of the constraint.

Score analysis justification example:

"justification": {
  "hourlyDemandRule": "HourlyDemand",
  "startDateTime": "2024-05-06T07:00:00Z",
  "shiftsWorked": 25
}

4.3. Soft constraints

4.3.1. Employee assignment disrupted on replanning

Global rules configuration can define one or more disruption rules. The constraint makes sure the disruptions caused by resolving an existing problem are minimized. This includes changes of the employee assigned to a shift, compared to the original schedule. Consider a case where you need to re-plan an already published schedule due to an unexpected employee absence. You want to minimize the impact of the re-planning on the schedule and the employees who might have already made plans based on the original schedule. Disruptions that are close to the time of the re-planning possibly have more impact than disruptions that are further away.

The constraint triggers if all conditions below apply:

  1. Original employee assigned to a shift differs from the employee assigned to the shift after the solving finished.

  2. The shift start is within the time window defined by the disruption rule’s start and end attributes. The boundaries of the time window are inclusive.

If defined, only shifts containing tags defined by the rule’s includeShiftTags attribute are included in the disruption check. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the rule’s excludeShiftTags attribute are included in the disruption checks. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeAssignmentDisruptedOnReplanningWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "currentEmployee": "Ann"
  "originalEmployee": "Beth",
  "shift": "ICU-Morning-01-05",
  "disruptionRule": "MinimimizeDisruptionShortTerm"
}

4.3.2. Preferred skill missing

Employee possesses several skills. Shift can define one or more preferred skills. The constraint triggers if the employee does not have all the skills defined by the shift. The skills need to be valid for the whole duration of the shift. Use the skill’s validityDateTimeSpans attribute to define the validity of a skill.

Use the constraint configuration’s preferredSkillMissingWeigh attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023",
  "missingSkills": [
    "Nurse"
  ]
}

4.3.3. Minutes worked per period not in preferred range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of minutes worked by the employee in a period is below the value of the period rule’s minutesWorkedMin, or above the value of the period rule’s minutesWorkedMax.

  2. Value of the period rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of minutes worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by period rule excludeShiftTags attribute are included in the total number of minutes worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s minutesAssignedPerPeriodNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax480MinutesPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "minutesWorked": 600
}

4.3.4. Shifts worked per period not in preferred range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of shifts assigned to the employee in a period is below the value of the period rule’s shiftsWorkedMin, or above the value of the period rule’s shiftsWorkedMax.

  2. Value of the period rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by period rule excludeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s shiftsAssignedPerPeriodNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax1ShiftPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "shiftsWorked": 2
}

4.3.5. Locations worked per period not in preferred range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. The number of shift locations assigned to the employee in a period is above the value of the period rule’s locationsWorkedMax.

  2. The value of the period rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by the period rule includeShiftTags attribute are included in the total number of locations worked. With shiftTagMatches set to ALL, all tags defined by the period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule excludeShiftTags attribute are included in the total number of locations worked. With shiftTagMatches set to ALL, all tags defined by the period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s locationsWorkedPerPeriodNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax1LocationPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "locationsWorked": 2
}

4.3.6. Days worked per period not in preferred range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of days when a shift is assigned to the employee in a period is below the value of the period rule’s daysWorkedMin, or above the value of the period rule’s daysWorkedMax.

  2. Value of the period rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by period rule excludeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The day is considered worked if the employee is assigned to at least one shift that starts on that day. Shifts that start on the previous day and end on the current day are not considered.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s daysWorkedPerPeriodNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax4DaysWorkedPerWeek",
  "dateSpan": {
    "start": "2023-11-13T00:00:00Z",
    "end": "2023-11-20T00:00:00Z"
  },
  "daysWorked": 5
}

4.3.7. Shift types worked per period not in preferred range for employee

Employee contract can define several period rules. The constraint triggers if all conditions below apply:

  1. Number of unique shift types assigned to the employee in a period is below the value of the period rule’s shiftTypesWorkedMin, or above the value of the period rule’s shiftTypesWorkedMax.

  2. A shift has exactly one tag defined by the shiftTypeTagCategories attribute. The value of this tag defines the shift type.

  3. Value of the period rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by period rule excludeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The day is considered worked if the employee is assigned to at least one shift that starts on that day. Shifts that start on the previous day and end on the current day are not considered.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s shiftTypesWorkedPerPeriodNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "periodRule": "BethMax2MorningShiftsWorkedPerWeek",
  "dateSpan": {
    "start": "2023-11-13T00:00:00Z",
    "end": "2023-11-20T00:00:00Z"
  },
  "shiftTypesWorked": 4
}

4.3.8. Consecutive days worked not in preferred range for employee

Employee contract can define several consecutive days worked rules. The constraint triggers if all conditions below apply:

  1. Number of consecutive days when a shift is assigned to the employee in a period is below the value of consecutive days worked rule minimum, or above the value of consecutive days worked rule maximum.

  2. Value of the period rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by period rule includeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by consecutive days worked rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by consecutive days worked rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by period rule excludeShiftTags attribute are included in the total number of days worked. With shiftTagMatches set to ALL, all tags defined by consecutive days worked rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by consecutive days worked rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The day is considered worked if the employee is assigned to at least one shift that starts on that day. Shifts that start on the previous day and end on the current day are not considered.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s consecutiveDaysWorkedNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "consecutiveDaysWorkedRule": "BethMax2ConsecutiveMorningDaysWorked",
  "shiftTypeTagCategory": "Morning",
  "sequenceStartDate": "2023-11-13",
  "sequenceEndDate": "2023-11-27"
}

4.3.9. Shifts worked not in preferred hourly demand range

Global rules configuration can define one or more minimum maximum shifts per hourly demand rules. The constraint makes sure the total number of shift assignments in hourly intervals, that match tags specified, are in the required range, optionally only for shifts with specific tags.

The constraint triggers if all conditions below apply:

  1. Number of shifts worked in a hourly demand interval is below the value of the demand rule’s minDemand, or above the value of demand rule’s maxDemand.

  2. Value of the demand rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by the period rule’s includeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule’s excludeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Use the constraint configuration’s shiftsWorkedNotInPreferredHourlyDemandRangeWeight attribute to update the weight of the constraint.

Score analysis justification example:

"justification": {
  "hourlyDemandRule": "HourlyDemand",
  "startDateTime": "2024-05-06T07:00:00Z",
  "shiftsWorked": 25
}

4.3.10. Balance shifts worked for minimum hourly demand

Global rules configuration can define one or more minimum maximum shifts per hourly demand rules. The constraint makes sure the total number of shift assignments, that match tags specified, are distributed evenly across the hourly intervals. The constraint takes the minimum demand into account, optionally only for shifts with specific tags. For example, if the minimum demand throughout the whole day is 5 shifts and the shift supply is higher than the demand, the constraint makes sure that the extra shifts are distributed evenly across the day, as opposed to assigning them all in the first hour of the day.

The constraint triggers if all conditions below apply:

  1. Number of shifts worked in a hourly demand interval differs from the value of the demand rule’s minDemand.

If defined, only shifts containing tags defined by the period rule’s includeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by period rule includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule’s excludeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by period rule excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by period rule excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Use the constraint configuration’s balanceShiftsWorkedForMinimumHourlyDemandWeight attribute to update the weight of the constraint.

Score analysis justification example:

"justification": {
  "hourlyDemandRule": "HourlyDemand",
  "startDateTime": "2024-05-06T07:00:00Z",
  "targetDemand": 30,
  "shiftsWorked": 25
}

4.3.11. Shifts worked per period not in preferred range

Global rules configuration can define one or more minimum or maximum number of shifts worked per period. This is useful to express a global preference to fulfill a certain number of shifts in a period, optionally only for shifts, or employees with specific tags. The constraint triggers if all conditions below apply:

  1. Number of shifts assigned in a period is below the value of the rule’s shiftsWorkedMin, or above the value of the rule’s shiftsWorkedMax.

  2. Value of period rule satisfiability attribute is set to PREFERRED.

If defined, only employees containing tags defined by rule’s includeEmployeeTags attribute are included in the total number of shifts worked. With employeeTagMatches set to ALL, all tags defined by the rule’s includeEmployeeTags attribute have to be present in the employee. With employeeTagMatches set to ANY, at least one tag defined by the rule’s includeEmployeeTags attribute has to be present in the employee.

If defined, only employees not containing tags defined by the rule’s excludeEmployeeTags attribute are included in the total number of shifts worked. With employeeTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the employee. With employeeTagMatches set to ANY, any of the tags defined by the rule’s excludeEmployeeTags attribute cannot be present in the employee.

The rule can define either includeEmployeeTags or excludeEmployeeTags, not both.

If defined, only shifts containing tags defined by the period rule’s includeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the period rule’s excludeShiftTags attribute are included in the total number of shifts worked. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Configuration example for a preference to staff at most 3 administrative shifts per day, including only full time employees.

"minimumMaximumShiftsPerPeriod": [
  {
    "id": "AtMost3AdministrativeShiftsPerDay",
    "period": "DAY",
    "satisfiability": "PREFERRED",
    "includeEmployeeTags": ["Full-time"],
    "includeShiftTags": ["Administrative"],
    "shiftsWorkedMax": 3
}

Score analysis justification example:

{
  "periodRule": "AtMost3AdministrativeShiftsPerDay",
  "dateSpan": {
    "start": "2023-11-10T00:00:00Z",
    "end": "2023-11-11T00:00:00Z"
  },
  "shiftsWorked": 4
}

4.3.12. Costs per period not in preferred range

Global rules configuration can define one or more costs rules. The constraint makes sure the total costs of shift assignments, that match tags specified, are in the required range.

The employee defines a cost group. The shift defines a cost group. The costs rule requires a list of employee shift cost details that expresses the cost of assigning the employee to the shift.

The constraint triggers if all conditions below apply:

  1. Total costs of shifts assigned in a period is below the value of the costs rule’s totalCostsMin, or above the value of the costs rule’s totalCostsMax.

  2. Value of the period rule’s satisfiability attribute is set to PREFERRED.

Note you need to define the cost detail for each employee cost group and shift cost group combination that should be included in the total costs. Undefined employee cost group and shift cost group combinations are not included in the total costs.

If defined, only employees containing tags defined by the rule’s includeEmployeeTags attribute are included in the total costs. With employeeTagMatches set to ALL, all tags defined by the rule’s includeEmployeeTags attribute have to be present in the employee. With employeeTagMatches set to ANY, at least one tag defined by the rule’s includeEmployeeTags attribute has to be present in the employee.

If defined, only employees not containing tags defined by the rule’s excludeEmployeeTags attribute are included in the total costs. With employeeTagMatches set to ALL, all tags defined by the rule’s excludeEmployeeTags attribute cannot be present in the employee. With employeeTagMatches set to ANY, any of the tags defined by the rule’s excludeEmployeeTags attribute cannot be present in the employee.

The rule can define either includeEmployeeTags or excludeEmployeeTags, not both.

If defined, only shifts containing tags defined by the rule’s includeShiftTags attribute are included in the total costs. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the rule’s excludeShiftTags attribute are included in the total costs. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Use the constraint configuration’s costsPerPeriodNotInPreferredRangeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "costsRule": "Max20kPerMonth",
  "dateSpan": {
    "start": "2023-11-01T00:00:00Z",
    "end": "2023-12-01T00:00:00Z"
  },
  "cost": 22000
}

4.3.13. Employee is paired with preferred employee

Employee can define several preferred employee pairings. The pairings express employees that prefer working together at the same time. The constraint triggers for each shift assigned to the employee that overlaps with a shift assigned to the preferred employee.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeIsPairedWithPreferredEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee1": "Beth Jones",
  "employee2": "Ann Green",
  "shift1": "icu-afternoon-10-11-2023",
  "shift2": "standard-afternoon-10-11-2023",
  "employeePairing": {
    "pairedEmployee": "Ann Green",
    "onlyForShiftTags": [
      "Training"
    ]
  }
}

4.3.14. Employee is paired with unpreferred employee

Employee can define several unpreferred employee pairings. The pairings express employees that prefer not to work together at the same time. The constraint triggers for each shift assigned to the employee that overlaps with a shift assigned to the unpreferred employee.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeIsPairedWithUnpreferredEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee1": "Beth Jones",
  "employee2": "Ann Green",
  "shift1": "icu-afternoon-10-11-2023",
  "shift2": "standard-afternoon-10-11-2023",
  "employeePairing": {
    "pairedEmployee": "Ann Green",
    "onlyForShiftTags": [
      "High risk"
    ]
  }
}

4.3.15. Employee works during preferred time

Employee contract can define several preferred time spans. The span defines a period when the employee prefers to work. The constraint triggers if the employee is assigned to a shift that matches optional shift tag criteria and overlaps with one or more preferred time spans defined by the employee.

If defined, only shifts containing tags defined by preferred time for employee includeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the preferred time for employee includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the preferred time for employee includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by preferred time for employee excludeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the preferred time for employee excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the preferred time for employee excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeWorksDuringPreferredTimeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023",
  "overlappingTimeSpans": [
    {
      "start": "2023-11-10T06:00:00Z",
      "end": "2023-11-10T18:00:00Z"
    }
  ]
}

4.3.16. Employee works during unpreferred time

Employee contract can define several unpreferred time spans. The span defines a period when the employee prefers not to work. The constraint triggers if the employee is assigned to a shift that matches optional shift tag criteria and overlaps with one or more unpreferred time spans defined by the employee.

If defined, only shifts containing tags defined by unpreferred time for employee includeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the unpreferred time for employee includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the unpreferred time for employee includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by unpreferred time for employee excludeShiftTags attribute are included. With shiftTagMatches set to ALL, all tags defined by the unpreferred time for employee excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the unpreferred time for employee excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeWorksDuringUnpreferredTimeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023",
  "overlappingTimeSpans": [
    {
      "start": "2023-11-10T12:00:00Z",
      "end": "2023-11-10T16:00:00Z"
    }
  ]
}

4.3.17. Employee works shifts with matching preferred shift tags

Global rules configuration can define one or more shift tag match rules. The constraint makes sure the employees are assigned to the shifts based on their shift type preference.

Imagine an organization that contains multiple departments. Each department contains multiple teams. We want to create a schedule for shifts that belong to specific departments and teams. For example a shift in Department A and team Team X. Employees also belong to specific departments and teams. Moreover, the employees can work a shift in a different department, or team, if needed. For example an employee preferrably works in Department A and team Team X, but can also take shifts in Department Y. The former assignment should be preferred if possible.

We define a tag hierarchy as described in section Tags and tag types:

"tagTypes": [
      {
        "id": "Department"
      },
      {
        "id": "Team"
      }
    ],
    "tags": [
      {
        "id": "Team X",
        "tagType": "Team"
      },
      {
        "id": "Team Y",
        "tagType": "Team"
      },
      {
        "id": "Department A",
        "tagType": "Department"
      },
      {
        "id": "Department B",
        "tagType": "Department"
      }
    ]

We define shifts that reference some of the tags:

"shifts": [
      {
        "id": "ShiftTeamX",
        "start": "2025-11-10T12:00:00Z",
        "end": "2025-11-10T16:00:00Z",
        "tags": [ "Team X", "Department A" ]
      },
      {
        "id": "ShiftTeamY",
        "start": "2025-11-11T12:00:00Z",
        "end": "2025-11-11T16:00:00Z",
        "tags": [ "Team Y", "Department A" ]
      },
      {
        "id": "ShiftDepartmentB",
        "start": "2025-11-12T12:00:00Z",
        "end": "2025-11-12T16:00:00Z",
        "tags": [ "Department B" ]
      }
    ]

We define employees that express preference to work shifts with some of the tags. This is done with the preferredShiftTags attribute:

"employees": [
      {
        "id": "EmployeeTeamX",
        "contracts": [ "Full time employee" ],
        "preferredShiftTags": [ "Team X", "Department A" ]
      },
            {
        "id": "EmployeeDepartmentB",
        "contracts": [ "Full time employee" ],
        "preferredShiftTags": [ "Department B" ]
      }
    ]

We define a rule that expresses how likely employees are to be assigned shifts that match their preferred tags. The rule states that whenever a shift is assigned to an employee and the preferred tag matches shift tags, we reward such assignment with a multiplier, depending on the shift type of the tag.

For example, EmployeeTeamX has preferred shift tags Team X and Department A. If they are assigned to the shift ShiftTeamX which has the tags Team X (tag type Team) and Department A (tag type Department), we reward with multipliers 1,000,000 and 1,000 respectively. If they are assigned to the shift ShiftTeamY which has the tags Team Y (tag type Team) and Department A (tag type Department), we reward with multipliers 1,000, since only the department matches. If they are assigned to the shift ShiftDepartmentB which has the tags Department B (tag type Department), we don’t reward, since none of the tags match.

"shiftTagMatchRules": [
        {
          "id": "MatchOrganization",
          "satisfiability": "PREFERRED",
          "tagTypeMatchMultipliers": {
            "Team": 1000000,
            "Department": 1000
          }
        }
      ]

The constraint triggers if all the conditions below apply:

  1. An employee that defines preferredShiftTags is assigned to a shift that defines tags and some of the tags are included in both collections.

  2. The value of the period rule’s satisfiability attribute is set to PREFERRED.

Use the constraint configuration’s employeeWorksShiftWithPreferredShiftTagsWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "rule": "MatchOrganization",
  "employee": "EmployeeTeamX",
  "shift": "ShiftTeamX",
  "matchingTags": [ "Department A", "Team X" ]
}

4.3.18. Employee has unpreferred shift near day off request

Employee contract can define several avoid shift close to day off request rules. The rules define types of shifts that should be avoided before / after a day off. The constraint triggers if all conditions below apply:

  1. Shift is assigned to the employee in a day preceding a day off and the shift contains one or more tags defined by the rule prohibitedPriorShiftTags attribute.

  2. Shift is assigned to the employee in a day following a day off and the shift contains one or more tags defined by the rule prohibitedAfterShiftTags attribute.

  3. Value of the rule’s satisfiability attribute is set to UNPREFERRED.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeHasUnpreferredShiftNearDayOffRequestWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-evening-10-11-2023",
  "avoidShiftCloseToDayOffRequestRule": "noEveningShiftBeforeDayOff"
}

4.3.19. Preferred employee assigned

Shift can define one or more preferred employees. The constraint triggers if the shift is assigned to one of the employees listed in the shift’s preferred employees collection.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s preferredEmployeeAssignedWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023"
}

4.3.20. Unpreferred employee assigned

Shift can define one or more unpreferred employees. The constraint triggers if the shift is assigned to one of the employees listed in the shift’s unpreferred employees collection.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s unpreferredEmployeeAssignedWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-afternoon-10-11-2023"
}

4.3.21. Balance time worked

Global rules configuration can define one or more balance time worked rules. The constraint makes sure the total number of minutes worked across shifts, that match the specified tags, is balanced across employees that match the specified tags. This avoids situations where some employees work more time than others.

Please see Load balancing and fairness for further information about the fairness concept.

If defined, only employees containing tags defined by the balance time worked rule’s includeEmployeeTags attribute are balanced. With employeeTagMatches set to ALL, all tags defined by the balance time worked rule’s includeEmployeeTags attribute have to be present in the employee. With employeeTagMatches set to ANY, at least one tag defined by the balance time worked rule’s includeEmployeeTags attribute has to be present in the employee.

If defined, only employees not containing tags defined by the balance time worked rule’s excludeEmployeeTags attribute are balanced. With employeeTagMatches set to ALL, all tags defined by the balance time worked rule’s excludeShiftTags attribute cannot be present in the employee. With employeeTagMatches set to ANY, any of the tags defined by the the balance time worked rule’s excludeEmployeeTags attribute cannot be present in the employee.

The rule can define either includeEmployeeTags or excludeEmployeeTags, not both.

If defined, only shifts containing tags defined by the balance time worked rule’s includeShiftTags attribute are balanced. With shiftTagMatches set to ALL, all tags defined by the balance time worked rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the balance time worked rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the balance time worked rule’s excludeShiftTags attribute are balanced. With shiftTagMatches set to ALL, all tags defined by the balance time worked rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the balance time worked rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Use employeeToPublishedMinutesWorked attribute to specify the number of minutes worked by each employee in the past.

Use the constraint configuration’s balanceTimeWorkedWeight attribute to update the weight of the constraint.

4.3.22. Balance shift count

Global rules configuration can define one or more balance shift count rules. The constraint makes sure the total number of shifts worked, that match the specified tags, is balanced across employees that match the specified tags. This avoids situations where some employees work more shifts than others.

Please see Load balancing and fairness for further information about the fairness concept.

If defined, only employees containing tags defined by the balance shift count rule’s includeEmployeeTags attribute are balanced. With employeeTagMatches set to ALL, all tags defined by the balance shift count rule’s includeEmployeeTags attribute have to be present in the employee. With employeeTagMatches set to ANY, at least one tag defined by the balance shift count rule’s includeEmployeeTags attribute has to be present in the employee.

If defined, only employees not containing tags defined by the balance shift count rule’s excludeEmployeeTags attribute are balanced. With employeeTagMatches set to ALL, all tags defined by the balance shift count rule’s excludeShiftTags attribute cannot be present in the employee. With employeeTagMatches set to ANY, any of the tags defined by the balance shift count rule’s excludeEmployeeTags attribute cannot be present in the employee.

The rule can define either includeEmployeeTags or excludeEmployeeTags, not both.

If defined, only shifts containing tags defined by the balance shift count rule’s includeShiftTags attribute are balanced. With shiftTagMatches set to ALL, all tags defined by the balance shift count rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the balance shift count rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the balance shift count rule’s excludeShiftTags attribute are balanced. With shiftTagMatches set to ALL, all tags defined by the balance shift count rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the balance shift count rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both.

Use employeeToPublishedShiftCount attribute to specify the number of shifts worked by each employee in the past.

Use the constraint configuration’s balanceShiftCountWeight attribute to update the weight of the constraint.

4.3.23. Minutes between shifts not in preferred range for employee

Employee contract can define several minutes between shifts rules. The constraint triggers if all the conditions below apply:

  1. The employee is assigned to two shifts and the duration between the first shift’s end and the second shift’s start is either below the minimum or above the maximum specified in the rule.

  2. Value of minutes between rule’s satisfiability attribute is set to PREFERRED.

  3. Value of requiredPriorShiftTags needs to be specified to identify the prior sequence, for example a sequence of night shifts.

If defined, only shifts containing tags defined by minutes between shifts rule’s requiredPriorShiftTags attribute can be the first shift. With shiftTagMatches set to ALL, all tags defined by the minutes between shifts rule’s requiredPriorShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the minutes between shifts rule’s requiredPriorShiftTags attribute has to be present in the shift.

If defined, only shifts containing tags defined by minutes between shifts rule’s requiredAfterShiftTags attribute can be the first shift. With shiftTagMatches set to ALL, all tags defined by the minutes between shifts rule’s requiredAfterShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the minutes between shifts rule’s requiredAfterShiftTags attribute has to be present in the shift.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s minutesBetweenShiftsNotInPreferredRangeForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift1": "icu-morning-10-11-2023",
  "shift2": "icu-afternoon-10-11-2023",
  "minutesBetweenShiftsRule": "minimum600minutes",
  "violationInMinutes": 120
}

4.3.24. Minimize gaps between shifts for employee

Employee contract can define several minimize gaps between shifts rules. The constraint makes sure that shifts close to each other are preferred for an employee, in case the employee is eligible to work multiple shifts per day.

Imagine a case, where we have 3 shifts on a day:

  • Morning shift - 9:00 - 12:00

  • Afternoon shift - 13:00 - 16:00

  • Late shift - 17:00 - 20:00

In case we assigned an employee to the Morning shift and the Late shift, it leaves them with a 5-hour gap between the shifts, which is undesirable. A preferred solution would be to assign them to the Morning shift and the Afternoon shift, or the Afternoon shift and the Late shift, since those pairs of shifts only have 1-hour gap between them. This constraint prefers closer assignments. The shorter the break between the shifts, the better.

To avoid situations, where we reward pairs of shifts that are separated by multiple days, the constraint requires a definition of a time scope. Only shifts that are close enough to each other are considered. Use the rule’s maximumMinutesBetweenSplitShifts to define the length of the scope. The default value of maximumMinutesBetweenSplitShifts is 120 minutes. Looking at the example above, if the maximumMinutesBetweenSplitShifts is configured to 120 minutes, the Morning shift and the Afternoon shifts match, since they are only separated by 1 hour. The same applies to the Afternoon shift and the Late shift. The combination of the Morning shift and Late shift does not match though, since they are separated by 5 hours, which is above the limit of 2 hours.

The constraint triggers if all the following conditions apply:

  1. The employee is assigned to two shifts and the duration between the first shift’s end and the second shift’s start is below the maximumMinutesBetweenSplitShifts specified in the rule.

If defined, only shifts containing tags defined by minutes between shifts rule’s requiredPriorShiftTags attribute can be the first shift. With shiftTagMatches set to ALL, all tags defined by the minimize gaps between shifts rule’s requiredPriorShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the minimize gaps between shifts rule’s requiredPriorShiftTags attribute has to be present in the shift.

If defined, only shifts containing tags defined by minutes between shifts rule’s requiredAfterShiftTags attribute can be the first shift. With shiftTagMatches set to ALL, all tags defined by the minimize gaps between shifts rule’s requiredAfterShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the minimize gaps between shifts rule’s requiredAfterShiftTags attribute has to be present in the shift.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s minimizeGapsBetweenShiftsForEmployeeWeight attribute to update the weight of the constraint.

Score analysis justification example:

"justification": {
    "employee": "Beth Jones",
    "shift1": "ICU morning",
    "shift2": "ICU afternoon",
    "minimizeGapsBetweenShiftsRule": "MinimizeGapsBetweenShiftsRule",
    "minutesBetweenShifts": 60

4.3.25. Employee does not have preferred daily shift pairing

Employee contract can define several daily shift pairings. The constraint triggers if all the conditions below apply:

  1. The employee is assigned to a shift matching the rule’s shiftTags and is not assigned to a shift matching the rule’s pairedShiftTags on a day defined by the rule’s dayOffset attribute. The offset is applied to a date of the first shift and can be both positive, or negative.

  2. Value of the daily shift pairing rule’s satisfiability attribute is set to PREFERRED.

With shiftTagMatches set to ALL, all tags defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute have to be present in the shift to match. With shiftTagMatches set to ANY, at least one tag defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute has to be present in the shift.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeDoesNotHavePreferredDailyShiftPairingWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift": "icu-morning-10-11-2023",
  "dailyShiftPairingRule": "saturdayWithSunday"
}

4.3.26. Employee has unpreferred daily shift pairing

Employee contract can define several daily shift pairings. The constraint triggers if all the conditions below apply:

  1. The employee is assigned to a shift matching the rule’s shiftTags and is assigned to a shift matching the rule’s pairedShiftTags on a day defined by the rule’s dayOffset attribute. The offset is applied to a date of the first shift and can be both positive, or negative.

  2. Value of the daily shift pairing rule’s satisfiability attribute is set to UNPREFERRED.

With shiftTagMatches set to ALL, all tags defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute have to be present in the shift to match. With shiftTagMatches set to ANY, at least one tag defined by the daily shift pairing rule’s shiftTags/pairedShiftTags attribute has to be present in the shift.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeHasUnpreferredDailyShiftPairingWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "employee": "Beth Jones",
  "shift1": "icu-late-friday",
  "shift2": "icu-early-saturday",
  "dailyShiftPairingRule": "lateFridayNotWithEarlySaturday"
}

4.3.27. Employee works preferred single day shift sequence pattern

Employee contract can define several single day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee works the exact sequence of shifts on a particular day, as declared in the rule’s pattern attribute. Number of shifts the employee works on given day needs to match the size of the pattern.

  2. Value of the single day shift sequence pattern rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the single day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeWorksPreferredSingleDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequence": {
    "matchElements": [
      {
        "shift": "ICU-Morning",
        "matchType": "MATCH"
      },
      {
        "shift": "ICU-Afternoon",
        "matchType": "MATCH"
      }
    ]
  },
  "patternRule": "MorningAfternoon"
}

4.3.28. Employee works unpreferred single day shift sequence pattern

Employee contract can define several single day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee works the exact sequence of shifts on a particular day, as declared in the rule’s pattern attribute. Number of shifts the employee works on given day needs to match the size of the pattern.

  2. Value of the single day shift sequence pattern rule’s satisfiability attribute is set to UNPREFERRED.

If defined, only shifts containing tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the single day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the single day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeWorksUnpreferredSingleDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequence": {
    "matchElements": [
      {
        "shift": "ICU-Morning",
        "matchType": "MATCH"
      },
      {
        "shift": "ICU-Afternoon",
        "matchType": "MATCH"
      }
    ]
  },
  "patternRule": "MorningAfternoon"
}

4.3.29. Employee works preferred multi day shift sequence pattern

Employee contract can define several multi day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee works the exact sequence of shifts, or day offs, spanning across consecutive days, as declared in the rule’s pattern attribute.

  2. Value of the multi day shift sequence pattern rule’s satisfiability attribute is set to PREFERRED.

If defined, only shifts containing tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the multi day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

In case there are multiple shifts on the same day, use the pattern element’s shiftMatches attribute to define the matching behavior. With shiftMatches set to ALL, all shifts need to match the tag criteria of the pattern element on that particular day. With shiftMatches set to ANY, any shift needs to match the tag criteria of the pattern element on that particular day. The default value of shiftMatches attribute is ALL.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeWorksPreferredMultiDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequences": [
    {
      "matchElements": [
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Late",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Late",
          "matchType": "MATCH"
        }
      ]
    }
  ],
  "patternRule": "EarlyEarlyNightNight"
}

4.3.30. Employee works unpreferred multi day shift sequence pattern

Employee contract can define several multi day shift sequence pattern rules. The constraint triggers if all the conditions below apply:

  1. The employee works the exact sequence of shifts, or day offs, spanning across consecutive days, as declared in the rule’s pattern attribute.

  2. Value of the multi day shift sequence pattern rule’s satisfiability attribute is set to UNPREFERRED.

If defined, only shifts containing tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the multi day shift sequence pattern rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute are included in the sequence. With shiftTagMatches set to ALL, all tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the multi day shift sequence pattern rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, not both. The default value of shiftTagMatches attribute is ALL.

In case there are multiple shifts on the same day, use the pattern element’s shiftMatches attribute to define the matching behavior. With shiftMatches set to ALL, all shifts need to match the tag criteria of the pattern element on that particular day. With shiftMatches set to ANY, any shift needs to match the tag criteria of the pattern element on that particular day. The default value of shiftMatches attribute is ALL.

The rule is more likely to be satisfied for employees with higher employee priority.

Use the constraint configuration’s employeeWorksUnpreferredMultiDayShiftSequencePatternWeight attribute to update the weight of the constraint.

Score analysis justification example:

{
  "matchSequences": [
    {
      "matchElements": [
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Early",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Late",
          "matchType": "MATCH"
        },
        {
          "shift": "ICU-Late",
          "matchType": "MATCH"
        }
      ]
    }
  ],
  "patternRule": "EarlyEarlyNightNight"
}

4.3.31. Minimize travel distance

Schedule parametrization can define travel configuration. The constraint makes sure the distance traveled between employee’s location and shift’s location is minimized.

The constraint triggers if all of the following conditions apply:

  1. Shift’s location is defined.

  2. Employee’s location is defined.

  3. _object_attributes_schedule_parameterization_travel_configuration[Travel configuration] is defined in the schedule parametrization.

If defined, only shifts containing tags defined by the travel configuration’s includeShiftTags attribute are included in the maximum travel distance check. With shiftTagMatches set to ALL, all tags defined by the rule’s includeShiftTags attribute have to be present in the shift. With shiftTagMatches set to ANY, at least one tag defined by the rule’s includeShiftTags attribute has to be present in the shift.

If defined, only shifts not containing tags defined by the travel configuration’s excludeShiftTags attribute are included in the maximum travel distance check. With shiftTagMatches set to ALL, all tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift. With shiftTagMatches set to ANY, any of the tags defined by the rule’s excludeShiftTags attribute cannot be present in the shift.

The rule can define either includeShiftTags or excludeShiftTags, but not both.

Use the constraint configuration’s minimizeTravelDistanceWeight attribute to update the weight of the constraint.

Configuration example to minimize the distance travelled for all shifts.

"travelConfiguration": {
}

Configuration example to minimize the distance travelled for all ICU shifts:

"travelConfiguration": {
    "includeShiftTags": ["ICU"]
}

Configuration example to minimize the distance travelled for all ICU shifts, or Cardiology shifts.

"travelConfiguration": {
    "includeShiftTags": ["ICU", "Cardiology],
    "shiftTagMatches": "ANY"
}

Score analysis justification example:

"justification": {
  "employee": "Ann Green",
  "shift": "ICU-shift-location-A",
  "distanceInMeters": 5500
}

5. Output structure

5.1. Run information

Contains information about the solver run, such as the run identifier and solver status.

"run": {
  "id": "3ffe8e6c-0b09-408b-b610-7550e8e401e6",
  "name": "BASIC",
  "submitDateTime": "2024-05-16T10:00:45.676469+02:00",
  "startDateTime": "2024-05-16T10:00:45.720273+02:00",
  "completeDateTime": null,
  "solverStatus": "SOLVING_ACTIVE",
  "score": "0hard/0medium/-1505soft",
  "tags": []
}

5.2. Model output

Contains solution data, such as shifts and employees assigned to them.

"modelOutput": {
  "shifts": [
    {
      "id": "1",
      "employee": "Elsa Li"
    },
    {
      "id": "2",
      "employee": "Elsa Watt"
    }
  ],
}

6. Additional features

6.1. Score analysis

Use this feature to understand the score structure of your schedule. It provides a detailed breakdown of the score, including the score of each constraint and justifications. Justifications are objects that contribute to violating, or meeting the constraint, for example an employee and two overlapping shifts that are assigned to them. This is especially useful when you want to highlight the violations in your user interface.

The score analysis is automatically calculated and stored at the end of each solver run.

The score analysis endpoint optionally accepts a boolean includeJustifications query parameter to control whether the justifications are included in the response. This can be useful to reduce the response size when you only need a top-level score breakdown.

Example 7. Get score analysis for a schedule without justifications

GET /v1/schedules/{id}/score-analysis

Example 8. Sample score analysis result without justifications
{
  "score": "0hard/-100medium/-600soft",
  "constraints": [
    {
      "name": "Employee is paired with preferred employee",
      "weight": "0hard/0medium/1soft",
      "score": "0hard/0medium/0soft",
      "matches": []
    },
    {
      "name": "Employee works during preferred time",
      "weight": "0hard/0medium/1soft",
      "score": "0hard/0medium/4320soft",
      "matches": []
    }...
Example 9. Get score analysis for a schedule with justifications

GET /v1/schedules/{id}/score-analysis?includeJustifications=true

Example 10. Sample score analysis result including justifications
{
  "score": "0hard/-100medium/-600soft",
  "constraints": [
    {
      "name": "Employee is paired with preferred employee",
      "weight": "0hard/0medium/1soft",
      "score": "0hard/0medium/0soft",
      "matches": []
    },
    {
      "name": "Employee works during preferred time",
      "weight": "0hard/0medium/1soft",
      "score": "0hard/0medium/4320soft",
      "matches": [
        {
          "score": "0hard/0medium/360soft",
          "justification": {
            "shift": "11",
            "employee": "Beth Jones",
            "overlappingTimeSpans": [
              {
                "start": "2024-03-12T00:00:00Z",
                "end": "2024-03-13T00:00:00Z",
                "includeShiftTags": [],
                "excludeShiftTags": [],
                "shiftTagMatches": "ALL"
              }
            ]
          }
        }...

Consider other use case where you have solved a schedule and want to fine tune it manually afterward. For example, assign a shift to a different employee. Use the score analysis to understand the impact of the change on the score and to validate that the new schedule is feasible.

Example 11. Calculate score analysis for a schedule including justifications

POST /v1/schedules/score-analysis?includeJustifications=true

The endpoint accepts a schedule object in the request body.

Example 12. Sample score analysis result
{
  "score": "0hard/0medium/-1200soft",
  "constraints": [
    {
      "name": "Employee is paired with preferred employee",
      "weight": "0hard/0medium/1soft",
      "score": "0hard/0medium/0soft",
      "matches": []
    },
    {
      "name": "Employee works during unpreferred time",
      "weight": "0hard/0medium/1soft",
      "score": "0hard/0medium/-960soft",
      "matches": [
        {
          "score": "0hard/0medium/-480soft",
          "justification": {
            "shift": "177",
            "employee": "Dan Jones21",
            "overlappingTimeSpans": [
                {
                    "start": "2024-03-19T00:00:00Z",
                    "end": "2024-03-20T00:00:00Z",
                    "includeShiftTags": [],
                    "excludeShiftTags": [],
                    "shiftTagMatches": "ALL"
                }
            ]
          }
        }...

6.2. Recommend Employee

Use this feature to react to abrupt changes in daily operations. Consider a case where an unexpected emergency happens, and you need to find an employee to handle it, while respecting the current schedule. The Recommend Employee API allows you to get multiple suggestions on staffing the new shift in a quick way. The employee recommendations are sorted by quality, with the best fit first.

Example 13. Get employee recommendations for a new shift

POST /v1/schedules/{id}/recommendations/recommend-employees

6.2.1. Recommend Employee API input

Description of Recommend Employee API input.

Name Required Format Description Example

Max number of recommendations

true

int

Upper limit for a number of employees to recommend for a new shift.

"maxNumberOfRecommendations": 3

Fit shift id

true

string

Identifier of the shift to get the employee recommendations for. The shift with given identifier needs to be a part of the modelInput schedule.

"fitShiftId": "icu-emergency-10-11-2023"

Config

false

object

Configuration that allows to customize constraint weights.

"config": { "unpreferredEmployeeAssignedWeight": "1" }

Model input

true

object

Model input with schedule that contains shift with identifier specified by fitShiftId attribute.

`"modelInput": { "contracts": [ { "id": "Default Contract", "consecutiveDaysWorkedRules": [ { "minimum": null, "maximum": 6, …​ } `

6.2.2. Recommend Employee API output

Description of Recommend Employee API output.

Name Format Description Example

Score diff

string

Total score difference between the new solution with the fitted shift and the solution without the fitted shift.

"scoreDiff": "0hard/100medium/-480soft"

Constraint diffs

array

Per-constraint score difference between the new solution with the fitted shift and the solution without the fitted shift.

`"constraintDiffs": [ { "score": "0hard/100medium/0soft", "constraintName": "Unassigned shift" }, …​ `

Employee id

string

Identifier of the recommended employee.

`"employeeId": "Amy Smith" `