<?php
/**
 * OrderShipmentsApi
 * PHP version 8.1
 *
 * @category Class
 * @package  Bigcommerce\OrdersV2
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * Orders V2
 *
 * Manage order coupons, messages, products, shipping addresses, statuses, taxes, shipments, and shipping address quotes.  - [Authentication](#authentication) - [Order](#order)  ## Authentication  Authenticate requests by including an [OAuth](https://developer.bigcommerce.com/api-docs/getting-started/authentication) `access_token` request header.  ```http GET https://api.bigcommerce.com/stores/{{STORE_HASH}}/v3/{{ENDPOINT}} Content-Type: application/json X-Auth-Token: {{ACCESS_TOKEN}} ```  ### OAuth Scopes  |  **UI Name** | **Permission** | **Parameter** | | --- | --- | --- | |  Orders | modify | `store_v2_orders` | |  Orders | read-only | `store_v2_orders_read_only` |   ## Order  The Order object contains a record of the purchase agreement between a shopper and a merchant. To learn more about creating orders, see [Orders API Guide](/api-docs/orders/orders-api-overview).  ### Currency Fields  The **default** currency refers to the transactional currency which is the currency the shopper pays in.  The **display** currency refers to the presentational currency used to present prices to the shopper on the storefront.  * `currency_id` - the display currency ID. Depending on the currency selected, the value may be different from the transactional currency. * `currency_code` - the currency code of the display currency used to present prices to the shopper on the storefront. Depending on the currency selected, the value may be different from the transactional currency. * `currency_exchange_rate` - the exchange rate between the store's default currency and the display currency. For orders created using the V2 endpoints, this value is always 1 (only in the storefront this value can be different to 1). * `default_currency_id` - the transactional currency ID. * `default_currency_code` - the currency code of the transactional currency the shopper pays in.  The following additional fields are returned on orders when Multi-Currency is enabled on the store:  * `store_default_currency_code` - the currency code of the store's default currency. * `store_default_to_transactional_exchange_rate` - the exchange rate between the store's default currency and the transactional currency used in the order.  **Example:**  ```json {   ...   \"currency_id\": 4,   \"currency_code\": \"EUR\",   \"currency_exchange_rate\": 1,   \"default_currency_id\": 4,   \"default_currency_code\": \"EUR\",   \"store_default_currency_code\": \"USD\",   \"store_default_to_transactional_exchange_rate\": \"100.0000000000\"   ... } ```
 *
 * The version of the OpenAPI document: 
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.13.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace Bigcommerce\OrdersV2\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Bigcommerce\OrdersV2\ApiException;
use Bigcommerce\OrdersV2\Configuration;
use Bigcommerce\OrdersV2\FormDataProcessor;
use Bigcommerce\OrdersV2\HeaderSelector;
use Bigcommerce\OrdersV2\ObjectSerializer;

/**
 * OrderShipmentsApi Class Doc Comment
 *
 * @category Class
 * @package  Bigcommerce\OrdersV2
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */
class OrderShipmentsApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var Configuration
     */
    protected $config;

    /**
     * @var HeaderSelector
     */
    protected $headerSelector;

    /**
     * @var int Host index
     */
    protected $hostIndex;

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'createOrderShipments' => [
            'application/json',
        ],
        'deleteAllOrderShipments' => [
            'application/json',
        ],
        'deleteOrderShipment' => [
            'application/json',
        ],
        'getAllOrderShipments' => [
            'application/json',
        ],
        'getCountShipments' => [
            'application/json',
        ],
        'getOrderShipment' => [
            'application/json',
        ],
        'updateOrderShipment' => [
            'application/json',
        ],
    ];

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     * @param int             $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        ?ClientInterface $client = null,
        ?Configuration $config = null,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: Configuration::getDefaultConfiguration();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex($hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index
     *
     * @return int Host index
     */
    public function getHostIndex()
    {
        return $this->hostIndex;
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation createOrderShipments
     *
     * Create Order Shipment&#39;
     *
     * @param  int $order_id ID of the order (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPost $order_shipment_post order_shipment_post (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV2\Model\OrderShipment
     */
    public function createOrderShipments($order_id, $order_shipment_post, string $contentType = self::contentTypes['createOrderShipments'][0])
    {
        list($response) = $this->createOrderShipmentsWithHttpInfo($order_id, $order_shipment_post, $contentType);
        return $response;
    }

    /**
     * Operation createOrderShipmentsWithHttpInfo
     *
     * Create Order Shipment&#39;
     *
     * @param  int $order_id ID of the order (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPost $order_shipment_post (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV2\Model\OrderShipment, HTTP status code, HTTP response headers (array of strings)
     */
    public function createOrderShipmentsWithHttpInfo($order_id, $order_shipment_post, string $contentType = self::contentTypes['createOrderShipments'][0])
    {
        $request = $this->createOrderShipmentsRequest($order_id, $order_shipment_post, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 201:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV2\Model\OrderShipment',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV2\Model\OrderShipment',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 201:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV2\Model\OrderShipment',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation createOrderShipmentsAsync
     *
     * Create Order Shipment&#39;
     *
     * @param  int $order_id ID of the order (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPost $order_shipment_post (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOrderShipmentsAsync($order_id, $order_shipment_post, string $contentType = self::contentTypes['createOrderShipments'][0])
    {
        return $this->createOrderShipmentsAsyncWithHttpInfo($order_id, $order_shipment_post, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation createOrderShipmentsAsyncWithHttpInfo
     *
     * Create Order Shipment&#39;
     *
     * @param  int $order_id ID of the order (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPost $order_shipment_post (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOrderShipmentsAsyncWithHttpInfo($order_id, $order_shipment_post, string $contentType = self::contentTypes['createOrderShipments'][0])
    {
        $returnType = '\Bigcommerce\OrdersV2\Model\OrderShipment';
        $request = $this->createOrderShipmentsRequest($order_id, $order_shipment_post, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createOrderShipments'
     *
     * @param  int $order_id ID of the order (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPost $order_shipment_post (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function createOrderShipmentsRequest($order_id, $order_shipment_post, string $contentType = self::contentTypes['createOrderShipments'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling createOrderShipments'
            );
        }

        // verify the required parameter 'order_shipment_post' is set
        if ($order_shipment_post === null || (is_array($order_shipment_post) && count($order_shipment_post) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_shipment_post when calling createOrderShipments'
            );
        }


        $resourcePath = '/orders/{order_id}/shipments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (isset($order_shipment_post)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($order_shipment_post));
            } else {
                $httpBody = $order_shipment_post;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'POST',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteAllOrderShipments
     *
     * Delete Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteAllOrderShipments($order_id, string $contentType = self::contentTypes['deleteAllOrderShipments'][0])
    {
        $this->deleteAllOrderShipmentsWithHttpInfo($order_id, $contentType);
    }

    /**
     * Operation deleteAllOrderShipmentsWithHttpInfo
     *
     * Delete Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteAllOrderShipmentsWithHttpInfo($order_id, string $contentType = self::contentTypes['deleteAllOrderShipments'][0])
    {
        $request = $this->deleteAllOrderShipmentsRequest($order_id, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
            }
        

            throw $e;
        }
    }

    /**
     * Operation deleteAllOrderShipmentsAsync
     *
     * Delete Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteAllOrderShipmentsAsync($order_id, string $contentType = self::contentTypes['deleteAllOrderShipments'][0])
    {
        return $this->deleteAllOrderShipmentsAsyncWithHttpInfo($order_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation deleteAllOrderShipmentsAsyncWithHttpInfo
     *
     * Delete Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteAllOrderShipmentsAsyncWithHttpInfo($order_id, string $contentType = self::contentTypes['deleteAllOrderShipments'][0])
    {
        $returnType = '';
        $request = $this->deleteAllOrderShipmentsRequest($order_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    return [null, $response->getStatusCode(), $response->getHeaders()];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteAllOrderShipments'
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function deleteAllOrderShipmentsRequest($order_id, string $contentType = self::contentTypes['deleteAllOrderShipments'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling deleteAllOrderShipments'
            );
        }


        $resourcePath = '/orders/{order_id}/shipments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            [],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'DELETE',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteOrderShipment
     *
     * Delete an Order Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderShipment'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteOrderShipment($order_id, $shipment_id, string $contentType = self::contentTypes['deleteOrderShipment'][0])
    {
        $this->deleteOrderShipmentWithHttpInfo($order_id, $shipment_id, $contentType);
    }

    /**
     * Operation deleteOrderShipmentWithHttpInfo
     *
     * Delete an Order Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderShipment'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteOrderShipmentWithHttpInfo($order_id, $shipment_id, string $contentType = self::contentTypes['deleteOrderShipment'][0])
    {
        $request = $this->deleteOrderShipmentRequest($order_id, $shipment_id, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
            }
        

            throw $e;
        }
    }

    /**
     * Operation deleteOrderShipmentAsync
     *
     * Delete an Order Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteOrderShipmentAsync($order_id, $shipment_id, string $contentType = self::contentTypes['deleteOrderShipment'][0])
    {
        return $this->deleteOrderShipmentAsyncWithHttpInfo($order_id, $shipment_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation deleteOrderShipmentAsyncWithHttpInfo
     *
     * Delete an Order Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteOrderShipmentAsyncWithHttpInfo($order_id, $shipment_id, string $contentType = self::contentTypes['deleteOrderShipment'][0])
    {
        $returnType = '';
        $request = $this->deleteOrderShipmentRequest($order_id, $shipment_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    return [null, $response->getStatusCode(), $response->getHeaders()];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteOrderShipment'
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function deleteOrderShipmentRequest($order_id, $shipment_id, string $contentType = self::contentTypes['deleteOrderShipment'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling deleteOrderShipment'
            );
        }

        // verify the required parameter 'shipment_id' is set
        if ($shipment_id === null || (is_array($shipment_id) && count($shipment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $shipment_id when calling deleteOrderShipment'
            );
        }


        $resourcePath = '/orders/{order_id}/shipments/{shipment_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }
        // path params
        if ($shipment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'shipment_id' . '}',
                ObjectSerializer::toPathValue($shipment_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            [],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'DELETE',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAllOrderShipments
     *
     * Get Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  float|null $page The page to return in the response. (optional)
     * @param  float|null $limit Number of results to return. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV2\Model\OrderShipment[]
     */
    public function getAllOrderShipments($order_id, $page = null, $limit = null, string $contentType = self::contentTypes['getAllOrderShipments'][0])
    {
        list($response) = $this->getAllOrderShipmentsWithHttpInfo($order_id, $page, $limit, $contentType);
        return $response;
    }

    /**
     * Operation getAllOrderShipmentsWithHttpInfo
     *
     * Get Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  float|null $page The page to return in the response. (optional)
     * @param  float|null $limit Number of results to return. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV2\Model\OrderShipment[], HTTP status code, HTTP response headers (array of strings)
     */
    public function getAllOrderShipmentsWithHttpInfo($order_id, $page = null, $limit = null, string $contentType = self::contentTypes['getAllOrderShipments'][0])
    {
        $request = $this->getAllOrderShipmentsRequest($order_id, $page, $limit, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV2\Model\OrderShipment[]',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV2\Model\OrderShipment[]',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV2\Model\OrderShipment[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getAllOrderShipmentsAsync
     *
     * Get Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  float|null $page The page to return in the response. (optional)
     * @param  float|null $limit Number of results to return. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAllOrderShipmentsAsync($order_id, $page = null, $limit = null, string $contentType = self::contentTypes['getAllOrderShipments'][0])
    {
        return $this->getAllOrderShipmentsAsyncWithHttpInfo($order_id, $page, $limit, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getAllOrderShipmentsAsyncWithHttpInfo
     *
     * Get Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  float|null $page The page to return in the response. (optional)
     * @param  float|null $limit Number of results to return. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAllOrderShipmentsAsyncWithHttpInfo($order_id, $page = null, $limit = null, string $contentType = self::contentTypes['getAllOrderShipments'][0])
    {
        $returnType = '\Bigcommerce\OrdersV2\Model\OrderShipment[]';
        $request = $this->getAllOrderShipmentsRequest($order_id, $page, $limit, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getAllOrderShipments'
     *
     * @param  int $order_id ID of the order (required)
     * @param  float|null $page The page to return in the response. (optional)
     * @param  float|null $limit Number of results to return. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAllOrderShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getAllOrderShipmentsRequest($order_id, $page = null, $limit = null, string $contentType = self::contentTypes['getAllOrderShipments'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling getAllOrderShipments'
            );
        }




        $resourcePath = '/orders/{order_id}/shipments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $page,
            'page', // param base name
            'number', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $limit,
            'limit', // param base name
            'number', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);


        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCountShipments
     *
     * Get Count of Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCountShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV2\Model\OrderCount
     */
    public function getCountShipments($order_id, string $contentType = self::contentTypes['getCountShipments'][0])
    {
        list($response) = $this->getCountShipmentsWithHttpInfo($order_id, $contentType);
        return $response;
    }

    /**
     * Operation getCountShipmentsWithHttpInfo
     *
     * Get Count of Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCountShipments'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV2\Model\OrderCount, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCountShipmentsWithHttpInfo($order_id, string $contentType = self::contentTypes['getCountShipments'][0])
    {
        $request = $this->getCountShipmentsRequest($order_id, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV2\Model\OrderCount',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV2\Model\OrderCount',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV2\Model\OrderCount',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getCountShipmentsAsync
     *
     * Get Count of Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCountShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCountShipmentsAsync($order_id, string $contentType = self::contentTypes['getCountShipments'][0])
    {
        return $this->getCountShipmentsAsyncWithHttpInfo($order_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getCountShipmentsAsyncWithHttpInfo
     *
     * Get Count of Order Shipments
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCountShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCountShipmentsAsyncWithHttpInfo($order_id, string $contentType = self::contentTypes['getCountShipments'][0])
    {
        $returnType = '\Bigcommerce\OrdersV2\Model\OrderCount';
        $request = $this->getCountShipmentsRequest($order_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCountShipments'
     *
     * @param  int $order_id ID of the order (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCountShipments'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getCountShipmentsRequest($order_id, string $contentType = self::contentTypes['getCountShipments'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling getCountShipments'
            );
        }


        $resourcePath = '/orders/{order_id}/shipments/count';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOrderShipment
     *
     * Get a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderShipment'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV2\Model\OrderShipment
     */
    public function getOrderShipment($order_id, $shipment_id, string $contentType = self::contentTypes['getOrderShipment'][0])
    {
        list($response) = $this->getOrderShipmentWithHttpInfo($order_id, $shipment_id, $contentType);
        return $response;
    }

    /**
     * Operation getOrderShipmentWithHttpInfo
     *
     * Get a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderShipment'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV2\Model\OrderShipment, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOrderShipmentWithHttpInfo($order_id, $shipment_id, string $contentType = self::contentTypes['getOrderShipment'][0])
    {
        $request = $this->getOrderShipmentRequest($order_id, $shipment_id, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV2\Model\OrderShipment',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV2\Model\OrderShipment',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV2\Model\OrderShipment',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getOrderShipmentAsync
     *
     * Get a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrderShipmentAsync($order_id, $shipment_id, string $contentType = self::contentTypes['getOrderShipment'][0])
    {
        return $this->getOrderShipmentAsyncWithHttpInfo($order_id, $shipment_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getOrderShipmentAsyncWithHttpInfo
     *
     * Get a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrderShipmentAsyncWithHttpInfo($order_id, $shipment_id, string $contentType = self::contentTypes['getOrderShipment'][0])
    {
        $returnType = '\Bigcommerce\OrdersV2\Model\OrderShipment';
        $request = $this->getOrderShipmentRequest($order_id, $shipment_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOrderShipment'
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getOrderShipmentRequest($order_id, $shipment_id, string $contentType = self::contentTypes['getOrderShipment'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling getOrderShipment'
            );
        }

        // verify the required parameter 'shipment_id' is set
        if ($shipment_id === null || (is_array($shipment_id) && count($shipment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $shipment_id when calling getOrderShipment'
            );
        }


        $resourcePath = '/orders/{order_id}/shipments/{shipment_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }
        // path params
        if ($shipment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'shipment_id' . '}',
                ObjectSerializer::toPathValue($shipment_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrderShipment
     *
     * Update a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPut $order_shipment_put order_shipment_put (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderShipment'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Bigcommerce\OrdersV2\Model\OrderShipment
     */
    public function updateOrderShipment($order_id, $shipment_id, $order_shipment_put, string $contentType = self::contentTypes['updateOrderShipment'][0])
    {
        list($response) = $this->updateOrderShipmentWithHttpInfo($order_id, $shipment_id, $order_shipment_put, $contentType);
        return $response;
    }

    /**
     * Operation updateOrderShipmentWithHttpInfo
     *
     * Update a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPut $order_shipment_put (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderShipment'] to see the possible values for this operation
     *
     * @throws \Bigcommerce\OrdersV2\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Bigcommerce\OrdersV2\Model\OrderShipment, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrderShipmentWithHttpInfo($order_id, $shipment_id, $order_shipment_put, string $contentType = self::contentTypes['updateOrderShipment'][0])
    {
        $request = $this->updateOrderShipmentRequest($order_id, $shipment_id, $order_shipment_put, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Bigcommerce\OrdersV2\Model\OrderShipment',
                        $request,
                        $response,
                    );
            }

            

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Bigcommerce\OrdersV2\Model\OrderShipment',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Bigcommerce\OrdersV2\Model\OrderShipment',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation updateOrderShipmentAsync
     *
     * Update a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPut $order_shipment_put (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrderShipmentAsync($order_id, $shipment_id, $order_shipment_put, string $contentType = self::contentTypes['updateOrderShipment'][0])
    {
        return $this->updateOrderShipmentAsyncWithHttpInfo($order_id, $shipment_id, $order_shipment_put, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation updateOrderShipmentAsyncWithHttpInfo
     *
     * Update a Shipment
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPut $order_shipment_put (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrderShipmentAsyncWithHttpInfo($order_id, $shipment_id, $order_shipment_put, string $contentType = self::contentTypes['updateOrderShipment'][0])
    {
        $returnType = '\Bigcommerce\OrdersV2\Model\OrderShipment';
        $request = $this->updateOrderShipmentRequest($order_id, $shipment_id, $order_shipment_put, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrderShipment'
     *
     * @param  int $order_id ID of the order (required)
     * @param  int $shipment_id Shipment ID (required)
     * @param  \Bigcommerce\OrdersV2\Model\OrderShipmentPut $order_shipment_put (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateOrderShipment'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function updateOrderShipmentRequest($order_id, $shipment_id, $order_shipment_put, string $contentType = self::contentTypes['updateOrderShipment'][0])
    {

        // verify the required parameter 'order_id' is set
        if ($order_id === null || (is_array($order_id) && count($order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_id when calling updateOrderShipment'
            );
        }

        // verify the required parameter 'shipment_id' is set
        if ($shipment_id === null || (is_array($shipment_id) && count($shipment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $shipment_id when calling updateOrderShipment'
            );
        }

        // verify the required parameter 'order_shipment_put' is set
        if ($order_shipment_put === null || (is_array($order_shipment_put) && count($order_shipment_put) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $order_shipment_put when calling updateOrderShipment'
            );
        }


        $resourcePath = '/orders/{order_id}/shipments/{shipment_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'order_id' . '}',
                ObjectSerializer::toPathValue($order_id),
                $resourcePath
            );
        }
        // path params
        if ($shipment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'shipment_id' . '}',
                ObjectSerializer::toPathValue($shipment_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['application/json', ],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (isset($order_shipment_put)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($order_shipment_put));
            } else {
                $httpBody = $order_shipment_put;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('X-Auth-Token');
        if ($apiKey !== null) {
            $headers['X-Auth-Token'] = $apiKey;
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'PUT',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option
     *
     * @throws \RuntimeException on file opening failure
     * @return array of http client options
     */
    protected function createHttpClientOption()
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile());
            }
        }

        return $options;
    }

    private function handleResponseWithDataType(
        string $dataType,
        RequestInterface $request,
        ResponseInterface $response
    ): array {
        if ($dataType === '\SplFileObject') {
            $content = $response->getBody(); //stream goes to serializer
        } else {
            $content = (string) $response->getBody();
            if ($dataType !== 'string') {
                try {
                    $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR);
                } catch (\JsonException $exception) {
                    throw new ApiException(
                        sprintf(
                            'Error JSON decoding server response (%s)',
                            $request->getUri()
                        ),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                        $content
                    );
                }
            }
        }

        return [
            ObjectSerializer::deserialize($content, $dataType, []),
            $response->getStatusCode(),
            $response->getHeaders()
        ];
    }

    private function responseWithinRangeCode(
        string $rangeCode,
        int $statusCode
    ): bool {
        $left = (int) ($rangeCode[0].'00');
        $right = (int) ($rangeCode[0].'99');

        return $statusCode >= $left && $statusCode <= $right;
    }
}
