openapi: 3.0.3
x-zally-ignore:
  - 224
  - 240
info:
  title: Order Communication Dispatcher API
  version: 1.0.0
  x-audience: external-partner
  x-api-id: 29ec86a0-1537-43d0-8753-a3a0ad83e662
  description: "This API can be used to track a `Tour`, to guide the driver through\
    \ a tour, and to communicate the execution of the\ntour back to the dispatcher.\n\
    \n## Taxonomy\n\n### Tour and tour stops\n\n* A `Tour` describes the movement\
    \ of a `MeansOfTransport` from an origin to a destination\n  via several `Stop`s.\
    \ It fulfills the transportation of goods described in `TransportOrder`s or services\
    \ described\n  in `ServiceOrder`s.\n* A `Stop` is defined by a `Location` and\
    \ a planned arrival time at which the `MeansOfTransport` is stopped to unload\n\
    \  or load the goods from or onto the `MeansOfTransport`.\n\n### Service orders\n\
    \n* A `ServiceOrder` describes an additional order to the `Driver` like refueling\
    \ at a specific gas station or\n  resting at a parking space.\n\n### Transport\
    \ orders\n\n* A `TransportOrder` describes the transportation of `Goods` from\
    \ one `Location` to another by one\n  `MeansOfTransport`.\n* A `MeansOfTransport`\
    \ describes the vehicle running the `Tour`, like a truck or a van.\n* `Goods`\
    \ are all items that are included in a `TransportOrder`, and can be either cargo\
    \ (a collection of \n  `HandlingUnit`s), or one of more trailers (`CustomerTrailer`)\
    \ being pulled.\n* A `Handling Unit` is a packaging container, which contains\
    \ `Article` items.\n  A `Handling Unit` has some physical properties: for example\
    \ dimension (width, height, depth), \n  weight, or stacking factor.\n* A `CustomerTrailer`\
    \ consists of a chain of `TrailerUnit`s coupled together, each of which can have\
    \ its \n  unique license plate.\n* A `BulkMaterial` describes goods that are not\
    \ contained in a `HandlingUnit`, for example gravel or sand.\n* As soon as a `Tour`\
    \ is started and a `TransportOrder` is loaded, it must be unloaded at any following\
    \ `Stop` \n  before the `Tour` is finished.\n  In the situation where a `TransportOrder`\
    \ has been loaded and the unloading `Stop` should be removed, then the \n  `TransportOrder`\
    \ must be referenced in an existing or new unreached stop.  \n\n### Tour problems\n\
    \n* A `TourProblem` describes a problem reported by the `Driver` while running\
    \ the `Tour` that they wish to\n  communicate to the `Dispatcher`. After the problem\
    \ is resolved, it must be acknowledged by the `Dispatcher`.\n\n### Confirmations\n\
    \n* A `Confirmation` delivers an update regarding the state of an active `Tour`,\
    \ `TourStop`, or `TourProblem`.\n  `Confirmation`s can include:\n  - the acknowledgement\
    \ of a `TourProblem` by the `Dispatcher` \n\n### Documents\n\n* A `Document` describes\
    \ a file attached to the tour.\n* `Document`s can be added by the `Dispatcher`\
    \ to provide additional information (e.g. directions) to the `Driver`\n  or they\
    \ can be added by the `Driver` e.g. to proof the handling of `Goods`.\n* It is\
    \ associated with a `Tour` and `Account`. In addition, it can reference certain\
    \ parts of a tour, such as\n  a certain `Stop` (e.g. proof of loading) or a `Problem`\
    \ (e.g. photo of damage dealt to the transport vehicle)\n* A `File` is the actual\
    \ binary data referenced by a `Document`.\n\n### Roles\n\n* The `Dispatcher` is\
    \ responsible for planning the `Tour`s of a `Driver`. They are interested in the\
    \ current state\n  of the `Tour`, whether it is running late or there are any\
    \ `TourProblem`s.\n\n* A `Driver` receives the `Tour` on his device and is running\
    \ the `Tour`.\n"
  contact:
    name: rio-team-rio-transport-one
    url: https://rio.cloud/
    email: rio_team_transport_one@rio.cloud
servers:
  - url: https://order-communication.tour-tracking.rio.cloud
tags:
  - name: Tours
    description: "Endpoints for creation, update and deletion of tours"
  - name: Tour problems
    description: Endpoints for confirmation of problems
  - name: Confirmations
    description: Endpoints for creating confirmations on tours and tours stops
  - name: Tour documents
    description: Endpoints for managing tour documents
  - name: Tour events
    description: Endpoints for querying tour events
  - name: Tour files
    description: System internal endpoints for managing tour files
