> ## Documentation Index
> Fetch the complete documentation index at: https://docs.automaticrostering.visma.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Shifts

> Learn how to define the shifts that employees can be assigned to cover demand.

Shifts specify the different kinds of working hour assignments that employees may receive. In any solution produced by the solver, employees will only receive working hours by being assigned to any of the possible Shifts. This page will give some pointers on how to define Shifts in your payload.

<Card title="Shift schema">
  <ResponseField name="shift" type="object">
    <Expandable title="properties">
      <ResponseField name="id" type="string" required>
        Unique identifier for the shift.
      </ResponseField>

      <ResponseField name="labels" type="array of string">
        List of labels assigned to this shift. Labels can be used in rules to group shifts.
      </ResponseField>

      <ResponseField name="isReadOnly" type="boolean">
        If set to true, the shift will not be assigned by us. Read only shifts will not be used in new assignments by us, their use is limited to preassigned shifts. Read only shifts can still be used to cover demand. Default: false.
      </ResponseField>

      <ResponseField name="canCoverDemand" type="boolean">
        Only relevant for preassigned shifts. If set to false, assignments of this shift will not contribute towards demand coverage. Shifts that cannot cover demand will not be used in new assignments by us, their use is limited to preassigned shifts. Default: true.
      </ResponseField>

      <ResponseField name="availableDays" type="object">
        List of days in the schedule.
      </ResponseField>

      <Expandable title="availableDays – properties">
        <ResponseField name="dates" type="array of date (date)">
          List of dates in the schedule. Only allowed in CALENDAR payloads.
        </ResponseField>

        <ResponseField name="dayIndices" type="array of dayIndex">
          List of day indices in the schedule. Only allowed in RECURRING payloads.
        </ResponseField>

        <ResponseField name="daysOfWeek" type="array of dayOfWeek">
          List of days of the week. Will apply to all days in the schedule that match any of the specified weekdays.
        </ResponseField>
      </Expandable>

      <ResponseField name="intervals" type="array of object" required>
        List of intervals that this shift consists of. The maximum duration of a shift is 72 hours.
      </ResponseField>

      <Expandable title="intervals – item structure">
        <ResponseField name="startTime" type="string (time)" required>
          TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
        </ResponseField>

        <ResponseField name="endTime" type="string (time)" required>
          TIME ISO 8601 format hh:mm. Equivalent to the 24h format of a single day. Use 00:00 to represent midnight.
        </ResponseField>

        <ResponseField name="dayIndicator" type="integer" required>
          Indicates which day this interval belongs to, relative to the day that the shift belongs to. -1 indicates the interval starts on the previous day, 0 on the same day, and 1 on the next day.
        </ResponseField>

        <ResponseField name="workload" type="object" />

        <Expandable title="workload – properties">
          <ResponseField name="factor" type="number">
            Factor by which the hours of this interval will be multiplied to calculate the total FTE hours of an employee. Default: 1.
          </ResponseField>

          <ResponseField name="category" type="string">
            Category of work carried out during the interval. Only relevant if using TIME\_DEMAND.
          </ResponseField>
        </Expandable>

        <ResponseField name="breakMinutes" type="integer">
          Minutes of break in this interval. We do not plan the break at any specific time, but the break minutes are subtracted from the total FTE for the shift. Default: 0.
        </ResponseField>

        <ResponseField name="taskId" type="string">
          Task id of the task that must be worked on during this interval. The task needs to be defined in the configuration part of the payload.
        </ResponseField>
      </Expandable>

      <ResponseField name="attributeRequirements" type="array of object">
        List of requirements on the attributes that an employee needs to be eligible to work this Shift. If an employee does not meet all of the requirements, the employee can not work this Shift.
      </ResponseField>

      <Expandable title="attributeRequirements – item structure">
        <ResponseField name="category" type="string">
          The category of the attribute.
        </ResponseField>

        <ResponseField name="values" type="array of string">
          The targeted values for this requirement.
        </ResponseField>

        <ResponseField name="matchType" type="string (enum: NONE | ANY | ALL)">
          Default: "ALL".
        </ResponseField>
      </Expandable>
    </Expandable>
  </ResponseField>
</Card>

<Info>
  By default, shifts may be used (assigned to employees) an unlimited amount of
  times in schedules produced by the solver. If you would like to specify
  exactly how many times the assignments of certain shifts is needed, see
  ShiftDemand.
</Info>

## Intervals

At its core, a shift is built up out of one or more `intervals`. Whenever a shift is assigned to an `employee`, that employee will work all of the intervals in the shift. Intervals must have a start- and end time that both fall within the same day, and the intervals of one shift must all fall within a maximum span of 72 hours (across no more than 3 distinct days). To specify that an interval is to take place a day before or a day after the day on which the shift is planned, the `dayIndicator` property can be used. The different intervals of a shift may not overlap one another.

<Tip>
  Consider a 6-hour Shift that starts on 20:00 and lasts until 02:00. This can be covered using Shift Intervals in one of two ways:

  * The Shift contains an interval from 20:00-00:00 with `dayIndicator` -1, and an interval from 00:00-02:00 with `dayIndicator` 0. When planning any instances of this Shift, it will be considered to belong to the second day.
  * The Shift contains an interval from 20:00-00:00 with `dayIndicator` 0, and an interval from 00:00-02:00 with `dayIndicator` 1. When planning any instances of this Shift, it will be considered to belong to the first day.

  .
</Tip>

### Breaks

It is possible to specify the amount of `breakMinutes` any interval contains. The break is not considered to happen at any specific time, this is only used to correctly determine the employee's FTE. A shift interval of 8 hours with a 1-hour break is considered to count for 7 worked hours.

## Day assignments

In the schedules created by the solver, Shifts are assigned to employees on days within the planning period. Shift assignments are always considered to belong to one specific day, even if the Shift contains working hours on the previous or next day. It is possible to specify specific days in the planning period on which a Shift may be assigned to employees. By default, the entire planning period is allowed. Alternatively, it is possible to specify which weekdays are available for a Shift.

<Tip>
  Consider the following example for a two-week planning period. `shift-1` shifts may only be assigned on Mondays, Tuesdays, and Wednesdays, while `shift-2` shifts may only be planned on the first three or the last three days of the period.

  ```json theme={null}
  [
    {
      "id": "shift-1",
      "intervals": [
        {
          "startTime": "09:00",
          "endTime": "17:00",
          "dayIndicator": 0
        }
      ],
      "availableDays": {
        "daysOfWeek": ["MON", "TUE", "WED"]
      }
    },
    {
      "id": "shift-2",
      "intervals": [
        {
          "startTime": "13:00",
          "endTime": "21:00",
          "dayIndicator": 0
        }
      ],
      "availableDays": {
        "dayIndices": [0, 1, 2, 11, 12, 13]
      }
    }
  ]
  ```
</Tip>

## Preassigned shifts

If there are certain shift assignments for employees that are already fixed, it is recommended to include these in the request. This way, the solver can take into account which hours an employee is already working and ensure the produced schedule is feasible given the already existing assignments.

However, it can occur that this means you have to send in a Shift definition that you do not want to be used by the solver to make new assignments - only to explain what kind of shift the employee is working in the already fixed assignment. For this purpose, it is possible to mark a Shift as `isReadOnly`. The solver will then not use it to make new assignments.

<Warning>
  An employee cannot be preassigned to multiple locked shifts on the same day,
  or to overlapping locked shifts.
</Warning>
