.. _order-shipping-api:

Order Shipping API
==================

One key feature of Shopware ERP is *shipping orders out of a warehouse*, which refers to the process of clearing the
physical stock which is being sent from the warehouse to the customer.

There are two endpoints for this:

* ``PUT /api/orders/{id}/ship`` is a high-level API which fully clears the stock for a single order from a warehouse
  using the :ref:`default strategy <picking-order>`.
* ``PUT /api/orderDetails/ship/{idempotencyKey}`` is a fine-grained, batch-focused, :ref:`idempotent <idempotency>` API
  which can fully or partially clear stock for any number of order positions (order details) from any number of orders.

.. http:put:: /api/orders/{id}/ship

    Ship the given order. Shipping an order entails the following steps:

    * For each order detail, physical stock equal to the remaining quantity to ship (equal to ``quantity - shipped``
      will be cleared from the given warehouse,
    * the shipped quantity of each order detail will be increased to the ordered quantity,
    * the order details' statuses will be set to "Completed",
    * the order's status will be set to "Completely delivered", and
    * if configured, a status update email will be sent to the customer unless the ``suppressStatusMail`` parameter
      is passed.

    Shipping an order which is already fully shipped has no effect. This means that this endpoint is naturally
    idempotent, which is why no idempotency key is required.

    :param integer|string id: the database ID or the order number of the of the order to ship
    :query boolean useNumberAsId: if ``true``, interpret ``id`` is an order number instead of as a database ID

    :<json object warehouse: a warehouse from which to clear the stock required to fill the order
    :<json integer warehouse.id: the database ID of the warehouse. Either this or the warehouses's shorthand code
        must be specified.
    :<json string warehouse.code: the shorthand code of the warehouse. Either this or the warehouse's shorthand code
        must be specified.
    :<json boolean suppressStatusMail: optional, if ``true``, no status update email will be sent to the customer

    :>json boolean success: ``true`` if shipping the order was successful, ``false`` otherwise

    **Example request**:

    .. http:example:: curl wget httpie

        PUT /api/orders/21400/ship?useNumberAsId=true HTTP/1.1
        Content-Type: application/json
        Host: localhost

        {
            "warehouse": {
                "id": 1
            },
            "suppressStatusMail": true
        }

    **Example response**:

    .. code-block:: http

        HTTP/1.1 200 OK
        Content-Type: application/json

        {
            "success": true
        }

.. http:put:: /api/orderDetails/ship/{idempotencyKey}

    For a batch of order details, clear the specified quantity of stock for the order detail from a specified stock
    location and increase the order detail's shipped quantity accordingly.

    This takes a list of independent operations which are executed in order. When doing mass updates, we recommend
    sending large batches for optimum performance. The maximum allowed batch size is 1000.

    For each operation, either a warehouse or a bin location from which to clear the stock must be specified. Warehouses
    are specified by their database ID or their code. Bin locations can either be specified by their database ID, or by
    their code and the warehouse code or the database ID of the warehouse (since the bin location code is unique on a
    per-warehouse basis).

    This endpoint requires an arbitrary, unique idempotency key to be specified as a path component of the request URL.
    This idempotency key must be reused when retrying the same batch of operations after a server or network failure.
    It must not be reused when sending a new batch of operations. See :ref:`idempotency` for further details on this.

    **Examples of valid bin location specifications**:

    .. code-block:: yaml

        "binLocation": {
            "id": 9
        }

    .. code-block:: yaml

        "binLocation": {
            "code": "a1",
            "warehouseId": "2"
        }

    .. code-block:: yaml

        "binLocation": {
            "code": "a1",
            "warehouseCode": "MW"
        }

    **Examples of valid warehouse specifications**:

    .. code-block:: yaml

        "warehouse": {
            "id": 9
        }

    .. code-block:: yaml

        "warehouse": {
            "code": "MW"
        }

    :param string idempotencyKey: the :ref:`idempotency key <idempotency>` for the request

    :<json object [*]: an individual operation of the batch
    :<json integer [*].orderDetailId: the order detail to ship
    :<json integer [*].quantity: the quantity of stock to ship. This must be less than or equal to the remaining
        quantity to ship, which is the difference between the ordered quantity and the shipped quantity.
    :<json object [*].warehouse: a warehouse from which to clear the stock for the order detail
    :<json integer [*].warehouse.id: the database ID of the warehouse. Either this or the warehouse's shorthand code
        must be specified
    :<json string [*].warehouse.code: the shorthand code of the warehouse. Either this or the warehouse's database ID
        must be specified.
    :<json object [*].binLocation: a bin location from which to clear the stock for the order detail
    :<json integer [*].binLocation.id: the database ID of the bin location. Either this or a valid combination of
        bin location code and a valid warehouse identifier must be specified.
    :<json string [*].binLocation.code: the shorthand code of the bin location. If this is used to identify the bin
        location, the warehouse must also be specified by its database ID or its shorthand code.
    :<json integer [*].binLocation.warehouseId: the database ID of the warehouse containing the bin location
    :<json string [*].binLocation.warehouseCode: the shorthand code of the warehouse containing the bin location

    :>json boolean success: ``true`` if all operations of the batch were executed successfully, ``false`` otherwise
    :>json string message: an explanatory message which is present when there was at least one unsuccessful operation
        in the batch
    :>json string idempotencyKey: the :ref:`idempotency key <idempotency>` of the batch
    :>json timestamp createdAt: the point in time when all operations in the batch were completed
    :>json any results[*].operationId: the value of the ``id`` property of the operation, if it was present in the
        request
    :>json boolean results[*].success: ``true`` if the operation was completed successfully, ``false`` otherwise. Note
        that retrying the batch with the same idempotency key will not change the result for this operation.
    :>json string results[*].message: an explanation of what went wrong which is only present when the operation was not
        successful

    **Example request**:

    .. http:example:: curl wget httpie

        PUT /api/orderDetails/ship/b09788d8-fda3-4a5f-b4ec-4b876e71dc76 HTTP/1.1
        Content-Type: application/json
        Host: localhost

        [
            {
                "orderDetailId": 3011,
                "quantity": 2,
                "binLocation": {
                    "id": 9
                }
            },
            {
                "orderDetailId": 3012,
                "quantity": 5,
                "warehouse": {
                    "id": 1
                }
            }
        ]

    **Example response**:

    .. code-block:: http

        HTTP/1.1 200 OK
        Content-Type: application/json

        {
            "success": true,
            "idempotencyKey": "b09788d8-fda3-4a5f-b4ec-4b876e71dc76",
            "createdAt": "2019-07-22T13:35:12+0200",
            "results": [
                {
                    "success": true
                },
                {
                    "success": true
                }
            ]
        }