paths:
  /tours:
    get:
      summary: "Returns a list of tours based on the bearer of the token. \nIf the\
        \ bearer is a driver, only tours that belong to the driver are returned.\n\
        If it's not a driver and an asset id is given, only tours that belong to the\
        \ asset are returned.\nIf it's not a driver and no asset id is given, no tours\
        \ are returned.\n"
      tags:
        - Tours
      parameters:
        - $ref: "#/components/parameters/asset_id"
        - $ref: "#/components/parameters/include_finished"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/cursor"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TourCursor"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: Request is forbidden due to insufficient scopes
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.read
  /tours/{tour-id}:
    get:
      summary: Returns a single tour for a given tour id
      tags:
        - Tours
      parameters:
        - $ref: "#/components/parameters/tour-id"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Tour"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "404":
          description: |
            The tour does not exist for this asset or driver
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.read
    put:
      summary: Creates or updates a tour
      tags:
        - Tours
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/if_none_match"
        - $ref: "#/components/parameters/if_match"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WriteTour"
      responses:
        "201":
          description: Indicates that the request has succeeded and has led to the
            creation of a resource
        "204":
          description: Indicates that the request has succeeded and has led to the
            update of a resource
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "404":
          description: Requested resource is not found
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "409":
          description: "Request payload is formatted correctly but cannot be processed\
            \ due to a resource conflict (e.g. a transport \nresource being assigned\
            \ to multiple simultaeous tours)\n"
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "412":
          description: Creation or update of a resource failed due to unsatisfied
            precondition
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "415":
          description: Request payload has a media type not supported by the service
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: "Request payload is formatted correctly but cannot be processed\
            \ because it conflicts with internal logic \n(e.g. trying to start a tour\
            \ that is already finished)\n"
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
    delete:
      summary: Deletes a tour
      description: |
        On successful deletion, a Kafka event is emitted. The tour is deleted immediately and new tours with the same id can be created.
      tags:
        - Tours
      parameters:
        - $ref: "#/components/parameters/tour-id"
      responses:
        "204":
          description: Indicates that tour was deleted
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: "Request payload is formatted correctly but cannot be processed\
            \ because it conflicts with internal logic \n(e.g. trying to delete a\
            \ tour that is currently being executed)\n"
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/finish:
    post:
      summary: Finishes a tour
      description: |
        On successful finish, a Kafka event of type `tour-finished` is emitted.
      tags:
        - Tours
      parameters:
        - $ref: "#/components/parameters/tour-id"
      responses:
        "204":
          description: Indicates that tour was finished
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: "Request payload is formatted correctly but cannot be processed\
            \ because it conflicts with internal logic \n(e.g. trying to finish a\
            \ tour that is already finished)\n"
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/messages:
    post:
      summary: Accepts LISTrac messages to manage tours
      requestBody:
        content:
          application/vnd.listrac+json:
            schema:
              $ref: "#/components/schemas/LisMessageWrapper"
      responses:
        "204":
          description: Successfully processed payload
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: "Request payload is formatted correctly but cannot be processed\
            \ because it conflicts with internal logic \n(e.g. trying to confirm a\
            \ problem that is not associated with this tour)\n"
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/problems/{problem-id}/confirmations:
    post:
      summary: "Creates a confirmation for a tour problem, for example, that it has\
        \ been resolved by the dispatcher"
      tags:
        - Tour problems
        - Confirmations
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/problem-id"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TourProblemConfirmation"
      responses:
        "204":
          description: Successfully created a tour problem confirmation
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "404":
          description: Resource cannot be found
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: "Request payload is formatted correctly but cannot be processed\
            \ because it conflicts with internal logic \n(e.g. trying to confirm a\
            \ problem that is not associated with this tour)\n"
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/documents:
    get:
      summary: Get documents associated with the given tour
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
      responses:
        "200":
          description: Successfully retrieved a `DocumentList`
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentList"
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.read
  /tours/{tour-id}/documents/{document-id}:
    put:
      summary: Upload document data for this tour and document
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/document-id"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WriteDocument"
      responses:
        "204":
          description: Successfully updated a `Document`
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: |
            Request payload is formatted correctly but cannot be processed because it conflicts with internal logic
            (e.g. maximum number of allowed documents associated with this tour is exceeded)
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
    delete:
      summary: Delete document data for this tour and document
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/document-id"
      responses:
        "204":
          description: Successfully deleted a `Document`
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "404":
          description: |
            The tour or document does not exist
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: |
            Request payload is formatted correctly but cannot be processed because it conflicts with internal logic
            (e.g. maximum number of allowed documents associated with this tour is exceeded)
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/service-orders/{service-order-id}/documents/{document-id}:
    put:
      summary: Upload document data for this service order and document
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/service-order-id"
        - $ref: "#/components/parameters/document-id"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WriteDocument"
      responses:
        "204":
          description: Successfully updated a `Document`
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: |
            Request payload is formatted correctly but cannot be processed because it conflicts with internal logic
            (e.g. maximum number of allowed documents associated with this service order is exceeded)
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/transport-orders/{transport-order-id}/documents/{document-id}:
    put:
      summary: Upload document data for this transport order and document
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/transport-order-id"
        - $ref: "#/components/parameters/document-id"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WriteDocument"
      responses:
        "204":
          description: Successfully updated a `Document`
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: |
            Request payload is formatted correctly but cannot be processed because it conflicts with internal logic
            (e.g. maximum number of allowed documents associated with this transport order is exceeded)
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/stops/{tour-stop-id}/documents/{document-id}:
    put:
      summary: Upload document data for this tour stop and document
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/tour-stop-id"
        - $ref: "#/components/parameters/document-id"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WriteDocument"
      responses:
        "204":
          description: Successfully updated a `Document`
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "422":
          description: |
            Request payload is formatted correctly but cannot be processed because it conflicts with internal logic
            (e.g. maximum number of allowed documents associated with this tour stop is exceeded)
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/files/{file-name}/upload:
    get:
      summary: |
        Generate and get upload link for a file. The link can be used for a `HTTP PUT` request to upload the file.
        The file will be automatically deleted 60 days after its upload.
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/file-name"
        - in: query
          name: fileType
          schema:
            type: string
            enum:
              - image/jpeg
              - application/pdf
          description: |
            The actual type of the file that will be uploaded using presigned URL.
            The specified `fileType` will be used to create a presigned URL with an expected `Content-Type` HTTP header.
            When uploading the file using presigned URL, the client must set the `Content-Type` header with the value specified by `fileType`.
            If the `Content-Type` HTTP header of the actual upload matches, the request succeeds.
            This query string parameter is optional for backwards-compatibility, but will be required in future iterations.
        - in: query
          name: fileSize
          schema:
            type: integer
            maximum: 10000000
          description: |
            The actual size of the file in bytes that will be uploaded using presigned URL.
            The specified `fileSize` will be used to create a presigned URL with an expected `Content-Length` HTTP header.
            When uploading the file using presigned URL, the client must set the `Content-Length` header with the value specified by `fileSize`.
            If the `Content-Length` HTTP header of the actual upload matches, the request succeeds.
            Maximum allowed value is 10000000 (10 Mb).
            This query string parameter is optional for backwards-compatibility, but will be required in future iterations.
      responses:
        "200":
          description: |
            Link for file upload. The upload link contains a signature that is valid for 15 minutes.
            If the link signature expires, a new link can be requested.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FileLink"
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.write
  /tours/{tour-id}/files/{file-name}/download:
    get:
      summary: |
        Generate and get download link for a file. The link can be used for an `HTTP GET` request to download the file.
      tags:
        - Tour documents
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/file-name"
      responses:
        "200":
          description: |
            Link for file download. The download link contains a signature that is valid for 15 minutes.
            If the link signature expires, a new link can be requested.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FileLink"
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "404":
          description: |
            Download link cannot be generated because the file does not exist.
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.read
  /accounts/{account-id}/tours/{tour-id}/files/{file-name}/download:
    get:
      summary: |
        Provides a presigned download link for a file associated with the specified
        tour and account.
      tags:
        - Tour files
      parameters:
        - $ref: "#/components/parameters/account-id"
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/file-name"
      responses:
        "200":
          description: |
            Link for file download. The download link contains a signature that is
            valid for 15 minutes. If the link signature expires, a new link can be
            requested.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FileLink"
        "400":
          description: Request is malformed and cannot be processed
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester does
            not have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "404":
          description: Download link cannot be generated because the file does not
            exist
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.file.read
  /tours/events:
    get:
      summary: Returns a list of tour events for all tours of the requesting account
      tags:
        - Tour events
      parameters:
        - $ref: "#/components/parameters/from_date"
        - $ref: "#/components/parameters/to_date"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/cursor"
      responses:
        "200":
          description: OK
          content:
            application/vnd.listrac+json:
              schema:
                $ref: "#/components/schemas/LisMessageWrapperListCursor"
            application/json:
              schema:
                $ref: "#/components/schemas/TourEventListCursor"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.read
  /tours/{tour-id}/events:
    get:
      summary: Returns a list of tour events of the given tour
      tags:
        - Tour events
      parameters:
        - $ref: "#/components/parameters/tour-id"
        - $ref: "#/components/parameters/from_date"
        - $ref: "#/components/parameters/to_date"
        - $ref: "#/components/parameters/limit"
        - $ref: "#/components/parameters/cursor"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TourEventListCursor"
        "401":
          description: Request is unauthorized
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "403":
          description: |
            Request is forbidden due to insufficient scopes or the requester doesn't have access to this tour
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        "404":
          description: |
            Tour cannot be found
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
        default:
          description: Default response
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
      security:
        - oauth2:
            - tour.read
