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

/**
 * Fortnox API
 *
 * # Documentation   The Fortnox API is organized around REST. This means that we’ve designed it to have resource-oriented URLs and be as predictable as possible for you as developer.  It also means that we use HTTP status codes when something goes wrong and HTTP verbs understod by many API clients around the web.  We use a modified version of OAuth2 for authentication to offer a secure way for both you and our users to interact.  The API is generally built to support both XML and JSON but in this documentation all the examples will be in JSON.  We encourage you to read all the articles in the [Guides & Good to Know section](https://www.fortnox.se/developer/guides-and-good-to-know/)</a> first, before going forward and learning about the different resources.  This to ensure you get an understanding of some of the shared components of the API such as parameters and error handling.  ## Rate limits  The limit per access-token is 25 requests per 5 seconds. This equals to 300 requests per minute.  [Read more about this here.](https://www.fortnox.se/developer/guides-and-good-to-know/rate-limits-for-fortnox-api/)  ## Query parameters  Use query parameters with the ?-character and separate parameters with the &-character.   **Example:**  GET - https://api.fortnox.se/3/invoices?accountnumberfrom=3000&accountnumberto=4000 Read more about our parameters [here](https://www.fortnox.se/developer/guides-and-good-to-know/parameters/)   Search the documentation using the search field in the top left corner.
 *
 * The version of the OpenAPI document: 
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.19.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 Fortnox\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 Fortnox\ApiException;
use Fortnox\Configuration;
use Fortnox\FormDataProcessor;
use Fortnox\HeaderSelector;
use Fortnox\ObjectSerializer;

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'create10' => [
            'application/json',
        ],
        'get16' => [
            'application/json',
        ],
        'getAll8' => [
            'application/json',
        ],
        'getRequiredProductionParts' => [
            'application/json',
        ],
        'release7' => [
            'application/json',
        ],
        'update5' => [
            'application/json',
        ],
        'updateNote2' => [
            'application/json',
        ],
        'voidProductionOrder' => [
            '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 create10
     *
     * Create a new production order
     *
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order to create &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['create10'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException
     */
    public function create10($production_order = null, string $contentType = self::contentTypes['create10'][0])
    {
        list($response) = $this->create10WithHttpInfo($production_order, $contentType);
        return $response;
    }

    /**
     * Operation create10WithHttpInfo
     *
     * Create a new production order
     *
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order to create &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['create10'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException, HTTP status code, HTTP response headers (array of strings)
     */
    public function create10WithHttpInfo($production_order = null, string $contentType = self::contentTypes['create10'][0])
    {
        $request = $this->create10Request($production_order, $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(
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\WarehouseWebException',
                        $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(
                '\Fortnox\Model\WarehouseProductionOrder',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 201:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation create10Async
     *
     * Create a new production order
     *
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order to create &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['create10'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function create10Async($production_order = null, string $contentType = self::contentTypes['create10'][0])
    {
        return $this->create10AsyncWithHttpInfo($production_order, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation create10AsyncWithHttpInfo
     *
     * Create a new production order
     *
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order to create &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['create10'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function create10AsyncWithHttpInfo($production_order = null, string $contentType = self::contentTypes['create10'][0])
    {
        $returnType = '\Fortnox\Model\WarehouseProductionOrder';
        $request = $this->create10Request($production_order, $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 'create10'
     *
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order to create &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['create10'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function create10Request($production_order = null, string $contentType = self::contentTypes['create10'][0])
    {



        $resourcePath = '/api/warehouse/productionorders-v1';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;





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

        // for model (json/xml)
        if (isset($production_order)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($production_order));
            } else {
                $httpBody = $production_order;
            }
        } 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);
            }
        }


        $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 get16
     *
     * Get Production Order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['get16'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException
     */
    public function get16($id, string $contentType = self::contentTypes['get16'][0])
    {
        list($response) = $this->get16WithHttpInfo($id, $contentType);
        return $response;
    }

    /**
     * Operation get16WithHttpInfo
     *
     * Get Production Order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['get16'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException, HTTP status code, HTTP response headers (array of strings)
     */
    public function get16WithHttpInfo($id, string $contentType = self::contentTypes['get16'][0])
    {
        $request = $this->get16Request($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(
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\WarehouseWebException',
                        $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(
                '\Fortnox\Model\WarehouseProductionOrder',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation get16Async
     *
     * Get Production Order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['get16'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function get16Async($id, string $contentType = self::contentTypes['get16'][0])
    {
        return $this->get16AsyncWithHttpInfo($id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation get16AsyncWithHttpInfo
     *
     * Get Production Order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['get16'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function get16AsyncWithHttpInfo($id, string $contentType = self::contentTypes['get16'][0])
    {
        $returnType = '\Fortnox\Model\WarehouseProductionOrder';
        $request = $this->get16Request($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 'get16'
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['get16'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function get16Request($id, string $contentType = self::contentTypes['get16'][0])
    {

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


        $resourcePath = '/api/warehouse/productionorders-v1/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($id !== null) {
            $resourcePath = str_replace(
                '{' . 'id' . '}',
                ObjectSerializer::toPathValue($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);
            }
        }


        $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 getAll8
     *
     * List production orders
     *
     * @param  string|null $state Include only production orders with the given state.               Allowed states: all, incomplete, delayed, completed, voided.               (Default is incomplete) (optional)
     * @param  string|null $item_id Include only production orders with the given production item. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAll8'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException
     */
    public function getAll8($state = null, $item_id = null, string $contentType = self::contentTypes['getAll8'][0])
    {
        list($response) = $this->getAll8WithHttpInfo($state, $item_id, $contentType);
        return $response;
    }

    /**
     * Operation getAll8WithHttpInfo
     *
     * List production orders
     *
     * @param  string|null $state Include only production orders with the given state.               Allowed states: all, incomplete, delayed, completed, voided.               (Default is incomplete) (optional)
     * @param  string|null $item_id Include only production orders with the given production item. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAll8'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException, HTTP status code, HTTP response headers (array of strings)
     */
    public function getAll8WithHttpInfo($state = null, $item_id = null, string $contentType = self::contentTypes['getAll8'][0])
    {
        $request = $this->getAll8Request($state, $item_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(
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\WarehouseWebException',
                        $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(
                '\Fortnox\Model\WarehouseProductionOrder',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getAll8Async
     *
     * List production orders
     *
     * @param  string|null $state Include only production orders with the given state.               Allowed states: all, incomplete, delayed, completed, voided.               (Default is incomplete) (optional)
     * @param  string|null $item_id Include only production orders with the given production item. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAll8'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAll8Async($state = null, $item_id = null, string $contentType = self::contentTypes['getAll8'][0])
    {
        return $this->getAll8AsyncWithHttpInfo($state, $item_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getAll8AsyncWithHttpInfo
     *
     * List production orders
     *
     * @param  string|null $state Include only production orders with the given state.               Allowed states: all, incomplete, delayed, completed, voided.               (Default is incomplete) (optional)
     * @param  string|null $item_id Include only production orders with the given production item. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAll8'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAll8AsyncWithHttpInfo($state = null, $item_id = null, string $contentType = self::contentTypes['getAll8'][0])
    {
        $returnType = '\Fortnox\Model\WarehouseProductionOrder';
        $request = $this->getAll8Request($state, $item_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 'getAll8'
     *
     * @param  string|null $state Include only production orders with the given state.               Allowed states: all, incomplete, delayed, completed, voided.               (Default is incomplete) (optional)
     * @param  string|null $item_id Include only production orders with the given production item. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getAll8'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getAll8Request($state = null, $item_id = null, string $contentType = self::contentTypes['getAll8'][0])
    {




        $resourcePath = '/api/warehouse/productionorders-v1';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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




        $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);
            }
        }


        $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 getRequiredProductionParts
     *
     * Get the package items (Bill Of Materials, BOMs) for a production article
     *
     * @param  string $item_id Production Article id (required)
     * @param  int|null $id the id of the production order (optional) (optional)
     * @param  string|null $quantity the quantity of the production order (assumed 1 if left empty) (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getRequiredProductionParts'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Fortnox\Model\WarehousePackageItem|\Fortnox\Model\WarehouseWebException
     */
    public function getRequiredProductionParts($item_id, $id = null, $quantity = null, string $contentType = self::contentTypes['getRequiredProductionParts'][0])
    {
        list($response) = $this->getRequiredProductionPartsWithHttpInfo($item_id, $id, $quantity, $contentType);
        return $response;
    }

    /**
     * Operation getRequiredProductionPartsWithHttpInfo
     *
     * Get the package items (Bill Of Materials, BOMs) for a production article
     *
     * @param  string $item_id Production Article id (required)
     * @param  int|null $id the id of the production order (optional) (optional)
     * @param  string|null $quantity the quantity of the production order (assumed 1 if left empty) (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getRequiredProductionParts'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Fortnox\Model\WarehousePackageItem|\Fortnox\Model\WarehouseWebException, HTTP status code, HTTP response headers (array of strings)
     */
    public function getRequiredProductionPartsWithHttpInfo($item_id, $id = null, $quantity = null, string $contentType = self::contentTypes['getRequiredProductionParts'][0])
    {
        $request = $this->getRequiredProductionPartsRequest($item_id, $id, $quantity, $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(
                        '\Fortnox\Model\WarehousePackageItem',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\WarehouseWebException',
                        $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(
                '\Fortnox\Model\WarehousePackageItem',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehousePackageItem',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getRequiredProductionPartsAsync
     *
     * Get the package items (Bill Of Materials, BOMs) for a production article
     *
     * @param  string $item_id Production Article id (required)
     * @param  int|null $id the id of the production order (optional) (optional)
     * @param  string|null $quantity the quantity of the production order (assumed 1 if left empty) (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getRequiredProductionParts'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRequiredProductionPartsAsync($item_id, $id = null, $quantity = null, string $contentType = self::contentTypes['getRequiredProductionParts'][0])
    {
        return $this->getRequiredProductionPartsAsyncWithHttpInfo($item_id, $id, $quantity, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getRequiredProductionPartsAsyncWithHttpInfo
     *
     * Get the package items (Bill Of Materials, BOMs) for a production article
     *
     * @param  string $item_id Production Article id (required)
     * @param  int|null $id the id of the production order (optional) (optional)
     * @param  string|null $quantity the quantity of the production order (assumed 1 if left empty) (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getRequiredProductionParts'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRequiredProductionPartsAsyncWithHttpInfo($item_id, $id = null, $quantity = null, string $contentType = self::contentTypes['getRequiredProductionParts'][0])
    {
        $returnType = '\Fortnox\Model\WarehousePackageItem';
        $request = $this->getRequiredProductionPartsRequest($item_id, $id, $quantity, $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 'getRequiredProductionParts'
     *
     * @param  string $item_id Production Article id (required)
     * @param  int|null $id the id of the production order (optional) (optional)
     * @param  string|null $quantity the quantity of the production order (assumed 1 if left empty) (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getRequiredProductionParts'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getRequiredProductionPartsRequest($item_id, $id = null, $quantity = null, string $contentType = self::contentTypes['getRequiredProductionParts'][0])
    {

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




        $resourcePath = '/api/warehouse/productionorders-v1/billofmaterials/{itemId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


        // path params
        if ($item_id !== null) {
            $resourcePath = str_replace(
                '{' . 'itemId' . '}',
                ObjectSerializer::toPathValue($item_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);
            }
        }


        $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 release7
     *
     * Release a production order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['release7'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException
     */
    public function release7($id, string $contentType = self::contentTypes['release7'][0])
    {
        list($response) = $this->release7WithHttpInfo($id, $contentType);
        return $response;
    }

    /**
     * Operation release7WithHttpInfo
     *
     * Release a production order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['release7'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException, HTTP status code, HTTP response headers (array of strings)
     */
    public function release7WithHttpInfo($id, string $contentType = self::contentTypes['release7'][0])
    {
        $request = $this->release7Request($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(
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\WarehouseWebException',
                        $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(
                '\Fortnox\Model\WarehouseProductionOrder',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation release7Async
     *
     * Release a production order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['release7'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function release7Async($id, string $contentType = self::contentTypes['release7'][0])
    {
        return $this->release7AsyncWithHttpInfo($id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation release7AsyncWithHttpInfo
     *
     * Release a production order document
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['release7'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function release7AsyncWithHttpInfo($id, string $contentType = self::contentTypes['release7'][0])
    {
        $returnType = '\Fortnox\Model\WarehouseProductionOrder';
        $request = $this->release7Request($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 'release7'
     *
     * @param  int $id Production Order document id. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['release7'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function release7Request($id, string $contentType = self::contentTypes['release7'][0])
    {

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


        $resourcePath = '/api/warehouse/productionorders-v1/release/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($id !== null) {
            $resourcePath = str_replace(
                '{' . 'id' . '}',
                ObjectSerializer::toPathValue($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);
            }
        }


        $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
        );
    }

    /**
     * Operation update5
     *
     * Update a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order data see &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['update5'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException
     */
    public function update5($id, $production_order = null, string $contentType = self::contentTypes['update5'][0])
    {
        list($response) = $this->update5WithHttpInfo($id, $production_order, $contentType);
        return $response;
    }

    /**
     * Operation update5WithHttpInfo
     *
     * Update a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order data see &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['update5'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException, HTTP status code, HTTP response headers (array of strings)
     */
    public function update5WithHttpInfo($id, $production_order = null, string $contentType = self::contentTypes['update5'][0])
    {
        $request = $this->update5Request($id, $production_order, $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(
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\WarehouseWebException',
                        $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(
                '\Fortnox\Model\WarehouseProductionOrder',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation update5Async
     *
     * Update a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order data see &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['update5'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function update5Async($id, $production_order = null, string $contentType = self::contentTypes['update5'][0])
    {
        return $this->update5AsyncWithHttpInfo($id, $production_order, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation update5AsyncWithHttpInfo
     *
     * Update a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order data see &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['update5'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function update5AsyncWithHttpInfo($id, $production_order = null, string $contentType = self::contentTypes['update5'][0])
    {
        $returnType = '\Fortnox\Model\WarehouseProductionOrder';
        $request = $this->update5Request($id, $production_order, $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 'update5'
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrder|null $production_order the production order data see &lt;code&gt;ProductionOrder&lt;/code&gt; (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['update5'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function update5Request($id, $production_order = null, string $contentType = self::contentTypes['update5'][0])
    {

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



        $resourcePath = '/api/warehouse/productionorders-v1/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

        // for model (json/xml)
        if (isset($production_order)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($production_order));
            } else {
                $httpBody = $production_order;
            }
        } 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);
            }
        }


        $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
        );
    }

    /**
     * Operation updateNote2
     *
     * Update the note of a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrderPatch|null $production_order_patch contains data to be patched onto the production order (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateNote2'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException
     */
    public function updateNote2($id, $production_order_patch = null, string $contentType = self::contentTypes['updateNote2'][0])
    {
        list($response) = $this->updateNote2WithHttpInfo($id, $production_order_patch, $contentType);
        return $response;
    }

    /**
     * Operation updateNote2WithHttpInfo
     *
     * Update the note of a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrderPatch|null $production_order_patch contains data to be patched onto the production order (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateNote2'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \Fortnox\Model\WarehouseProductionOrder|\Fortnox\Model\WarehouseWebException, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateNote2WithHttpInfo($id, $production_order_patch = null, string $contentType = self::contentTypes['updateNote2'][0])
    {
        $request = $this->updateNote2Request($id, $production_order_patch, $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(
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\WarehouseWebException',
                        $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(
                '\Fortnox\Model\WarehouseProductionOrder',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseProductionOrder',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation updateNote2Async
     *
     * Update the note of a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrderPatch|null $production_order_patch contains data to be patched onto the production order (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateNote2'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateNote2Async($id, $production_order_patch = null, string $contentType = self::contentTypes['updateNote2'][0])
    {
        return $this->updateNote2AsyncWithHttpInfo($id, $production_order_patch, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation updateNote2AsyncWithHttpInfo
     *
     * Update the note of a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrderPatch|null $production_order_patch contains data to be patched onto the production order (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateNote2'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateNote2AsyncWithHttpInfo($id, $production_order_patch = null, string $contentType = self::contentTypes['updateNote2'][0])
    {
        $returnType = '\Fortnox\Model\WarehouseProductionOrder';
        $request = $this->updateNote2Request($id, $production_order_patch, $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 'updateNote2'
     *
     * @param  int $id Production Order document id. (required)
     * @param  \Fortnox\Model\WarehouseProductionOrderPatch|null $production_order_patch contains data to be patched onto the production order (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['updateNote2'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function updateNote2Request($id, $production_order_patch = null, string $contentType = self::contentTypes['updateNote2'][0])
    {

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



        $resourcePath = '/api/warehouse/productionorders-v1/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

        // for model (json/xml)
        if (isset($production_order_patch)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($production_order_patch));
            } else {
                $httpBody = $production_order_patch;
            }
        } 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);
            }
        }


        $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(
            'PATCH',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation voidProductionOrder
     *
     * Void a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  bool|null $force true to force void a released document, default false (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voidProductionOrder'] to see the possible values for this operation
     *
     * @throws \Fortnox\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return void
     */
    public function voidProductionOrder($id, $force = null, string $contentType = self::contentTypes['voidProductionOrder'][0])
    {
        $this->voidProductionOrderWithHttpInfo($id, $force, $contentType);
    }

    /**
     * Operation voidProductionOrderWithHttpInfo
     *
     * Void a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  bool|null $force true to force void a released document, default false (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voidProductionOrder'] to see the possible values for this operation
     *
     * @throws \Fortnox\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 voidProductionOrderWithHttpInfo($id, $force = null, string $contentType = self::contentTypes['voidProductionOrder'][0])
    {
        $request = $this->voidProductionOrderRequest($id, $force, $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()) {
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\WarehouseWebException',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation voidProductionOrderAsync
     *
     * Void a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  bool|null $force true to force void a released document, default false (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voidProductionOrder'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voidProductionOrderAsync($id, $force = null, string $contentType = self::contentTypes['voidProductionOrder'][0])
    {
        return $this->voidProductionOrderAsyncWithHttpInfo($id, $force, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation voidProductionOrderAsyncWithHttpInfo
     *
     * Void a production order
     *
     * @param  int $id Production Order document id. (required)
     * @param  bool|null $force true to force void a released document, default false (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voidProductionOrder'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voidProductionOrderAsyncWithHttpInfo($id, $force = null, string $contentType = self::contentTypes['voidProductionOrder'][0])
    {
        $returnType = '';
        $request = $this->voidProductionOrderRequest($id, $force, $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 'voidProductionOrder'
     *
     * @param  int $id Production Order document id. (required)
     * @param  bool|null $force true to force void a released document, default false (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voidProductionOrder'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function voidProductionOrderRequest($id, $force = null, string $contentType = self::contentTypes['voidProductionOrder'][0])
    {

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



        $resourcePath = '/api/warehouse/productionorders-v1/void/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


        // path params
        if ($id !== null) {
            $resourcePath = str_replace(
                '{' . 'id' . '}',
                ObjectSerializer::toPathValue($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);
            }
        }


        $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());
            }
        }

        if ($this->config->getCertFile()) {
            $options[RequestOptions::CERT] = $this->config->getCertFile();
        }

        if ($this->config->getKeyFile()) {
            $options[RequestOptions::SSL_KEY] = $this->config->getKeyFile();
        }

        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;
    }
}
