# Restaurant Scheduling

Consider a restaurant that plans weekly schedules for the kitchen. The
restaurant shifts are Monday through Friday from 12hr to 23hr. There are five
employees that can perform three roles: `Station chef`, `Head chef` and `Sous
chef`. On every shift, there needs to be two employees working as a `Station
chef` with high priority and one employee working as a `Sous chef` with medium
priority. Additionally, a `Head chef` is required on Tuesdays and Fridays with
medium priority. The only other scheduling constraint is for one of the
employees, `Liam`, who requested work on the "Wednesday-2023-05-03", but not to
work on the `Friday-2023-05-05` shift.

## Role coverage for every shift

Coverage for a specific role can be specified for a given set of shifts with a
[coverage requirement](https://developers.google.com/optimization/service/reference/rest/v1/scheduling/solveShiftScheduling#coveragerequirement). For example, the first shift
of this problem can be represented as:

      {
        "shifts": [
          {
            "id": "Monday-2023-05-01",
            "startDateTime": {
              "year": 2023,
              "month": 5,
              "day": 1,
              "hours": 12
            },
            "endDateTime": {
              "year": 2023,
              "month": 5,
              "day": 1,
              "hours": 23
            }
          }
        ]
      }

Assuming all five shifts are: `Monday-2023-05-01`, `Tuesday-2023-05-02`,
`Wednesday-2023-05-03`, `Thursday-2023-05-04`, and `Friday-2023-05-05`, the
coverage requirement for the `Station chef` and `Sous chef` roles is represented
as:

    {
      "coverageRequirements": [{
          "shiftIds": ["Monday-2023-05-01", "Tuesday-2023-05-02",
                      "Wednesday-2023-05-03", "Thursday-2023-05-04",
                      "Friday-2023-05-05"]
          "roleRequirements": [{
            "roleId": "Station chef",
            "targetEmployeeCount": 2,
            "priority": "PRIORITY_HIGH"
          }, {
            "roleId": "Sous chef",
            "targetEmployeeCount": 1,
            "priority": "PRIORITY_MEDIUM"
          }]
        }
      ]
    }

To consider the requirement for a `Head chef`, an additional coverage
requirement can be specified on the necessary shifts. The complete list of
coverage requirements is:

    {
      "coverageRequirements": [{
          "shiftIds": ["Monday-2023-05-01", "Tuesday-2023-05-02",
                      "Wednesday-2023-05-03", "Thursday-2023-05-04",
                      "Friday-2023-05-05"],
          "roleRequirements": [{
            "roleId": "Station chef",
            "targetEmployeeCount": 2,
            "priority": "PRIORITY_HIGH"
          }, {
            "roleId": "Sous chef",
            "targetEmployeeCount": 1,
            "priority": "PRIORITY_MEDIUM"
          }]
        },
        {
          "shiftIds": ["Tuesday-2023-05-02", "Friday-2023-05-05"],
          "roleRequirements": [{
            "roleId": "Head chef",
            "targetEmployeeCount": 1,
            "priority": "PRIORITY_MEDIUM"
          }]
        }
      ]
    }

## Employee requests

Employee requests are represented with the [shift request](https://developers.google.com/optimization/service/reference/rest/v1/scheduling/solveShiftScheduling#shiftrequest)
field. In this example, `Liam` has requested to work on the Wednesday shift, but
**not** to work on the Friday shift. This is represented (along with his roles)
as:

    {
      "employees": [{
        "id": "Liam",
        "roleIds": ["Station chef", "Head chef"],
        "shiftRequests": [
          {
            "priority": "PRIORITY_HIGH",
            "shiftIds": ["Wednesday-2023-05-03"],
            "type": "STATUS_WORK"
          },
          {
            "priority": "PRIORITY_HIGH",
            "shiftIds": ["Friday-2023-05-05"],
            "type": "STATUS_NOT_WORK"
          }
        ]
      }]
    }

#### Example with all five employees


      {
        "employees": [
          {
            "id": "Liam",
            "roleIds": [
              "Station chef",
              "Head chef"
            ],
            "shiftRequests": [
              {
                "priority": "PRIORITY_HIGH",
                "shiftIds": [
                  "Wednesday-2023-05-03"
                ],
                "type": "STATUS_WORK"
              },
              {
                "priority": "PRIORITY_HIGH",
                "shiftIds": [
                  "Friday-2023-05-05"
                ],
                "type": "STATUS_NOT_WORK"
              }
            ]
          }
          , {
            "id": "Olivia",
            "roleIds": ["Station chef"]
          }, {
            "id": "Noah",
            "roleIds": ["Station chef"]
          }, {
            "id": "Emma",
            "roleIds": ["Head chef"]
          }, {
            "id": "Oliver",
            "roleIds": ["Station chef", "Sous chef"]
          }
        ]
      }
      
#### Example of a complete request


      {
        "employees": [
          {
            "id": "Liam",
            "roleIds": [
              "Station chef",
              "Head chef"
            ],
            "shiftRequests": [
              {
                "priority": "PRIORITY_HIGH",
                "shiftIds": [
                  "Wednesday-2023-05-03"
                ],
                "type": "STATUS_WORK"
              },
              {
                "priority": "PRIORITY_HIGH",
                "shiftIds": [
                  "Friday-2023-05-05"
                ],
                "type": "STATUS_NOT_WORK"
              }
            ]
          },
          {
            "id": "Olivia",
            "roleIds": [
              "Station chef"
            ]
          },
          {
            "id": "Noah",
            "roleIds": [
              "Station chef"
            ]
          },
          {
            "id": "Emma",
            "roleIds": [
              "Head chef"
            ]
          },
          {
            "id": "Oliver",
            "roleIds": [
              "Station chef",
              "Sous chef"
            ]
          }
        ],
        "shifts": [
          {
            "id": "Monday-2023-05-01",
            "startDateTime": {
              "year": 2023,
              "month": 5,
              "day": 1,
              "hours": 12
            },
            "endDateTime": {
              "year": 2023,
              "month": 5,
              "day": 1,
              "hours": 23
            }
          },
          {
            "id": "Tuesday-2023-05-02",
            "startDateTime": {
              "year": 2023,
              "month": 5,
              "day": 2,
              "hours": 12
            },
            "endDateTime": {
              "year": 2023,
              "month": 5,
              "day": 2,
              "hours": 23
            }
          },
          {
            "id": "Wednesday-2023-05-03",
            "startDateTime": {
              "year": 2023,
              "month": 5,
              "day": 3,
              "hours": 12
            },
            "endDateTime": {
              "year": 2023,
              "month": 5,
              "day": 3,
              "hours": 23
            }
          },
          {
            "id": "Thursday-2023-05-04",
            "startDateTime": {
              "year": 2023,
              "month": 5,
              "day": 4,
              "hours": 12
            },
            "endDateTime": {
              "year": 2023,
              "month": 5,
              "day": 4,
              "hours": 23
            }
          },
          {
            "id": "Friday-2023-05-05",
            "startDateTime": {
              "year": 2023,
              "month": 5,
              "day": 5,
              "hours": 12
            },
            "endDateTime": {
              "year": 2023,
              "month": 5,
              "day": 5,
              "hours": 23
            }
          }
        ],
        "coverageRequirements": [
          {
            "shiftIds": [
              "Monday-2023-05-01",
              "Tuesday-2023-05-02",
              "Wednesday-2023-05-03",
              "Thursday-2023-05-04",
              "Friday-2023-05-05"
            ],
            "roleRequirements": [
              {
                "roleId": "Station chef",
                "targetEmployeeCount": 2,
                "priority": "PRIORITY_HIGH"
              },
              {
                "roleId": "Sous chef",
                "targetEmployeeCount": 1,
                "priority": "PRIORITY_MEDIUM"
              }
            ]
          },
          {
            "shiftIds": [
              "Tuesday-2023-05-02",
              "Friday-2023-05-05"
            ],
            "roleRequirements": [
              {
                "roleId": "Head chef",
                "targetEmployeeCount": 1,
                "priority": "PRIORITY_MEDIUM"
              }
            ]
          }
        ],
        "roleIds": [
          "Station chef",
          "Head chef",
          "Sous chef"
        ]
      }
      
## Response example

The response of the solver contains the assignment of employees to the
restaurant shifts and the status of the optimization procedure. For example, the
shifts assigned to one of the employees are returned as:

    {
      "solutionStatus": "OPTIMAL",
      "shiftAssignments": [
        {
          "employeeId": "Liam",
          "shiftId": "Monday-2023-05-01",
          "roleId": "Station chef"
        },
        {
          "employeeId": "Liam",
          "shiftId": "Tuesday-2023-05-02",
          "roleId": "Station chef"
        },
        {
          "employeeId": "Liam",
          "shiftId": "Wednesday-2023-05-03",
          "roleId": "Station chef"
        },
        {
          "employeeId": "Liam",
          "shiftId": "Thursday-2023-05-04",
          "roleId": "Station chef"
        }, ...
      ]
    }

#### Example of a complete response


      {
        "solutionStatus": "OPTIMAL",
        "shiftAssignments": [
          {
            "employeeId": "Liam",
            "shiftId": "Monday-2023-05-01",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Liam",
            "shiftId": "Tuesday-2023-05-02",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Liam",
            "shiftId": "Wednesday-2023-05-03",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Liam",
            "shiftId": "Thursday-2023-05-04",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Olivia",
            "shiftId": "Friday-2023-05-05",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Noah",
            "shiftId": "Monday-2023-05-01",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Noah",
            "shiftId": "Tuesday-2023-05-02",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Noah",
            "shiftId": "Wednesday-2023-05-03",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Noah",
            "shiftId": "Thursday-2023-05-04",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Noah",
            "shiftId": "Friday-2023-05-05",
            "roleId": "Station chef"
          },
          {
            "employeeId": "Emma",
            "shiftId": "Tuesday-2023-05-02",
            "roleId": "Head chef"
          },
          {
            "employeeId": "Emma",
            "shiftId": "Friday-2023-05-05",
            "roleId": "Head chef"
          },
          {
            "employeeId": "Oliver",
            "shiftId": "Monday-2023-05-01",
            "roleId": "Sous chef"
          },
          {
            "employeeId": "Oliver",
            "shiftId": "Tuesday-2023-05-02",
            "roleId": "Sous chef"
          },
          {
            "employeeId": "Oliver",
            "shiftId": "Wednesday-2023-05-03",
            "roleId": "Sous chef"
          },
          {
            "employeeId": "Oliver",
            "shiftId": "Thursday-2023-05-04",
            "roleId": "Sous chef"
          },
          {
            "employeeId": "Oliver",
            "shiftId": "Friday-2023-05-05",
            "roleId": "Sous chef"
          }
        ]
      }