components:
  parameters:
    if_none_match:
      name: If-None-Match
      in: header
      required: false
      description: |
        Used to create an initial resource. If the provided value is `*`, it is required that the resource does not exist at all. For more information, refer to https://opensource.zalando.com/restful-api-guidelines/#182
      schema:
        type: string
        example: '*'
    if_match:
      name: If-Match
      in: header
      required: false
      description: |
        Used to update an already existing resource. The backend only operates on the resource if the current etag of that resource matches the provided value. For more information, refer to https://opensource.zalando.com/restful-api-guidelines/#182
      schema:
        type: string
        example: null
    account-id:
      in: path
      name: account-id
      description: The accountId of the requesting user
      required: true
      schema:
        $ref: "#/components/schemas/IdString"
    tour-id:
      in: path
      name: tour-id
      description: The id of the `Tour` for which to retrieve or update data.
      required: true
      schema:
        $ref: "#/components/schemas/IdString"
    tour-stop-id:
      in: path
      name: tour-stop-id
      description: The id of the `TourStop` for which to retrieve or update data.
      required: true
      schema:
        $ref: "#/components/schemas/IdString"
    service-order-id:
      in: path
      name: service-order-id
      description: The id of the `ServiceOrder` for which to retrieve or update data.
      required: true
      schema:
        $ref: "#/components/schemas/IdString"
    transport-order-id:
      in: path
      name: transport-order-id
      description: The id of the `TransportOrder` for which to retrieve or update
        data.
      required: true
      schema:
        $ref: "#/components/schemas/IdString"
    problem-id:
      in: path
      name: problem-id
      description: The id of the `TourProblem` for which to retrieve or update data.
      required: true
      schema:
        $ref: "#/components/schemas/IdString"
    document-id:
      in: path
      name: document-id
      description: The id of the `Document` for which manages a file.
      required: true
      schema:
        $ref: "#/components/schemas/IdString"
    file-name:
      in: path
      name: file-name
      description: The name of the `File` for which to retrieve or update a file.
      required: true
      schema:
        type: string
    asset_id:
      in: query
      name: asset_id
      description: The asset id of the `MeansOfTransport` for which to retrieve data.
      schema:
        $ref: "#/components/schemas/IdString"
    include_finished:
      in: query
      name: include_finished
      description: Determines if tours in response will be filtered to include finished
        tours.
      schema:
        type: boolean
        default: true
    from_date:
      in: query
      name: from_date
      description: The start date of the query
      required: false
      example: 2023-10-27T13:53:28Z
      schema:
        type: string
        format: date-time
    to_date:
      in: query
      name: to_date
      description: The end date of the query
      required: false
      example: 2023-10-27T13:53:28Z
      schema:
        type: string
        format: date-time
    limit:
      in: query
      name: limit
      description: Limit the number of returned resources in list
      example: 30
      required: false
      schema:
        type: integer
    cursor:
      in: query
      name: cursor
      description: "A cursor for pagination. Is either an identifier or a composite\
        \ identifier, base64 encoded."
      required: false
      schema:
        type: string
      example: 84f92a7c-6d81-406d-a636-d7be425fb4df
  securitySchemes:
    oauth2:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://auth.iam.rio.cloud/oauth/token
          scopes:
            tour.read: Read access to `Tour`s
            tour.write: Write access to `Tour`s
            tour.file.read: System-to-system read/download of tour files
  schemas:
    WriteTour:
      type: object
      description: The plan data of a `Tour`.
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        external_id:
          type: string
          example: ABC123
          description: |
            Identifier for this tour in an external transport or tour management  system connecting to this service.
        name:
          type: string
          example: My Test Tour From A To B
        account_id:
          $ref: "#/components/schemas/IdString"
        note:
          type: string
          description: |
            A tour specific note is a free-text field set by the dispatcher to inform drivers about additional instructions.
          example: Ensure all cargo is securely loaded and double-check the delivery
            addresses before departure.
        means_of_transport:
          $ref: "#/components/schemas/MeansOfTransport"
        trailer:
          $ref: "#/components/schemas/Trailer"
        drivers:
          type: array
          items:
            type: string
            description: Driver ID
        service_orders:
          type: array
          items:
            $ref: "#/components/schemas/WriteServiceOrder"
        transport_orders:
          type: array
          items:
            $ref: "#/components/schemas/WriteTransportOrder"
        stops:
          type: array
          items:
            $ref: "#/components/schemas/WriteTourStop"
        additional_customer_data:
          $ref: "#/components/schemas/AdditionalCustomerData"
      required:
        - id
        - account_id
        - stops
    Tour:
      type: object
      description: Both the plan data and execution data of a `Tour`.
      allOf:
        - $ref: "#/components/schemas/WriteTour"
        - properties:
            status:
              $ref: "#/components/schemas/TourStatus"
            service_orders:
              type: array
              items:
                $ref: "#/components/schemas/ServiceOrder"
            transport_orders:
              type: array
              items:
                $ref: "#/components/schemas/TransportOrder"
            means_of_transport:
              $ref: "#/components/schemas/MeansOfTransport"
            stops:
              type: array
              items:
                $ref: "#/components/schemas/TourStop"
            problems:
              $ref: "#/components/schemas/TourProblems"
            documents:
              $ref: "#/components/schemas/Documents"
            seen_at:
              $ref: "#/components/schemas/Timestamp"
            started_at:
              $ref: "#/components/schemas/Timestamp"
            finished_at:
              $ref: "#/components/schemas/Timestamp"
            etag:
              type: string
              example: 1
          required:
            - drivers
            - status
            - etag
      readOnly: true
    TourCursor:
      type: object
      description: A list of `Tour`s with pagination data.
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Tour"
        next:
          type: string
    WriteTourStop:
      type: object
      description: A stop that is executed as part of a tour.
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        external_id:
          type: string
          example: ABC123
          description: |
            Identifier for this stop in an external transport or tour management  system connecting to this service.
        planned_arrival_at:
          description: The planned time of arrival at the tour stop.
          allOf:
            - $ref: "#/components/schemas/Timestamp"
        planned_departure_at:
          description: The planned time of departure from the tour stop.
          allOf:
            - $ref: "#/components/schemas/Timestamp"
        location:
          $ref: "#/components/schemas/Location"
        additional_customer_data:
          $ref: "#/components/schemas/AdditionalCustomerData"
        load:
          type: array
          items:
            $ref: "#/components/schemas/OrderHandle"
        unload:
          type: array
          items:
            $ref: "#/components/schemas/OrderHandle"
        execute:
          type: array
          items:
            $ref: "#/components/schemas/OrderHandle"
      required:
        - id
        - planned_arrival_at
        - planned_departure_at
        - location
    TourStop:
      allOf:
        - $ref: "#/components/schemas/WriteTourStop"
        - properties:
            documents:
              $ref: "#/components/schemas/Documents"
            reached_at:
              description: The time the stop was reached at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            unloading_started_at:
              description: The time the unloading was started at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            unloading_finished_at:
              description: The time the unloading was finished at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            loading_started_at:
              description: The time the loading was started at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            loading_finished_at:
              description: The time the loading was finished at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            execution_started_at:
              description: The time the execution of the service orders was started
                at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            execution_finished_at:
              description: The time the execution of the service orders was finished
                at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            finished_at:
              description: The time the stop was finished at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            added_at:
              description: The time the stop was added at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            cancelled_at:
              description: The time the stop was cancelled at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            skipped_at:
              description: The time the stop was skipped at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
      readOnly: true
    WriteServiceOrder:
      type: object
      description: A service order to be executed at a stop.
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        external_id:
          type: string
          example: ABC123
          description: |
            Identifier for this service order in an external transport or tour management  system connecting to this service.
        order:
          type: string
          description: |
            The actual order for the driver.
          example: Fill up with 100 l gasoline.
        note:
          type: string
          description: |
            Optional comment or note by the dispatcher to provide the driver with  additional information for the given service order
          example: Please photograph and upload the receipt.
        secondary_reference_id:
          type: string
          description: |
            An secondary reference number for a service order.
        additional_customer_data:
          $ref: "#/components/schemas/AdditionalCustomerData"
      required:
        - id
        - order
    ServiceOrder:
      allOf:
        - $ref: "#/components/schemas/WriteServiceOrder"
        - properties:
            documents:
              $ref: "#/components/schemas/Documents"
            started_at:
              description: The time the service order has been started.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            finished_at:
              description: The time the service order has been finished.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            added_at:
              description: The time the service order was added at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            cancelled_at:
              description: The time the service order was cancelled at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
      readOnly: true
    WriteTransportOrder:
      type: object
      description: "A transport order with loading, unloading and goods. To be picked\
        \ up from at `Stop` and delivered to another `Stop`."
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        external_id:
          type: string
          example: ABC123
          description: |
            Identifier for this transport order in an external transport or tour management  system connecting to this service.
        reference_id:
          type: string
          example: REF0001-ABC
          description: |
            An human readable reference ID for the driver or the recipient of this transport order.
        secondary_reference_id:
          type: string
          example: Relation 1326-167
          description: |
            An secondary reference number for a transport order.
        additional_customer_data:
          $ref: "#/components/schemas/AdditionalCustomerData"
        contact:
          $ref: "#/components/schemas/Contact"
        goods:
          $ref: "#/components/schemas/WriteGoods"
        loading:
          $ref: "#/components/schemas/Loading"
        unloading:
          $ref: "#/components/schemas/Unloading"
      required:
        - id
    TransportOrder:
      allOf:
        - $ref: "#/components/schemas/WriteTransportOrder"
        - properties:
            goods:
              $ref: "#/components/schemas/Goods"
            documents:
              $ref: "#/components/schemas/Documents"
            loaded_at:
              description: The time the goods have been picked up.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            delivered_at:
              description: The time the goods have been delivered.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            added_at:
              description: The time the transport order was added at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
            cancelled_at:
              description: The time the transport order was cancelled at.
              allOf:
                - $ref: "#/components/schemas/Timestamp"
      readOnly: true
    IdString:
      type: string
      example: 52210794-96bd-4797-abf5-b2b41c13e2ea
      description: Often a UUID. But there are exceptions. Always handle an ID as
        a string.
    Timestamp:
      type: string
      description: An ISO 8601 formatted timestamp.
      format: ISO 8601
      example: 2023-09-01T12:00:00.000Z
    Loading:
      type: object
      description: Data pertaining to the loading of a transport order
      properties:
        note:
          type: string
          description: |
            Optional comment or note by the dispatcher to provide the driver with  additional information for the given loading
          example: Please call the contact before entering the plant.
    Unloading:
      type: object
      description: Data pertaining to the unloading of a transport order
      properties:
        note:
          type: string
          description: |
            Optional comment or note by the dispatcher to provide the driver with  additional information for the given unloading
          example: Please call the contact before entering the plant.
    GoodsBase:
      type: object
      properties:
        type:
          type: string
          x-extensible-enum:
            - cargo-material
            - customer-trailer
            - swap-body
            - bulk-material
          example: cargo-material
      required:
        - type
    WriteGoods:
      description: |
        The goods being transported in the transport order.
      oneOf:
        - $ref: "#/components/schemas/WriteCargoMaterial"
        - $ref: "#/components/schemas/WriteCustomerTrailer"
        - $ref: "#/components/schemas/WriteSwapBody"
        - $ref: "#/components/schemas/WriteBulkMaterial"
      discriminator:
        propertyName: type
        mapping:
          cargo-material: "#/components/schemas/WriteCargoMaterial"
          customer-trailer: "#/components/schemas/WriteCustomerTrailer"
          swap-body: "#/components/schemas/WriteSwapBody"
          bulk-material: "#/components/schemas/WriteBulkMaterial"
    Goods:
      description: |
        The goods being transported in the transport order.
      oneOf:
        - $ref: "#/components/schemas/CargoMaterial"
        - $ref: "#/components/schemas/CustomerTrailer"
        - $ref: "#/components/schemas/SwapBody"
        - $ref: "#/components/schemas/BulkMaterial"
      discriminator:
        propertyName: type
        mapping:
          cargo-material: "#/components/schemas/CargoMaterial"
          customer-trailer: "#/components/schemas/CustomerTrailer"
          swap-body: "#/components/schemas/SwapBody"
          bulk-material: "#/components/schemas/BulkMaterial"
      readOnly: true
    WriteBulkMaterial:
      allOf:
        - $ref: "#/components/schemas/GoodsBase"
        - type: object
          properties:
            type:
              type: string
              enum:
                - bulk-material
            units:
              type: array
              items:
                $ref: "#/components/schemas/WriteBulkMaterialUnit"
          required:
            - units
    BulkMaterial:
      allOf:
        - $ref: "#/components/schemas/WriteBulkMaterial"
        - type: object
          properties:
            units:
              type: array
              items:
                $ref: "#/components/schemas/BulkMaterialUnit"
      readOnly: true
    WriteBulkMaterialUnit:
      type: object
      description: |
        Bulk material
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        quantity:
          $ref: "#/components/schemas/MaterialQuantity"
        material:
          $ref: "#/components/schemas/Material"
      additionalProperties: true
      required:
        - quantity
        - material
    BulkMaterialUnit:
      allOf:
        - $ref: "#/components/schemas/WriteBulkMaterialUnit"
        - type: object
          properties:
            documents:
              $ref: "#/components/schemas/Documents"
            reported_at:
              $ref: "#/components/schemas/Timestamp"
            proof_of_loading:
              $ref: "#/components/schemas/BulkMaterialUnitProofOfHandling"
            proof_of_delivery:
              $ref: "#/components/schemas/BulkMaterialUnitProofOfHandling"
          required:
            - id
      readOnly: true
    Material:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
      required:
        - name
        - id
    MaterialQuantity:
      type: object
      properties:
        type:
          type: string
          x-extensible-enum:
            - kilogram
            - ton
            - liter
            - cubic-meter
          example: kilogram
        value:
          type: number
          format: double
      required:
        - type
        - value
    WriteCargoMaterial:
      allOf:
        - $ref: "#/components/schemas/GoodsBase"
        - type: object
          properties:
            type:
              type: string
              enum:
                - cargo-material
            handling_units:
              type: array
              items:
                $ref: "#/components/schemas/WriteHandlingUnit"
          required:
            - handling_units
    CargoMaterial:
      allOf:
        - $ref: "#/components/schemas/WriteCargoMaterial"
        - type: object
          properties:
            handling_units:
              type: array
              items:
                $ref: "#/components/schemas/HandlingUnit"
      readOnly: true
    WriteHandlingUnit:
      type: object
      description: |
        A HandlingUnit is a unit of goods that combines the characteristics of load units and packages. On `CargoMaterial` level it represents a load unit where the `packaging_type` could be e.g. euro-pallet.
        If the `HandlingUnit` is part of another `HandlingUnits` content it represents a package where the `packaging_code` could be one of packaging materials like a plastic container or a carton of a specific size.
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        packaging_type:
          type: string
          description: |
            Name of the packaging material.
          x-extensible-enum:
            - unspecified
            - unpackaged
            - euro-pallet
            - industrial-pallet
            - one-way-pallet
            - cage-pallet
            - cardboard-box
            - rack
          example: euro-pallet
        quantity:
          type: integer
          format: int32
        stacking_factor:
          type: integer
          format: int32
          description: |
            Describes how many layers of the handling units can be stacked on top of each other. A value of 1 describes 1 layer, i.e., a non-stackable handling unit.
        dimension:
          $ref: "#/components/schemas/Dimension"
        weight:
          $ref: "#/components/schemas/Weight"
        loading_meter:
          $ref: "#/components/schemas/LoadingMeter"
        articles:
          type: array
          items:
            $ref: "#/components/schemas/Article"
      additionalProperties: true
      required:
        - packaging_type
        - quantity
    HandlingUnit:
      allOf:
        - $ref: "#/components/schemas/WriteHandlingUnit"
        - type: object
          properties:
            id:
              $ref: "#/components/schemas/IdString"
            documents:
              $ref: "#/components/schemas/Documents"
            reported_at:
              $ref: "#/components/schemas/Timestamp"
            proof_of_loading:
              $ref: "#/components/schemas/ProofOfHandling"
            proof_of_delivery:
              $ref: "#/components/schemas/ProofOfHandling"
          required:
            - id
      readOnly: true
    WriteCustomerTrailer:
      type: object
      description: The trailers that are to be delivered in the transport order.
      allOf:
        - $ref: "#/components/schemas/GoodsBase"
        - type: object
          properties:
            type:
              type: string
              enum:
                - customer-trailer
            trailers:
              type: array
              items:
                $ref: "#/components/schemas/WriteTrailerUnit"
          required:
            - trailers
    CustomerTrailer:
      allOf:
        - $ref: "#/components/schemas/WriteCustomerTrailer"
        - type: object
          properties:
            trailers:
              type: array
              items:
                $ref: "#/components/schemas/TrailerUnit"
      readOnly: true
    WriteTrailerUnit:
      description: A trailer that can be assigned as goods for a transport order.
      type: object
      properties:
        id:
          type: string
        license_plate:
          type: string
        note:
          type: string
      required:
        - id
    TrailerUnit:
      allOf:
        - $ref: "#/components/schemas/WriteTrailerUnit"
        - type: object
          properties:
            proof_of_loading:
              $ref: "#/components/schemas/CustomerTrailerProofOfHandling"
            proof_of_delivery:
              $ref: "#/components/schemas/CustomerTrailerProofOfHandling"
      readOnly: true
    WriteSwapBody:
      type: object
      description: The swap body used in a transport order.
      allOf:
        - $ref: "#/components/schemas/GoodsBase"
        - type: object
          properties:
            type:
              type: string
              enum:
                - swap-body
            units:
              type: array
              items:
                $ref: "#/components/schemas/WriteSwapBodyUnit"
          required:
            - units
    SwapBody:
      type: object
      description: The swap body used in a transport order.
      allOf:
        - $ref: "#/components/schemas/GoodsBase"
        - type: object
          properties:
            units:
              type: array
              items:
                $ref: "#/components/schemas/SwapBodyUnit"
          required:
            - units
      readOnly: true
    WriteSwapBodyUnit:
      type: object
      properties:
        id:
          type: string
      required:
        - id
    SwapBodyUnit:
      allOf:
        - $ref: "#/components/schemas/WriteSwapBodyUnit"
        - type: object
          properties:
            proof_of_loading:
              $ref: "#/components/schemas/SwapBodyProofOfHandling"
            proof_of_delivery:
              $ref: "#/components/schemas/SwapBodyProofOfHandling"
      readOnly: true
    CustomerTrailerProofOfHandling:
      type: object
      readOnly: true
      properties:
        confirmed_at:
          $ref: "#/components/schemas/Timestamp"
        license_plate:
          type: string
          example: DE 1234
      required:
        - confirmed_at
    SwapBodyProofOfHandling:
      type: object
      readOnly: true
      properties:
        confirmed_at:
          $ref: "#/components/schemas/Timestamp"
        swap_body_reference:
          type: string
          example: SB 1234
      required:
        - confirmed_at
    ProofOfHandling:
      type: object
      properties:
        confirmed_at:
          $ref: "#/components/schemas/Timestamp"
        deviation:
          $ref: "#/components/schemas/HandlingUnitDeviation"
      required:
        - confirmed_at
    BulkMaterialUnitProofOfHandling:
      type: object
      properties:
        confirmed_at:
          $ref: "#/components/schemas/Timestamp"
        deviation:
          $ref: "#/components/schemas/BulkMaterialUnitDeviation"
      required:
        - confirmed_at
    Dimension:
      type: object
      properties:
        length_cm:
          type: number
          format: double
          description: Length in centimeters
        width_cm:
          type: number
          format: double
          description: Width in centimeters
        height_cm:
          type: number
          format: double
          description: Height in centimeters
      required:
        - length_cm
        - width_cm
        - height_cm
    Weight:
      type: object
      properties:
        weight_kg:
          type: number
          format: double
          description: Weight of the handling unit in kg
      required:
        - weight_kg
    LoadingMeter:
      type: object
      properties:
        value:
          type: number
          format: double
          description: Loading meter of the handling unit
      required:
        - value
    Article:
      type: object
      properties:
        customer_article_id:
          type: string
          example: BLT Bremsbeläge
        quantity:
          $ref: "#/components/schemas/ArticleQuantity"
        name:
          type: string
        article_id:
          type: string
      additionalProperties: true
    ArticleQuantity:
      type: object
      oneOf:
        - $ref: "#/components/schemas/ArticleQuantityInteger"
        - $ref: "#/components/schemas/ArticleQuantityDecimal"
    ArticleQuantityInteger:
      type: object
      properties:
        type:
          type: string
          x-extensible-enum:
            - piece
            - leaf
            - drum
            - pair
            - roll
            - set
          example: piece
        value:
          type: integer
          format: int32
      required:
        - type
        - value
    ArticleQuantityDecimal:
      type: object
      properties:
        type:
          type: string
          x-extensible-enum:
            - meter
            - square-meter
            - cubic-meter
            - kilogram
          example: kilogram
        value:
          type: number
          format: double
      required:
        - type
        - value
    TourStatus:
      type: string
      example: in-transit
      x-extensible-enum:
        - planned
        - in-transit
        - handling
        - finished
      description: The current status of the tour.
    AdditionalCustomerData:
      type: object
      description: A dictionary containing additional customer data for the resource.
      additionalProperties:
        type: string
    MeansOfTransport:
      type: object
      description: The means of transport used for a tour. A tour without a set `MeansOfTransport`
        cannot be started.
      allOf:
        - $ref: "#/components/schemas/AssetId"
        - $ref: "#/components/schemas/LicensePlate"
      minProperties: 1
    Trailer:
      type: object
      description: A trailer that can be coupled with the main means of transport
        for this tour.
      allOf:
        - $ref: "#/components/schemas/AssetId"
        - $ref: "#/components/schemas/LicensePlate"
      minProperties: 1
    AssetId:
      type: object
      properties:
        asset_id:
          description: The id of an asset.
          allOf:
            - $ref: "#/components/schemas/IdString"
    LicensePlate:
      type: object
      properties:
        license_plate:
          type: object
          description: A license plate number and country code
          properties:
            plate_number:
              type: string
              description: License plate number
              example: M-AN 100
            country_code:
              type: string
              description: Country code of the country the vehicle is licensed in
              example: DE
          required:
            - plate_number
            - country_code
    OrderHandle:
      $ref: "#/components/schemas/IdString"
    TimeWindow:
      type: object
      description: A time window defined by the two time points `start_at` and `end_at`.
      properties:
        start_at:
          $ref: "#/components/schemas/Timestamp"
        end_at:
          $ref: "#/components/schemas/Timestamp"
      required:
        - start_at
        - end_at
    Location:
      type: object
      description: A physical location specified by an `Address` and geographic `Coordinates`.
      properties:
        name:
          type: string
          example: Paketdepot Süd
          description: |
            Human readable name for the location.
        address:
          $ref: "#/components/schemas/Address"
        coordinates:
          $ref: "#/components/schemas/Coordinates"
        external_id:
          type: string
          example: ABC123
          description: |
            Identifier for this location in an external transport or tour management  system connecting to this service.
      required:
        - coordinates
    Address:
      type: object
      description: The address of a location.
      properties:
        street:
          type: string
          example: Oskar-Schlemmer-Str. 18-21
        postal_code:
          type: string
          example: 80807
        city:
          type: string
          example: Munich
        country:
          type: string
          example: Germany
    Coordinates:
      type: object
      description: Geographic coordinates consisting of a `latitude` and a `longitude`.
      properties:
        latitude:
          type: number
          format: double
        longitude:
          type: number
          format: double
      required:
        - latitude
        - longitude
    Contact:
      type: object
      description: Contact information of e.g. the shipment consignee
      properties:
        name:
          type: string
          example: Christian Mags
        email:
          type: string
          example: christian.mags@magskunststoffe.de
        phone:
          type: string
          example: 089 24 48 86 86
        language:
          type: string
          example: de
          description: ISO 639-1 language code
        has_agreed_to_receive_emails:
          type: boolean
          example: true
          description: Set to true if contact should receive automatic delivery status
            updates via email
    TourProblems:
      type: array
      items:
        $ref: "#/components/schemas/TourProblem"
    TourProblem:
      type: object
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        type:
          $ref: "#/components/schemas/TourProblemType"
        tour_stop_id:
          $ref: "#/components/schemas/IdString"
        documents:
          $ref: "#/components/schemas/WriteDocuments"
        reported_at:
          allOf:
            - $ref: "#/components/schemas/Timestamp"
        acknowledged_at:
          allOf:
            - $ref: "#/components/schemas/Timestamp"
      required:
        - id
        - type
      readOnly: true
    TourProblemType:
      type: string
      x-extensible-enum:
        - call-back
        - declined-goods
        - problem-with-customer
        - customer-not-available
        - accident
        - heavy-traffic
        - damage
        - running-late
        - other
    TourEventListCursor:
      type: object
      allOf:
        - $ref: "#/components/schemas/TourEventList"
        - properties:
            next:
              type: string
              description: "The fully qualified URL to the next result page, including\
                \ the cursor and all given query parameters."
    LisMessageWrapperListCursor:
      type: object
      allOf:
        - $ref: "#/components/schemas/LisMessageWrapperList"
        - properties:
            next:
              type: string
              description: "The fully qualified URL to the next result page, including\
                \ the cursor and all given query parameters."
          required:
            - next
    LisMessageWrapperList:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/LisMessageWithAttachmentsWrapper"
      required:
        - items
    TourEventList:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/BaseTourEvent"
    LisMessageWithAttachmentsWrapper:
      type: object
      properties:
        message:
          type: string
          description: Tour event in LISTrac message format.
        attachments:
          type: array
          items:
            type: object
            properties:
              uri:
                type: string
                description: URI to download the file content.
              file_name:
                type: string
                description: Name of the file.
            required:
              - uri
              - file_name
      required:
        - message
    LisMessageWrapper:
      type: object
      properties:
        message:
          type: string
          description: Raw content in a LISTrac message format.
      required:
        - message
    BaseTourEvent:
      oneOf:
        - $ref: "#/components/schemas/TourEvent"
        - $ref: "#/components/schemas/TourStopEvent"
        - $ref: "#/components/schemas/ProblemReportedEvent"
        - $ref: "#/components/schemas/ProblemAcknowledgedEvent"
        - $ref: "#/components/schemas/CustomerTrailerConfirmedEvent"
        - $ref: "#/components/schemas/SwapBodyConfirmedEvent"
        - $ref: "#/components/schemas/HandlingUnitEvent"
    TourEvent:
      properties:
        id:
          type: string
          format: uuid
        account_id:
          type: string
          format: uuid
        tour_id:
          type: string
        occurred_at:
          type: string
        event_type:
          type: string
          enum:
            - tour-created
            - tour-updated
            - tour-deleted
            - tour-acknowledged
            - tour-started
            - tour-finished
      required:
        - id
        - account_id
        - tour_id
        - occurred_at
        - event_type
    ProblemAcknowledgedEvent:
      properties:
        id:
          type: string
          format: uuid
        account_id:
          type: string
          format: uuid
        tour_id:
          type: string
        occurred_at:
          type: string
        event_type:
          type: string
          enum:
            - problem-acknowledged
        problem_id:
          type: string
      required:
        - id
        - account_id
        - tour_id
        - occurred_at
        - event_type
        - problem_id
    ProblemReportedEvent:
      properties:
        id:
          type: string
          format: uuid
        account_id:
          type: string
          format: uuid
        tour_id:
          type: string
        occurred_at:
          type: string
        event_type:
          type: string
          enum:
            - problem-reported
        problem:
          $ref: "#/components/schemas/TourProblem"
      required:
        - id
        - account_id
        - tour_id
        - occurred_at
        - event_type
        - problem
    CustomerTrailerConfirmedEvent:
      properties:
        id:
          type: string
          format: uuid
        account_id:
          type: string
          format: uuid
        tour_id:
          type: string
        occurred_at:
          type: string
        event_type:
          type: string
          enum:
            - trailer-confirmed
        tour_stop_id:
          type: string
        transport_order_id:
          type: string
        customer_trailer_id:
          type: string
        customer_trailer_license_plate:
          type: string
      required:
        - id
        - account_id
        - tour_id
        - occurred_at
        - event_type
        - tour_stop_id
        - transport_order_id
        - customer_trailer_id
    SwapBodyConfirmedEvent:
      properties:
        id:
          type: string
          format: uuid
        account_id:
          type: string
          format: uuid
        tour_id:
          type: string
        occurred_at:
          type: string
        event_type:
          type: string
          enum:
            - swap-body-confirmed
        tour_stop_id:
          type: string
        transport_order_id:
          type: string
        swap_body_id:
          type: string
        swap_body_reference:
          type: string
      required:
        - id
        - account_id
        - tour_id
        - occurred_at
        - event_type
        - tour_stop_id
        - transport_order_id
        - swap_body_id
    HandlingUnitEvent:
      properties:
        id:
          type: string
          format: uuid
        account_id:
          type: string
          format: uuid
        tour_id:
          type: string
        occurred_at:
          type: string
        event_type:
          type: string
          enum:
            - handling-unit-confirmed
            - additional-handling-unit-reported
        tour_stop_id:
          type: string
        transport_order_id:
          type: string
        handling_unit_id:
          type: string
      required:
        - id
        - account_id
        - tour_id
        - occurred_at
        - event_type
        - tour_stop_id
        - transport_order_id
        - handling_unit_id
    TourStopEvent:
      properties:
        id:
          type: string
          format: uuid
        account_id:
          type: string
          format: uuid
        tour_id:
          type: string
        occurred_at:
          type: string
        event_type:
          type: string
          enum:
            - tour-stop-reached
            - loading-started
            - loading-finished
            - unloading-started
            - unloading-finished
            - execution-started
            - execution-finished
            - tour-stop-finished
            - tour-stop-skipped
        tour_stop_id:
          type: string
      required:
        - id
        - account_id
        - tour_id
        - occurred_at
        - event_type
        - tour_stop_id
    TourProblemConfirmation:
      type: object
      properties:
        type:
          type: string
          enum:
            - acknowledge-tour-problem
          example: acknowledge-tour-problem
      required:
        - type
    HandlingUnitDeviation:
      type: object
      properties:
        quantity:
          type: integer
          format: int32
        weight:
          $ref: "#/components/schemas/Weight"
        loading_meter:
          $ref: "#/components/schemas/LoadingMeter"
        articles:
          type: array
          items:
            $ref: "#/components/schemas/Article"
        comment:
          type: string
          description: Optional comment regarding this deviation
          example: Received 2 boxes instead of 3 due to issue at box factory
      minProperties: 1
    BulkMaterialUnitDeviation:
      type: object
      properties:
        quantity:
          $ref: "#/components/schemas/MaterialQuantity"
        comment:
          type: string
          description: Optional comment regarding this deviation
          example: Received 1 ton of sand instead of 2
      minProperties: 1
    WriteDocument:
      type: object
      description: A document pertaining to (some part of) this `Tour`
      properties:
        id:
          $ref: "#/components/schemas/IdString"
        type:
          type: string
          x-extensible-enum:
            - directions
            - receipt
            - proof-of-loading
            - proof-of-delivery
            - other
          description: Type (purpose) of this `Document`.
          example: other
        name:
          type: string
          description: Name of this document
          example: My Receipt
        file_name:
          type: string
          description: Name of the file described by this `Document`
          example: my-receipt.pdf
        external_id:
          type: string
          example: ABC123
          description: |
            Identifier for this tour in an external transport or tour management  system connecting to this service.
      required:
        - id
        - type
        - name
        - file_name
    WriteDocuments:
      type: array
      items:
        $ref: "#/components/schemas/WriteDocument"
    Document:
      type: object
      description: A document pertaining to (some part of) this `Tour` via association
      allOf:
        - $ref: "#/components/schemas/WriteDocument"
        - properties:
            associations:
              type: array
              items:
                $ref: "#/components/schemas/DocumentAssociation"
      readOnly: true
    Documents:
      type: array
      items:
        $ref: "#/components/schemas/Document"
    DocumentList:
      type: object
      properties:
        items:
          $ref: "#/components/schemas/Documents"
    DocumentAssociation:
      type: object
      description: |
        An association of the document with a `Tour`, `Tour Stop`, `Service Order`, `Transport Order`, `Problem`, or `Handling Unit`.
        `id` identifies the entity this document is associated with, e.g. tour stop id.
      properties:
        type:
          type: string
          enum:
            - tour
            - tour-stop
            - service-order
            - transport-order
            - problem
            - handling-unit
            - bulk-material-unit
        id:
          $ref: "#/components/schemas/IdString"
    FileLink:
      type: object
      description: Upload or download link for the given file name
      properties:
        file_name:
          type: string
          description: Name (incl. extension) of the file being accessed via this
            link
          example: my_document.pdf
        action_link:
          type: string
          description: URL for downloading or uploading the given file
          example: https://example.com/files/13445/my_document.pdf
      required:
        - file_name
        - action_link
    Link:
      type: object
      required:
        - href
      properties:
        href:
          type: string
          example: https://...
    Problem:
      type: object
      allOf:
        - $ref: https://opensource.zalando.com/problem/schema.yaml#/Problem
        - properties:
            code:
              type: string
              example: SOME_PROBLEM
              description: Machine-readable error code for the problem
