<?php
/**
 * FortnoxOffersApi
 * 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;

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'offerControllerDoCreate' => [
            'application/json',
        ],
        'offerControllerDoIndex' => [
            'application/json',
        ],
        'offerControllerDoShow' => [
            'application/json',
        ],
        'offerControllerDoShowAndEmail' => [
            'application/json',
        ],
        'offerControllerDoShowAndPreview' => [
            'application/json',
        ],
        'offerControllerDoShowAndPrint' => [
            'application/json',
        ],
        'offerControllerDoUpdate' => [
            'application/json',
        ],
        'offerControllerDoUpdateAndCancel' => [
            'application/json',
        ],
        'offerControllerDoUpdateAndCreateInvoice' => [
            'application/json',
        ],
        'offerControllerDoUpdateAndCreateOrder' => [
            'application/json',
        ],
        'offerControllerDoUpdateAndExternalPrint' => [
            '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 offerControllerDoCreate
     *
     * Create an offer
     *
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for create offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoCreate'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoCreate($offer = null, string $contentType = self::contentTypes['offerControllerDoCreate'][0])
    {
        list($response) = $this->offerControllerDoCreateWithHttpInfo($offer, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoCreateWithHttpInfo
     *
     * Create an offer
     *
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for create offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoCreate'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoCreateWithHttpInfo($offer = null, string $contentType = self::contentTypes['offerControllerDoCreate'][0])
    {
        $request = $this->offerControllerDoCreateRequest($offer, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 400:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 201:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoCreateAsync
     *
     * Create an offer
     *
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for create offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoCreate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoCreateAsync($offer = null, string $contentType = self::contentTypes['offerControllerDoCreate'][0])
    {
        return $this->offerControllerDoCreateAsyncWithHttpInfo($offer, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoCreateAsyncWithHttpInfo
     *
     * Create an offer
     *
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for create offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoCreate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoCreateAsyncWithHttpInfo($offer = null, string $contentType = self::contentTypes['offerControllerDoCreate'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoCreateRequest($offer, $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 'offerControllerDoCreate'
     *
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for create offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoCreate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoCreateRequest($offer = null, string $contentType = self::contentTypes['offerControllerDoCreate'][0])
    {



        $resourcePath = '/3/offers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;





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

        // for model (json/xml)
        if (isset($offer)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($offer));
            } else {
                $httpBody = $offer;
            }
        } 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 offerControllerDoIndex
     *
     * Retrieve a list of offers
     *
     * @param  string|null $todate filter by to date (optional)
     * @param  string|null $fromdate filter by from date (optional)
     * @param  string|null $filter possibility to filter offers (optional)
     * @param  string|null $sortby sort returned list of offers (optional)
     * @param  string|null $customername filter by customer name (optional)
     * @param  string|null $customernumber filter by customer number (optional)
     * @param  string|null $documentnumber filter by document number (optional)
     * @param  string|null $costcenter filter by cost center (optional)
     * @param  string|null $label filter by label (optional)
     * @param  string|null $project filter by project (optional)
     * @param  bool|null $sent filter by sent (optional)
     * @param  bool|null $notcompleted filter by not completed (optional)
     * @param  string|null $ourreference filter by our reference (optional)
     * @param  string|null $yourreference filter by your reference (optional)
     * @param  string|null $lastmodified filter by last modified (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoIndex'] 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\FortnoxOfferOfferListResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoIndex($todate = null, $fromdate = null, $filter = null, $sortby = null, $customername = null, $customernumber = null, $documentnumber = null, $costcenter = null, $label = null, $project = null, $sent = null, $notcompleted = null, $ourreference = null, $yourreference = null, $lastmodified = null, string $contentType = self::contentTypes['offerControllerDoIndex'][0])
    {
        list($response) = $this->offerControllerDoIndexWithHttpInfo($todate, $fromdate, $filter, $sortby, $customername, $customernumber, $documentnumber, $costcenter, $label, $project, $sent, $notcompleted, $ourreference, $yourreference, $lastmodified, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoIndexWithHttpInfo
     *
     * Retrieve a list of offers
     *
     * @param  string|null $todate filter by to date (optional)
     * @param  string|null $fromdate filter by from date (optional)
     * @param  string|null $filter possibility to filter offers (optional)
     * @param  string|null $sortby sort returned list of offers (optional)
     * @param  string|null $customername filter by customer name (optional)
     * @param  string|null $customernumber filter by customer number (optional)
     * @param  string|null $documentnumber filter by document number (optional)
     * @param  string|null $costcenter filter by cost center (optional)
     * @param  string|null $label filter by label (optional)
     * @param  string|null $project filter by project (optional)
     * @param  bool|null $sent filter by sent (optional)
     * @param  bool|null $notcompleted filter by not completed (optional)
     * @param  string|null $ourreference filter by our reference (optional)
     * @param  string|null $yourreference filter by your reference (optional)
     * @param  string|null $lastmodified filter by last modified (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoIndex'] 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\FortnoxOfferOfferListResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoIndexWithHttpInfo($todate = null, $fromdate = null, $filter = null, $sortby = null, $customername = null, $customernumber = null, $documentnumber = null, $costcenter = null, $label = null, $project = null, $sent = null, $notcompleted = null, $ourreference = null, $yourreference = null, $lastmodified = null, string $contentType = self::contentTypes['offerControllerDoIndex'][0])
    {
        $request = $this->offerControllerDoIndexRequest($todate, $fromdate, $filter, $sortby, $customername, $customernumber, $documentnumber, $costcenter, $label, $project, $sent, $notcompleted, $ourreference, $yourreference, $lastmodified, $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\FortnoxOfferOfferListResponseWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferListResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferListResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoIndexAsync
     *
     * Retrieve a list of offers
     *
     * @param  string|null $todate filter by to date (optional)
     * @param  string|null $fromdate filter by from date (optional)
     * @param  string|null $filter possibility to filter offers (optional)
     * @param  string|null $sortby sort returned list of offers (optional)
     * @param  string|null $customername filter by customer name (optional)
     * @param  string|null $customernumber filter by customer number (optional)
     * @param  string|null $documentnumber filter by document number (optional)
     * @param  string|null $costcenter filter by cost center (optional)
     * @param  string|null $label filter by label (optional)
     * @param  string|null $project filter by project (optional)
     * @param  bool|null $sent filter by sent (optional)
     * @param  bool|null $notcompleted filter by not completed (optional)
     * @param  string|null $ourreference filter by our reference (optional)
     * @param  string|null $yourreference filter by your reference (optional)
     * @param  string|null $lastmodified filter by last modified (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoIndexAsync($todate = null, $fromdate = null, $filter = null, $sortby = null, $customername = null, $customernumber = null, $documentnumber = null, $costcenter = null, $label = null, $project = null, $sent = null, $notcompleted = null, $ourreference = null, $yourreference = null, $lastmodified = null, string $contentType = self::contentTypes['offerControllerDoIndex'][0])
    {
        return $this->offerControllerDoIndexAsyncWithHttpInfo($todate, $fromdate, $filter, $sortby, $customername, $customernumber, $documentnumber, $costcenter, $label, $project, $sent, $notcompleted, $ourreference, $yourreference, $lastmodified, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoIndexAsyncWithHttpInfo
     *
     * Retrieve a list of offers
     *
     * @param  string|null $todate filter by to date (optional)
     * @param  string|null $fromdate filter by from date (optional)
     * @param  string|null $filter possibility to filter offers (optional)
     * @param  string|null $sortby sort returned list of offers (optional)
     * @param  string|null $customername filter by customer name (optional)
     * @param  string|null $customernumber filter by customer number (optional)
     * @param  string|null $documentnumber filter by document number (optional)
     * @param  string|null $costcenter filter by cost center (optional)
     * @param  string|null $label filter by label (optional)
     * @param  string|null $project filter by project (optional)
     * @param  bool|null $sent filter by sent (optional)
     * @param  bool|null $notcompleted filter by not completed (optional)
     * @param  string|null $ourreference filter by our reference (optional)
     * @param  string|null $yourreference filter by your reference (optional)
     * @param  string|null $lastmodified filter by last modified (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoIndexAsyncWithHttpInfo($todate = null, $fromdate = null, $filter = null, $sortby = null, $customername = null, $customernumber = null, $documentnumber = null, $costcenter = null, $label = null, $project = null, $sent = null, $notcompleted = null, $ourreference = null, $yourreference = null, $lastmodified = null, string $contentType = self::contentTypes['offerControllerDoIndex'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferListResponseWrap';
        $request = $this->offerControllerDoIndexRequest($todate, $fromdate, $filter, $sortby, $customername, $customernumber, $documentnumber, $costcenter, $label, $project, $sent, $notcompleted, $ourreference, $yourreference, $lastmodified, $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 'offerControllerDoIndex'
     *
     * @param  string|null $todate filter by to date (optional)
     * @param  string|null $fromdate filter by from date (optional)
     * @param  string|null $filter possibility to filter offers (optional)
     * @param  string|null $sortby sort returned list of offers (optional)
     * @param  string|null $customername filter by customer name (optional)
     * @param  string|null $customernumber filter by customer number (optional)
     * @param  string|null $documentnumber filter by document number (optional)
     * @param  string|null $costcenter filter by cost center (optional)
     * @param  string|null $label filter by label (optional)
     * @param  string|null $project filter by project (optional)
     * @param  bool|null $sent filter by sent (optional)
     * @param  bool|null $notcompleted filter by not completed (optional)
     * @param  string|null $ourreference filter by our reference (optional)
     * @param  string|null $yourreference filter by your reference (optional)
     * @param  string|null $lastmodified filter by last modified (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoIndexRequest($todate = null, $fromdate = null, $filter = null, $sortby = null, $customername = null, $customernumber = null, $documentnumber = null, $costcenter = null, $label = null, $project = null, $sent = null, $notcompleted = null, $ourreference = null, $yourreference = null, $lastmodified = null, string $contentType = self::contentTypes['offerControllerDoIndex'][0])
    {

















        $resourcePath = '/3/offers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $todate,
            'todate', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $fromdate,
            'fromdate', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $filter,
            'filter', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $sortby,
            'sortby', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $customername,
            'customername', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $customernumber,
            'customernumber', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $documentnumber,
            'documentnumber', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $costcenter,
            'costcenter', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $label,
            'label', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $project,
            'project', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $sent,
            'sent', // param base name
            'boolean', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $notcompleted,
            'notcompleted', // param base name
            'boolean', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $ourreference,
            'ourreference', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $yourreference,
            'yourreference', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $lastmodified,
            'lastmodified', // 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 offerControllerDoShow
     *
     * Retrieve a single offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShow'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoShow($document_number, string $contentType = self::contentTypes['offerControllerDoShow'][0])
    {
        list($response) = $this->offerControllerDoShowWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoShowWithHttpInfo
     *
     * Retrieve a single offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShow'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoShowWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShow'][0])
    {
        $request = $this->offerControllerDoShowRequest($document_number, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoShowAsync
     *
     * Retrieve a single offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShow'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAsync($document_number, string $contentType = self::contentTypes['offerControllerDoShow'][0])
    {
        return $this->offerControllerDoShowAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoShowAsyncWithHttpInfo
     *
     * Retrieve a single offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShow'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAsyncWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShow'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoShowRequest($document_number, $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 'offerControllerDoShow'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShow'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoShowRequest($document_number, string $contentType = self::contentTypes['offerControllerDoShow'][0])
    {

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


        $resourcePath = '/3/offers/{DocumentNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($document_number !== null) {
            $resourcePath = str_replace(
                '{' . 'DocumentNumber' . '}',
                ObjectSerializer::toPathValue($document_number),
                $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 offerControllerDoShowAndEmail
     *
     * Send given offer as email
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndEmail'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoShowAndEmail($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndEmail'][0])
    {
        list($response) = $this->offerControllerDoShowAndEmailWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoShowAndEmailWithHttpInfo
     *
     * Send given offer as email
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndEmail'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoShowAndEmailWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndEmail'][0])
    {
        $request = $this->offerControllerDoShowAndEmailRequest($document_number, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoShowAndEmailAsync
     *
     * Send given offer as email
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndEmail'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAndEmailAsync($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndEmail'][0])
    {
        return $this->offerControllerDoShowAndEmailAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoShowAndEmailAsyncWithHttpInfo
     *
     * Send given offer as email
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndEmail'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAndEmailAsyncWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndEmail'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoShowAndEmailRequest($document_number, $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 'offerControllerDoShowAndEmail'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndEmail'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoShowAndEmailRequest($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndEmail'][0])
    {

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


        $resourcePath = '/3/offers/{DocumentNumber}/email';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // path params
        if ($document_number !== null) {
            $resourcePath = str_replace(
                '{' . 'DocumentNumber' . '}',
                ObjectSerializer::toPathValue($document_number),
                $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 offerControllerDoShowAndPreview
     *
     * Preview given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPreview'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoShowAndPreview($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPreview'][0])
    {
        list($response) = $this->offerControllerDoShowAndPreviewWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoShowAndPreviewWithHttpInfo
     *
     * Preview given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPreview'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoShowAndPreviewWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPreview'][0])
    {
        $request = $this->offerControllerDoShowAndPreviewRequest($document_number, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoShowAndPreviewAsync
     *
     * Preview given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPreview'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAndPreviewAsync($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPreview'][0])
    {
        return $this->offerControllerDoShowAndPreviewAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoShowAndPreviewAsyncWithHttpInfo
     *
     * Preview given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPreview'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAndPreviewAsyncWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPreview'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoShowAndPreviewRequest($document_number, $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 'offerControllerDoShowAndPreview'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPreview'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoShowAndPreviewRequest($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPreview'][0])
    {

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


        $resourcePath = '/3/offers/{DocumentNumber}/preview';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


        $headers = $this->headerSelector->selectHeaders(
            ['application/pdf', '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 offerControllerDoShowAndPrint
     *
     * Print given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPrint'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoShowAndPrint($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPrint'][0])
    {
        list($response) = $this->offerControllerDoShowAndPrintWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoShowAndPrintWithHttpInfo
     *
     * Print given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPrint'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoShowAndPrintWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPrint'][0])
    {
        $request = $this->offerControllerDoShowAndPrintRequest($document_number, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoShowAndPrintAsync
     *
     * Print given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAndPrintAsync($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPrint'][0])
    {
        return $this->offerControllerDoShowAndPrintAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoShowAndPrintAsyncWithHttpInfo
     *
     * Print given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoShowAndPrintAsyncWithHttpInfo($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPrint'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoShowAndPrintRequest($document_number, $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 'offerControllerDoShowAndPrint'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoShowAndPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoShowAndPrintRequest($document_number, string $contentType = self::contentTypes['offerControllerDoShowAndPrint'][0])
    {

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


        $resourcePath = '/3/offers/{DocumentNumber}/print';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


        $headers = $this->headerSelector->selectHeaders(
            ['application/pdf', '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 offerControllerDoUpdate
     *
     * Update an offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdate'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoUpdate($document_number, $offer = null, string $contentType = self::contentTypes['offerControllerDoUpdate'][0])
    {
        list($response) = $this->offerControllerDoUpdateWithHttpInfo($document_number, $offer, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoUpdateWithHttpInfo
     *
     * Update an offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdate'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoUpdateWithHttpInfo($document_number, $offer = null, string $contentType = self::contentTypes['offerControllerDoUpdate'][0])
    {
        $request = $this->offerControllerDoUpdateRequest($document_number, $offer, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoUpdateAsync
     *
     * Update an offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAsync($document_number, $offer = null, string $contentType = self::contentTypes['offerControllerDoUpdate'][0])
    {
        return $this->offerControllerDoUpdateAsyncWithHttpInfo($document_number, $offer, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoUpdateAsyncWithHttpInfo
     *
     * Update an offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAsyncWithHttpInfo($document_number, $offer = null, string $contentType = self::contentTypes['offerControllerDoUpdate'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoUpdateRequest($document_number, $offer, $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 'offerControllerDoUpdate'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $offer Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoUpdateRequest($document_number, $offer = null, string $contentType = self::contentTypes['offerControllerDoUpdate'][0])
    {

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



        $resourcePath = '/3/offers/{DocumentNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

        // for model (json/xml)
        if (isset($offer)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($offer));
            } else {
                $httpBody = $offer;
            }
        } 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 offerControllerDoUpdateAndCancel
     *
     * Cancels given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCancel'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoUpdateAndCancel($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCancel'][0])
    {
        list($response) = $this->offerControllerDoUpdateAndCancelWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoUpdateAndCancelWithHttpInfo
     *
     * Cancels given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCancel'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoUpdateAndCancelWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCancel'][0])
    {
        $request = $this->offerControllerDoUpdateAndCancelRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoUpdateAndCancelAsync
     *
     * Cancels given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCancel'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndCancelAsync($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCancel'][0])
    {
        return $this->offerControllerDoUpdateAndCancelAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoUpdateAndCancelAsyncWithHttpInfo
     *
     * Cancels given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCancel'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndCancelAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCancel'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoUpdateAndCancelRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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 'offerControllerDoUpdateAndCancel'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCancel'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoUpdateAndCancelRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCancel'][0])
    {

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



        $resourcePath = '/3/offers/{DocumentNumber}/cancel';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

        // for model (json/xml)
        if (isset($fortnox_offer_offer_single_payload_item_wrap)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fortnox_offer_offer_single_payload_item_wrap));
            } else {
                $httpBody = $fortnox_offer_offer_single_payload_item_wrap;
            }
        } 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 offerControllerDoUpdateAndCreateInvoice
     *
     * Create invoice out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateInvoice'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoUpdateAndCreateInvoice($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateInvoice'][0])
    {
        list($response) = $this->offerControllerDoUpdateAndCreateInvoiceWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoUpdateAndCreateInvoiceWithHttpInfo
     *
     * Create invoice out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateInvoice'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoUpdateAndCreateInvoiceWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateInvoice'][0])
    {
        $request = $this->offerControllerDoUpdateAndCreateInvoiceRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoUpdateAndCreateInvoiceAsync
     *
     * Create invoice out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateInvoice'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndCreateInvoiceAsync($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateInvoice'][0])
    {
        return $this->offerControllerDoUpdateAndCreateInvoiceAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoUpdateAndCreateInvoiceAsyncWithHttpInfo
     *
     * Create invoice out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateInvoice'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndCreateInvoiceAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateInvoice'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoUpdateAndCreateInvoiceRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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 'offerControllerDoUpdateAndCreateInvoice'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateInvoice'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoUpdateAndCreateInvoiceRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateInvoice'][0])
    {

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



        $resourcePath = '/3/offers/{DocumentNumber}/createinvoice';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

        // for model (json/xml)
        if (isset($fortnox_offer_offer_single_payload_item_wrap)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fortnox_offer_offer_single_payload_item_wrap));
            } else {
                $httpBody = $fortnox_offer_offer_single_payload_item_wrap;
            }
        } 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 offerControllerDoUpdateAndCreateOrder
     *
     * Create order out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateOrder'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoUpdateAndCreateOrder($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateOrder'][0])
    {
        list($response) = $this->offerControllerDoUpdateAndCreateOrderWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoUpdateAndCreateOrderWithHttpInfo
     *
     * Create order out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateOrder'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoUpdateAndCreateOrderWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateOrder'][0])
    {
        $request = $this->offerControllerDoUpdateAndCreateOrderRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoUpdateAndCreateOrderAsync
     *
     * Create order out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateOrder'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndCreateOrderAsync($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateOrder'][0])
    {
        return $this->offerControllerDoUpdateAndCreateOrderAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoUpdateAndCreateOrderAsyncWithHttpInfo
     *
     * Create order out of given offer
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateOrder'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndCreateOrderAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateOrder'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoUpdateAndCreateOrderRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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 'offerControllerDoUpdateAndCreateOrder'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndCreateOrder'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoUpdateAndCreateOrderRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndCreateOrder'][0])
    {

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



        $resourcePath = '/3/offers/{DocumentNumber}/createorder';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

        // for model (json/xml)
        if (isset($fortnox_offer_offer_single_payload_item_wrap)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fortnox_offer_offer_single_payload_item_wrap));
            } else {
                $httpBody = $fortnox_offer_offer_single_payload_item_wrap;
            }
        } 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 offerControllerDoUpdateAndExternalPrint
     *
     * Set given offer as sent
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndExternalPrint'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function offerControllerDoUpdateAndExternalPrint($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndExternalPrint'][0])
    {
        list($response) = $this->offerControllerDoUpdateAndExternalPrintWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation offerControllerDoUpdateAndExternalPrintWithHttpInfo
     *
     * Set given offer as sent
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndExternalPrint'] 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\FortnoxOfferOfferResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function offerControllerDoUpdateAndExternalPrintWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndExternalPrint'][0])
    {
        $request = $this->offerControllerDoUpdateAndExternalPrintRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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\FortnoxOfferOfferResponseWrap',
                        $request,
                        $response,
                    );
                case 404:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxOfferOfferResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxOfferOfferResponseWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                default:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation offerControllerDoUpdateAndExternalPrintAsync
     *
     * Set given offer as sent
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndExternalPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndExternalPrintAsync($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndExternalPrint'][0])
    {
        return $this->offerControllerDoUpdateAndExternalPrintAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation offerControllerDoUpdateAndExternalPrintAsyncWithHttpInfo
     *
     * Set given offer as sent
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndExternalPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function offerControllerDoUpdateAndExternalPrintAsyncWithHttpInfo($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndExternalPrint'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxOfferOfferResponseWrap';
        $request = $this->offerControllerDoUpdateAndExternalPrintRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap, $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 'offerControllerDoUpdateAndExternalPrint'
     *
     * @param  string $document_number identifies the offer (required)
     * @param  \Fortnox\Model\FortnoxOfferOfferSinglePayloadItemWrap|null $fortnox_offer_offer_single_payload_item_wrap Request body for update offer (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['offerControllerDoUpdateAndExternalPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function offerControllerDoUpdateAndExternalPrintRequest($document_number, $fortnox_offer_offer_single_payload_item_wrap = null, string $contentType = self::contentTypes['offerControllerDoUpdateAndExternalPrint'][0])
    {

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



        $resourcePath = '/3/offers/{DocumentNumber}/externalprint';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

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

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