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

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'contractControllerDoCreate' => [
            'application/json',
        ],
        'contractControllerDoIndex' => [
            'application/json',
        ],
        'contractControllerDoShow' => [
            'application/json',
        ],
        'contractControllerDoUpdate' => [
            'application/json',
        ],
        'contractControllerDoUpdateAndCreateInvoice' => [
            'application/json',
        ],
        'contractControllerDoUpdateAndFinish' => [
            'application/json',
        ],
        'contractControllerDoUpdateAndIncreaseInvoiceCount' => [
            '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 contractControllerDoCreate
     *
     * Create a contract
     *
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractCreatePayloadWrap|null $contract Request body for create contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoCreate'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function contractControllerDoCreate($contract = null, string $contentType = self::contentTypes['contractControllerDoCreate'][0])
    {
        list($response) = $this->contractControllerDoCreateWithHttpInfo($contract, $contentType);
        return $response;
    }

    /**
     * Operation contractControllerDoCreateWithHttpInfo
     *
     * Create a contract
     *
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractCreatePayloadWrap|null $contract Request body for create contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoCreate'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function contractControllerDoCreateWithHttpInfo($contract = null, string $contentType = self::contentTypes['contractControllerDoCreate'][0])
    {
        $request = $this->contractControllerDoCreateRequest($contract, $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\FortnoxContractInvoiceContractResponseWrap',
                        $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\FortnoxContractInvoiceContractResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 201:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap',
                        $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 contractControllerDoCreateAsync
     *
     * Create a contract
     *
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractCreatePayloadWrap|null $contract Request body for create contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoCreate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoCreateAsync($contract = null, string $contentType = self::contentTypes['contractControllerDoCreate'][0])
    {
        return $this->contractControllerDoCreateAsyncWithHttpInfo($contract, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

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



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





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

        // for model (json/xml)
        if (isset($contract)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($contract));
            } else {
                $httpBody = $contract;
            }
        } 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 contractControllerDoIndex
     *
     * Retrieve a list of contracts
     *
     * @param  \DateTime|null $periodstart Filter contracts by start of contract period (optional)
     * @param  \DateTime|null $periodend Filter contracts by end of contract period (optional)
     * @param  string|null $filter Filter contracts by status (optional)
     * @param  int|null $documentnumber Filter contracts by document number (optional)
     * @param  string|null $customernumber Filter contracts by customer number (optional)
     * @param  int|null $templatenumber Filter contracts by template number (optional)
     * @param  int|null $invoicesremaining Filter contracts by number of remaining invoices (optional)
     * @param  \DateTime|null $lastmodified Filter contracts by last modified date (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoIndex'] 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\FortnoxContractInvoiceContractListResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function contractControllerDoIndex($periodstart = null, $periodend = null, $filter = null, $documentnumber = null, $customernumber = null, $templatenumber = null, $invoicesremaining = null, $lastmodified = null, string $contentType = self::contentTypes['contractControllerDoIndex'][0])
    {
        list($response) = $this->contractControllerDoIndexWithHttpInfo($periodstart, $periodend, $filter, $documentnumber, $customernumber, $templatenumber, $invoicesremaining, $lastmodified, $contentType);
        return $response;
    }

    /**
     * Operation contractControllerDoIndexWithHttpInfo
     *
     * Retrieve a list of contracts
     *
     * @param  \DateTime|null $periodstart Filter contracts by start of contract period (optional)
     * @param  \DateTime|null $periodend Filter contracts by end of contract period (optional)
     * @param  string|null $filter Filter contracts by status (optional)
     * @param  int|null $documentnumber Filter contracts by document number (optional)
     * @param  string|null $customernumber Filter contracts by customer number (optional)
     * @param  int|null $templatenumber Filter contracts by template number (optional)
     * @param  int|null $invoicesremaining Filter contracts by number of remaining invoices (optional)
     * @param  \DateTime|null $lastmodified Filter contracts by last modified date (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoIndex'] 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\FortnoxContractInvoiceContractListResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function contractControllerDoIndexWithHttpInfo($periodstart = null, $periodend = null, $filter = null, $documentnumber = null, $customernumber = null, $templatenumber = null, $invoicesremaining = null, $lastmodified = null, string $contentType = self::contentTypes['contractControllerDoIndex'][0])
    {
        $request = $this->contractControllerDoIndexRequest($periodstart, $periodend, $filter, $documentnumber, $customernumber, $templatenumber, $invoicesremaining, $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\FortnoxContractInvoiceContractListResponseWrap',
                        $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\FortnoxContractInvoiceContractListResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxContractInvoiceContractListResponseWrap',
                        $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 contractControllerDoIndexAsync
     *
     * Retrieve a list of contracts
     *
     * @param  \DateTime|null $periodstart Filter contracts by start of contract period (optional)
     * @param  \DateTime|null $periodend Filter contracts by end of contract period (optional)
     * @param  string|null $filter Filter contracts by status (optional)
     * @param  int|null $documentnumber Filter contracts by document number (optional)
     * @param  string|null $customernumber Filter contracts by customer number (optional)
     * @param  int|null $templatenumber Filter contracts by template number (optional)
     * @param  int|null $invoicesremaining Filter contracts by number of remaining invoices (optional)
     * @param  \DateTime|null $lastmodified Filter contracts by last modified date (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoIndexAsync($periodstart = null, $periodend = null, $filter = null, $documentnumber = null, $customernumber = null, $templatenumber = null, $invoicesremaining = null, $lastmodified = null, string $contentType = self::contentTypes['contractControllerDoIndex'][0])
    {
        return $this->contractControllerDoIndexAsyncWithHttpInfo($periodstart, $periodend, $filter, $documentnumber, $customernumber, $templatenumber, $invoicesremaining, $lastmodified, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation contractControllerDoIndexAsyncWithHttpInfo
     *
     * Retrieve a list of contracts
     *
     * @param  \DateTime|null $periodstart Filter contracts by start of contract period (optional)
     * @param  \DateTime|null $periodend Filter contracts by end of contract period (optional)
     * @param  string|null $filter Filter contracts by status (optional)
     * @param  int|null $documentnumber Filter contracts by document number (optional)
     * @param  string|null $customernumber Filter contracts by customer number (optional)
     * @param  int|null $templatenumber Filter contracts by template number (optional)
     * @param  int|null $invoicesremaining Filter contracts by number of remaining invoices (optional)
     * @param  \DateTime|null $lastmodified Filter contracts by last modified date (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoIndexAsyncWithHttpInfo($periodstart = null, $periodend = null, $filter = null, $documentnumber = null, $customernumber = null, $templatenumber = null, $invoicesremaining = null, $lastmodified = null, string $contentType = self::contentTypes['contractControllerDoIndex'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxContractInvoiceContractListResponseWrap';
        $request = $this->contractControllerDoIndexRequest($periodstart, $periodend, $filter, $documentnumber, $customernumber, $templatenumber, $invoicesremaining, $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 'contractControllerDoIndex'
     *
     * @param  \DateTime|null $periodstart Filter contracts by start of contract period (optional)
     * @param  \DateTime|null $periodend Filter contracts by end of contract period (optional)
     * @param  string|null $filter Filter contracts by status (optional)
     * @param  int|null $documentnumber Filter contracts by document number (optional)
     * @param  string|null $customernumber Filter contracts by customer number (optional)
     * @param  int|null $templatenumber Filter contracts by template number (optional)
     * @param  int|null $invoicesremaining Filter contracts by number of remaining invoices (optional)
     * @param  \DateTime|null $lastmodified Filter contracts by last modified date (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function contractControllerDoIndexRequest($periodstart = null, $periodend = null, $filter = null, $documentnumber = null, $customernumber = null, $templatenumber = null, $invoicesremaining = null, $lastmodified = null, string $contentType = self::contentTypes['contractControllerDoIndex'][0])
    {










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

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $periodstart,
            'periodstart', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $periodend,
            'periodend', // 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(
            $documentnumber,
            'documentnumber', // param base name
            'integer', // 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(
            $templatenumber,
            'templatenumber', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $invoicesremaining,
            'invoicesremaining', // param base name
            'integer', // 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 contractControllerDoShow
     *
     * Retrieve a single contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoShow'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function contractControllerDoShow($document_number, string $contentType = self::contentTypes['contractControllerDoShow'][0])
    {
        list($response) = $this->contractControllerDoShowWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation contractControllerDoShowWithHttpInfo
     *
     * Retrieve a single contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoShow'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function contractControllerDoShowWithHttpInfo($document_number, string $contentType = self::contentTypes['contractControllerDoShow'][0])
    {
        $request = $this->contractControllerDoShowRequest($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\FortnoxContractInvoiceContractResponseWrap',
                        $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\FortnoxContractInvoiceContractResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap',
                        $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 contractControllerDoShowAsync
     *
     * Retrieve a single contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoShow'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoShowAsync($document_number, string $contentType = self::contentTypes['contractControllerDoShow'][0])
    {
        return $this->contractControllerDoShowAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

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


        $resourcePath = '/3/contracts/{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 contractControllerDoUpdate
     *
     * Update a contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdatePayloadWrap|null $contract Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdate'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function contractControllerDoUpdate($document_number, $contract = null, string $contentType = self::contentTypes['contractControllerDoUpdate'][0])
    {
        list($response) = $this->contractControllerDoUpdateWithHttpInfo($document_number, $contract, $contentType);
        return $response;
    }

    /**
     * Operation contractControllerDoUpdateWithHttpInfo
     *
     * Update a contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdatePayloadWrap|null $contract Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdate'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function contractControllerDoUpdateWithHttpInfo($document_number, $contract = null, string $contentType = self::contentTypes['contractControllerDoUpdate'][0])
    {
        $request = $this->contractControllerDoUpdateRequest($document_number, $contract, $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\FortnoxContractInvoiceContractResponseWrap',
                        $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\FortnoxContractInvoiceContractResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap',
                        $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 contractControllerDoUpdateAsync
     *
     * Update a contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdatePayloadWrap|null $contract Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoUpdateAsync($document_number, $contract = null, string $contentType = self::contentTypes['contractControllerDoUpdate'][0])
    {
        return $this->contractControllerDoUpdateAsyncWithHttpInfo($document_number, $contract, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

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



        $resourcePath = '/3/contracts/{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($contract)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($contract));
            } else {
                $httpBody = $contract;
            }
        } 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 contractControllerDoUpdateAndCreateInvoice
     *
     * Create invoice from contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \DateTime|null $invoicedate Date of invoicing (optional)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndCreateInvoicePayloadWrap|null $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndCreateInvoice'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function contractControllerDoUpdateAndCreateInvoice($document_number, $invoicedate = null, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndCreateInvoice'][0])
    {
        list($response) = $this->contractControllerDoUpdateAndCreateInvoiceWithHttpInfo($document_number, $invoicedate, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap, $contentType);
        return $response;
    }

    /**
     * Operation contractControllerDoUpdateAndCreateInvoiceWithHttpInfo
     *
     * Create invoice from contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \DateTime|null $invoicedate Date of invoicing (optional)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndCreateInvoicePayloadWrap|null $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndCreateInvoice'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function contractControllerDoUpdateAndCreateInvoiceWithHttpInfo($document_number, $invoicedate = null, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndCreateInvoice'][0])
    {
        $request = $this->contractControllerDoUpdateAndCreateInvoiceRequest($document_number, $invoicedate, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_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\FortnoxContractInvoiceContractResponseWrap',
                        $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\FortnoxContractInvoiceContractResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap',
                        $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 contractControllerDoUpdateAndCreateInvoiceAsync
     *
     * Create invoice from contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \DateTime|null $invoicedate Date of invoicing (optional)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndCreateInvoicePayloadWrap|null $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndCreateInvoice'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoUpdateAndCreateInvoiceAsync($document_number, $invoicedate = null, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndCreateInvoice'][0])
    {
        return $this->contractControllerDoUpdateAndCreateInvoiceAsyncWithHttpInfo($document_number, $invoicedate, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation contractControllerDoUpdateAndCreateInvoiceAsyncWithHttpInfo
     *
     * Create invoice from contract
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \DateTime|null $invoicedate Date of invoicing (optional)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndCreateInvoicePayloadWrap|null $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndCreateInvoice'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoUpdateAndCreateInvoiceAsyncWithHttpInfo($document_number, $invoicedate = null, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndCreateInvoice'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap';
        $request = $this->contractControllerDoUpdateAndCreateInvoiceRequest($document_number, $invoicedate, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_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 'contractControllerDoUpdateAndCreateInvoice'
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \DateTime|null $invoicedate Date of invoicing (optional)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndCreateInvoicePayloadWrap|null $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndCreateInvoice'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function contractControllerDoUpdateAndCreateInvoiceRequest($document_number, $invoicedate = null, $fortnox_contract_invoice_contract_update_and_create_invoice_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndCreateInvoice'][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 contractControllerDoUpdateAndCreateInvoice'
            );
        }




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

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


        // 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_contract_invoice_contract_update_and_create_invoice_payload_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_contract_invoice_contract_update_and_create_invoice_payload_wrap));
            } else {
                $httpBody = $fortnox_contract_invoice_contract_update_and_create_invoice_payload_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 contractControllerDoUpdateAndFinish
     *
     * Set a contract as finished
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndFinishPayloadWrap|null $fortnox_contract_invoice_contract_update_and_finish_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndFinish'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function contractControllerDoUpdateAndFinish($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndFinish'][0])
    {
        list($response) = $this->contractControllerDoUpdateAndFinishWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_wrap, $contentType);
        return $response;
    }

    /**
     * Operation contractControllerDoUpdateAndFinishWithHttpInfo
     *
     * Set a contract as finished
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndFinishPayloadWrap|null $fortnox_contract_invoice_contract_update_and_finish_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndFinish'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function contractControllerDoUpdateAndFinishWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndFinish'][0])
    {
        $request = $this->contractControllerDoUpdateAndFinishRequest($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_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\FortnoxContractInvoiceContractResponseWrap',
                        $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\FortnoxContractInvoiceContractResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap',
                        $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 contractControllerDoUpdateAndFinishAsync
     *
     * Set a contract as finished
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndFinishPayloadWrap|null $fortnox_contract_invoice_contract_update_and_finish_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndFinish'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoUpdateAndFinishAsync($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndFinish'][0])
    {
        return $this->contractControllerDoUpdateAndFinishAsyncWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation contractControllerDoUpdateAndFinishAsyncWithHttpInfo
     *
     * Set a contract as finished
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndFinishPayloadWrap|null $fortnox_contract_invoice_contract_update_and_finish_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndFinish'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoUpdateAndFinishAsyncWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndFinish'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap';
        $request = $this->contractControllerDoUpdateAndFinishRequest($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_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 'contractControllerDoUpdateAndFinish'
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndFinishPayloadWrap|null $fortnox_contract_invoice_contract_update_and_finish_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndFinish'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function contractControllerDoUpdateAndFinishRequest($document_number, $fortnox_contract_invoice_contract_update_and_finish_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndFinish'][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 contractControllerDoUpdateAndFinish'
            );
        }



        $resourcePath = '/3/contracts/{DocumentNumber}/finish';
        $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_contract_invoice_contract_update_and_finish_payload_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_contract_invoice_contract_update_and_finish_payload_wrap));
            } else {
                $httpBody = $fortnox_contract_invoice_contract_update_and_finish_payload_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 contractControllerDoUpdateAndIncreaseInvoiceCount
     *
     * Increases the invoice count without creating an invoice
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndIncreaseInvoiceCountPayloadWrap|null $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function contractControllerDoUpdateAndIncreaseInvoiceCount($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'][0])
    {
        list($response) = $this->contractControllerDoUpdateAndIncreaseInvoiceCountWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap, $contentType);
        return $response;
    }

    /**
     * Operation contractControllerDoUpdateAndIncreaseInvoiceCountWithHttpInfo
     *
     * Increases the invoice count without creating an invoice
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndIncreaseInvoiceCountPayloadWrap|null $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'] 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\FortnoxContractInvoiceContractResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function contractControllerDoUpdateAndIncreaseInvoiceCountWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'][0])
    {
        $request = $this->contractControllerDoUpdateAndIncreaseInvoiceCountRequest($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_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\FortnoxContractInvoiceContractResponseWrap',
                        $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\FortnoxContractInvoiceContractResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap',
                        $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 contractControllerDoUpdateAndIncreaseInvoiceCountAsync
     *
     * Increases the invoice count without creating an invoice
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndIncreaseInvoiceCountPayloadWrap|null $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoUpdateAndIncreaseInvoiceCountAsync($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'][0])
    {
        return $this->contractControllerDoUpdateAndIncreaseInvoiceCountAsyncWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation contractControllerDoUpdateAndIncreaseInvoiceCountAsyncWithHttpInfo
     *
     * Increases the invoice count without creating an invoice
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndIncreaseInvoiceCountPayloadWrap|null $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function contractControllerDoUpdateAndIncreaseInvoiceCountAsyncWithHttpInfo($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxContractInvoiceContractResponseWrap';
        $request = $this->contractControllerDoUpdateAndIncreaseInvoiceCountRequest($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_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 'contractControllerDoUpdateAndIncreaseInvoiceCount'
     *
     * @param  string $document_number identifies the contract (required)
     * @param  \Fortnox\Model\FortnoxContractInvoiceContractUpdateAndIncreaseInvoiceCountPayloadWrap|null $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap Request body for update contract (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function contractControllerDoUpdateAndIncreaseInvoiceCountRequest($document_number, $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap = null, string $contentType = self::contentTypes['contractControllerDoUpdateAndIncreaseInvoiceCount'][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 contractControllerDoUpdateAndIncreaseInvoiceCount'
            );
        }



        $resourcePath = '/3/contracts/{DocumentNumber}/increaseinvoicecount';
        $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_contract_invoice_contract_update_and_increase_invoice_count_payload_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_contract_invoice_contract_update_and_increase_invoice_count_payload_wrap));
            } else {
                $httpBody = $fortnox_contract_invoice_contract_update_and_increase_invoice_count_payload_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;
    }
}
