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

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'invoiceControllerDoCreate' => [
            'application/json',
        ],
        'invoiceControllerDoIndex' => [
            'application/json',
        ],
        'invoiceControllerDoShow' => [
            'application/json',
        ],
        'invoiceControllerDoShowAndEinvoice' => [
            'application/json',
        ],
        'invoiceControllerDoShowAndEmail' => [
            'application/json',
        ],
        'invoiceControllerDoShowAndEprint' => [
            'application/json',
        ],
        'invoiceControllerDoShowAndPreview' => [
            'application/json',
        ],
        'invoiceControllerDoShowAndPrint' => [
            'application/json',
        ],
        'invoiceControllerDoShowAndPrintReminder' => [
            'application/json',
        ],
        'invoiceControllerDoUpdate' => [
            'application/json',
        ],
        'invoiceControllerDoUpdateAndBookkeep' => [
            'application/json',
        ],
        'invoiceControllerDoUpdateAndCancel' => [
            'application/json',
        ],
        'invoiceControllerDoUpdateAndCredit' => [
            'application/json',
        ],
        'invoiceControllerDoUpdateAndExternalPrint' => [
            'application/json',
        ],
        'invoiceControllerDoUpdateAndWarehouseReady' => [
            '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 invoiceControllerDoCreate
     *
     * Create an invoice
     *
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $invoice_payload Request body for create invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoCreate'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoCreate($invoice_payload = null, string $contentType = self::contentTypes['invoiceControllerDoCreate'][0])
    {
        list($response) = $this->invoiceControllerDoCreateWithHttpInfo($invoice_payload, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoCreateWithHttpInfo
     *
     * Create an invoice
     *
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $invoice_payload Request body for create invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoCreate'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoCreateWithHttpInfo($invoice_payload = null, string $contentType = self::contentTypes['invoiceControllerDoCreate'][0])
    {
        $request = $this->invoiceControllerDoCreateRequest($invoice_payload, $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\FortnoxKfInvoiceResponseWrap',
                        $request,
                        $response,
                    );
                case 400:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
                default:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $request,
                        $response,
                    );
            }

            

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

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

            throw $e;
        }
    }

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

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



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





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

        // for model (json/xml)
        if (isset($invoice_payload)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($invoice_payload));
            } else {
                $httpBody = $invoice_payload;
            }
        } 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 invoiceControllerDoIndex
     *
     * Retrieve a list of invoices
     *
     * @param  string|null $tofinalpaydate Tofinalpaydate of invoices to list (optional)
     * @param  string|null $fromfinalpaydate Fromfinalpaydate of invoices to list (optional)
     * @param  string|null $filter possibility to filter invoices (optional)
     * @param  string|null $sortby field to sort returned list on (optional)
     * @param  string|null $costcenter Costcenter of invoices to list (optional)
     * @param  string|null $customername Customername of invoices to list (optional)
     * @param  string|null $customernumber Customernumber of invoices to list (optional)
     * @param  string|null $label Label of invoices to list (optional)
     * @param  string|null $documentnumber Documentnumber of invoices to list (optional)
     * @param  string|null $fromdate Fromdate of invoices to list (optional)
     * @param  string|null $todate Todate of invoices to list (optional)
     * @param  string|null $lastmodified Lastmodified of invoices to list (optional)
     * @param  string|null $notcompleted Notcompleted of invoices to list (optional)
     * @param  string|null $ocr Ocr of invoices to list (optional)
     * @param  string|null $ourreference Ourreference of invoices to list (optional)
     * @param  string|null $project Project of invoices to list (optional)
     * @param  string|null $sent Sent of invoices to list (optional)
     * @param  string|null $externalinvoicereference1 Externalinvoicereference1 of invoices to list (optional)
     * @param  string|null $externalinvoicereference2 Externalinvoicereference2 of invoices to list (optional)
     * @param  string|null $yourreference Yourreference of invoices to list (optional)
     * @param  string|null $invoicetype Invoicetype of invoices to list (optional)
     * @param  string|null $articlenumber Articlenumber of invoices to list (optional)
     * @param  string|null $articledescription Articledescription of invoices to list (optional)
     * @param  string|null $currency Currency of invoices to list (optional)
     * @param  string|null $accountnumberfrom Accountnumberfrom of invoices to list (optional)
     * @param  string|null $accountnumberto Accountnumberto of invoices to list (optional)
     * @param  string|null $yourordernumber Yourordernumber of invoices to list (optional)
     * @param  string|null $credit Credit of invoices to list (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoIndex'] 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\FortnoxKfInvoiceListResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoIndex($tofinalpaydate = null, $fromfinalpaydate = null, $filter = null, $sortby = null, $costcenter = null, $customername = null, $customernumber = null, $label = null, $documentnumber = null, $fromdate = null, $todate = null, $lastmodified = null, $notcompleted = null, $ocr = null, $ourreference = null, $project = null, $sent = null, $externalinvoicereference1 = null, $externalinvoicereference2 = null, $yourreference = null, $invoicetype = null, $articlenumber = null, $articledescription = null, $currency = null, $accountnumberfrom = null, $accountnumberto = null, $yourordernumber = null, $credit = null, string $contentType = self::contentTypes['invoiceControllerDoIndex'][0])
    {
        list($response) = $this->invoiceControllerDoIndexWithHttpInfo($tofinalpaydate, $fromfinalpaydate, $filter, $sortby, $costcenter, $customername, $customernumber, $label, $documentnumber, $fromdate, $todate, $lastmodified, $notcompleted, $ocr, $ourreference, $project, $sent, $externalinvoicereference1, $externalinvoicereference2, $yourreference, $invoicetype, $articlenumber, $articledescription, $currency, $accountnumberfrom, $accountnumberto, $yourordernumber, $credit, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoIndexWithHttpInfo
     *
     * Retrieve a list of invoices
     *
     * @param  string|null $tofinalpaydate Tofinalpaydate of invoices to list (optional)
     * @param  string|null $fromfinalpaydate Fromfinalpaydate of invoices to list (optional)
     * @param  string|null $filter possibility to filter invoices (optional)
     * @param  string|null $sortby field to sort returned list on (optional)
     * @param  string|null $costcenter Costcenter of invoices to list (optional)
     * @param  string|null $customername Customername of invoices to list (optional)
     * @param  string|null $customernumber Customernumber of invoices to list (optional)
     * @param  string|null $label Label of invoices to list (optional)
     * @param  string|null $documentnumber Documentnumber of invoices to list (optional)
     * @param  string|null $fromdate Fromdate of invoices to list (optional)
     * @param  string|null $todate Todate of invoices to list (optional)
     * @param  string|null $lastmodified Lastmodified of invoices to list (optional)
     * @param  string|null $notcompleted Notcompleted of invoices to list (optional)
     * @param  string|null $ocr Ocr of invoices to list (optional)
     * @param  string|null $ourreference Ourreference of invoices to list (optional)
     * @param  string|null $project Project of invoices to list (optional)
     * @param  string|null $sent Sent of invoices to list (optional)
     * @param  string|null $externalinvoicereference1 Externalinvoicereference1 of invoices to list (optional)
     * @param  string|null $externalinvoicereference2 Externalinvoicereference2 of invoices to list (optional)
     * @param  string|null $yourreference Yourreference of invoices to list (optional)
     * @param  string|null $invoicetype Invoicetype of invoices to list (optional)
     * @param  string|null $articlenumber Articlenumber of invoices to list (optional)
     * @param  string|null $articledescription Articledescription of invoices to list (optional)
     * @param  string|null $currency Currency of invoices to list (optional)
     * @param  string|null $accountnumberfrom Accountnumberfrom of invoices to list (optional)
     * @param  string|null $accountnumberto Accountnumberto of invoices to list (optional)
     * @param  string|null $yourordernumber Yourordernumber of invoices to list (optional)
     * @param  string|null $credit Credit of invoices to list (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoIndex'] 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\FortnoxKfInvoiceListResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoIndexWithHttpInfo($tofinalpaydate = null, $fromfinalpaydate = null, $filter = null, $sortby = null, $costcenter = null, $customername = null, $customernumber = null, $label = null, $documentnumber = null, $fromdate = null, $todate = null, $lastmodified = null, $notcompleted = null, $ocr = null, $ourreference = null, $project = null, $sent = null, $externalinvoicereference1 = null, $externalinvoicereference2 = null, $yourreference = null, $invoicetype = null, $articlenumber = null, $articledescription = null, $currency = null, $accountnumberfrom = null, $accountnumberto = null, $yourordernumber = null, $credit = null, string $contentType = self::contentTypes['invoiceControllerDoIndex'][0])
    {
        $request = $this->invoiceControllerDoIndexRequest($tofinalpaydate, $fromfinalpaydate, $filter, $sortby, $costcenter, $customername, $customernumber, $label, $documentnumber, $fromdate, $todate, $lastmodified, $notcompleted, $ocr, $ourreference, $project, $sent, $externalinvoicereference1, $externalinvoicereference2, $yourreference, $invoicetype, $articlenumber, $articledescription, $currency, $accountnumberfrom, $accountnumberto, $yourordernumber, $credit, $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\FortnoxKfInvoiceListResponseWrap',
                        $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\FortnoxKfInvoiceListResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceListResponseWrap',
                        $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 invoiceControllerDoIndexAsync
     *
     * Retrieve a list of invoices
     *
     * @param  string|null $tofinalpaydate Tofinalpaydate of invoices to list (optional)
     * @param  string|null $fromfinalpaydate Fromfinalpaydate of invoices to list (optional)
     * @param  string|null $filter possibility to filter invoices (optional)
     * @param  string|null $sortby field to sort returned list on (optional)
     * @param  string|null $costcenter Costcenter of invoices to list (optional)
     * @param  string|null $customername Customername of invoices to list (optional)
     * @param  string|null $customernumber Customernumber of invoices to list (optional)
     * @param  string|null $label Label of invoices to list (optional)
     * @param  string|null $documentnumber Documentnumber of invoices to list (optional)
     * @param  string|null $fromdate Fromdate of invoices to list (optional)
     * @param  string|null $todate Todate of invoices to list (optional)
     * @param  string|null $lastmodified Lastmodified of invoices to list (optional)
     * @param  string|null $notcompleted Notcompleted of invoices to list (optional)
     * @param  string|null $ocr Ocr of invoices to list (optional)
     * @param  string|null $ourreference Ourreference of invoices to list (optional)
     * @param  string|null $project Project of invoices to list (optional)
     * @param  string|null $sent Sent of invoices to list (optional)
     * @param  string|null $externalinvoicereference1 Externalinvoicereference1 of invoices to list (optional)
     * @param  string|null $externalinvoicereference2 Externalinvoicereference2 of invoices to list (optional)
     * @param  string|null $yourreference Yourreference of invoices to list (optional)
     * @param  string|null $invoicetype Invoicetype of invoices to list (optional)
     * @param  string|null $articlenumber Articlenumber of invoices to list (optional)
     * @param  string|null $articledescription Articledescription of invoices to list (optional)
     * @param  string|null $currency Currency of invoices to list (optional)
     * @param  string|null $accountnumberfrom Accountnumberfrom of invoices to list (optional)
     * @param  string|null $accountnumberto Accountnumberto of invoices to list (optional)
     * @param  string|null $yourordernumber Yourordernumber of invoices to list (optional)
     * @param  string|null $credit Credit of invoices to list (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoIndexAsync($tofinalpaydate = null, $fromfinalpaydate = null, $filter = null, $sortby = null, $costcenter = null, $customername = null, $customernumber = null, $label = null, $documentnumber = null, $fromdate = null, $todate = null, $lastmodified = null, $notcompleted = null, $ocr = null, $ourreference = null, $project = null, $sent = null, $externalinvoicereference1 = null, $externalinvoicereference2 = null, $yourreference = null, $invoicetype = null, $articlenumber = null, $articledescription = null, $currency = null, $accountnumberfrom = null, $accountnumberto = null, $yourordernumber = null, $credit = null, string $contentType = self::contentTypes['invoiceControllerDoIndex'][0])
    {
        return $this->invoiceControllerDoIndexAsyncWithHttpInfo($tofinalpaydate, $fromfinalpaydate, $filter, $sortby, $costcenter, $customername, $customernumber, $label, $documentnumber, $fromdate, $todate, $lastmodified, $notcompleted, $ocr, $ourreference, $project, $sent, $externalinvoicereference1, $externalinvoicereference2, $yourreference, $invoicetype, $articlenumber, $articledescription, $currency, $accountnumberfrom, $accountnumberto, $yourordernumber, $credit, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation invoiceControllerDoIndexAsyncWithHttpInfo
     *
     * Retrieve a list of invoices
     *
     * @param  string|null $tofinalpaydate Tofinalpaydate of invoices to list (optional)
     * @param  string|null $fromfinalpaydate Fromfinalpaydate of invoices to list (optional)
     * @param  string|null $filter possibility to filter invoices (optional)
     * @param  string|null $sortby field to sort returned list on (optional)
     * @param  string|null $costcenter Costcenter of invoices to list (optional)
     * @param  string|null $customername Customername of invoices to list (optional)
     * @param  string|null $customernumber Customernumber of invoices to list (optional)
     * @param  string|null $label Label of invoices to list (optional)
     * @param  string|null $documentnumber Documentnumber of invoices to list (optional)
     * @param  string|null $fromdate Fromdate of invoices to list (optional)
     * @param  string|null $todate Todate of invoices to list (optional)
     * @param  string|null $lastmodified Lastmodified of invoices to list (optional)
     * @param  string|null $notcompleted Notcompleted of invoices to list (optional)
     * @param  string|null $ocr Ocr of invoices to list (optional)
     * @param  string|null $ourreference Ourreference of invoices to list (optional)
     * @param  string|null $project Project of invoices to list (optional)
     * @param  string|null $sent Sent of invoices to list (optional)
     * @param  string|null $externalinvoicereference1 Externalinvoicereference1 of invoices to list (optional)
     * @param  string|null $externalinvoicereference2 Externalinvoicereference2 of invoices to list (optional)
     * @param  string|null $yourreference Yourreference of invoices to list (optional)
     * @param  string|null $invoicetype Invoicetype of invoices to list (optional)
     * @param  string|null $articlenumber Articlenumber of invoices to list (optional)
     * @param  string|null $articledescription Articledescription of invoices to list (optional)
     * @param  string|null $currency Currency of invoices to list (optional)
     * @param  string|null $accountnumberfrom Accountnumberfrom of invoices to list (optional)
     * @param  string|null $accountnumberto Accountnumberto of invoices to list (optional)
     * @param  string|null $yourordernumber Yourordernumber of invoices to list (optional)
     * @param  string|null $credit Credit of invoices to list (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoIndexAsyncWithHttpInfo($tofinalpaydate = null, $fromfinalpaydate = null, $filter = null, $sortby = null, $costcenter = null, $customername = null, $customernumber = null, $label = null, $documentnumber = null, $fromdate = null, $todate = null, $lastmodified = null, $notcompleted = null, $ocr = null, $ourreference = null, $project = null, $sent = null, $externalinvoicereference1 = null, $externalinvoicereference2 = null, $yourreference = null, $invoicetype = null, $articlenumber = null, $articledescription = null, $currency = null, $accountnumberfrom = null, $accountnumberto = null, $yourordernumber = null, $credit = null, string $contentType = self::contentTypes['invoiceControllerDoIndex'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxKfInvoiceListResponseWrap';
        $request = $this->invoiceControllerDoIndexRequest($tofinalpaydate, $fromfinalpaydate, $filter, $sortby, $costcenter, $customername, $customernumber, $label, $documentnumber, $fromdate, $todate, $lastmodified, $notcompleted, $ocr, $ourreference, $project, $sent, $externalinvoicereference1, $externalinvoicereference2, $yourreference, $invoicetype, $articlenumber, $articledescription, $currency, $accountnumberfrom, $accountnumberto, $yourordernumber, $credit, $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 'invoiceControllerDoIndex'
     *
     * @param  string|null $tofinalpaydate Tofinalpaydate of invoices to list (optional)
     * @param  string|null $fromfinalpaydate Fromfinalpaydate of invoices to list (optional)
     * @param  string|null $filter possibility to filter invoices (optional)
     * @param  string|null $sortby field to sort returned list on (optional)
     * @param  string|null $costcenter Costcenter of invoices to list (optional)
     * @param  string|null $customername Customername of invoices to list (optional)
     * @param  string|null $customernumber Customernumber of invoices to list (optional)
     * @param  string|null $label Label of invoices to list (optional)
     * @param  string|null $documentnumber Documentnumber of invoices to list (optional)
     * @param  string|null $fromdate Fromdate of invoices to list (optional)
     * @param  string|null $todate Todate of invoices to list (optional)
     * @param  string|null $lastmodified Lastmodified of invoices to list (optional)
     * @param  string|null $notcompleted Notcompleted of invoices to list (optional)
     * @param  string|null $ocr Ocr of invoices to list (optional)
     * @param  string|null $ourreference Ourreference of invoices to list (optional)
     * @param  string|null $project Project of invoices to list (optional)
     * @param  string|null $sent Sent of invoices to list (optional)
     * @param  string|null $externalinvoicereference1 Externalinvoicereference1 of invoices to list (optional)
     * @param  string|null $externalinvoicereference2 Externalinvoicereference2 of invoices to list (optional)
     * @param  string|null $yourreference Yourreference of invoices to list (optional)
     * @param  string|null $invoicetype Invoicetype of invoices to list (optional)
     * @param  string|null $articlenumber Articlenumber of invoices to list (optional)
     * @param  string|null $articledescription Articledescription of invoices to list (optional)
     * @param  string|null $currency Currency of invoices to list (optional)
     * @param  string|null $accountnumberfrom Accountnumberfrom of invoices to list (optional)
     * @param  string|null $accountnumberto Accountnumberto of invoices to list (optional)
     * @param  string|null $yourordernumber Yourordernumber of invoices to list (optional)
     * @param  string|null $credit Credit of invoices to list (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function invoiceControllerDoIndexRequest($tofinalpaydate = null, $fromfinalpaydate = null, $filter = null, $sortby = null, $costcenter = null, $customername = null, $customernumber = null, $label = null, $documentnumber = null, $fromdate = null, $todate = null, $lastmodified = null, $notcompleted = null, $ocr = null, $ourreference = null, $project = null, $sent = null, $externalinvoicereference1 = null, $externalinvoicereference2 = null, $yourreference = null, $invoicetype = null, $articlenumber = null, $articledescription = null, $currency = null, $accountnumberfrom = null, $accountnumberto = null, $yourordernumber = null, $credit = null, string $contentType = self::contentTypes['invoiceControllerDoIndex'][0])
    {






























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

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $tofinalpaydate,
            'tofinalpaydate', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $fromfinalpaydate,
            'fromfinalpaydate', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $filter,
            'filter', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $sortby,
            'sortby', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $costcenter,
            'costcenter', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $customername,
            'customername', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $customernumber,
            'customernumber', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $label,
            'label', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $documentnumber,
            'documentnumber', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $fromdate,
            'fromdate', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $todate,
            'todate', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $lastmodified,
            'lastmodified', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $notcompleted,
            'notcompleted', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $ocr,
            'ocr', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $ourreference,
            'ourreference', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $project,
            'project', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $sent,
            'sent', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $externalinvoicereference1,
            'externalinvoicereference1', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $externalinvoicereference2,
            'externalinvoicereference2', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $yourreference,
            'yourreference', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $invoicetype,
            'invoicetype', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $articlenumber,
            'articlenumber', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $articledescription,
            'articledescription', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $currency,
            'currency', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $accountnumberfrom,
            'accountnumberfrom', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $accountnumberto,
            'accountnumberto', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $yourordernumber,
            'yourordernumber', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $credit,
            'credit', // 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 invoiceControllerDoShow
     *
     * Retrieve a single invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShow'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoShow($document_number, string $contentType = self::contentTypes['invoiceControllerDoShow'][0])
    {
        list($response) = $this->invoiceControllerDoShowWithHttpInfo($document_number, $contentType);
        return $response;
    }

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

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


        $resourcePath = '/3/invoices/{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 invoiceControllerDoShowAndEinvoice
     *
     * Send an invoice as e-invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndEinvoice'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoShowAndEinvoice($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndEinvoice'][0])
    {
        list($response) = $this->invoiceControllerDoShowAndEinvoiceWithHttpInfo($document_number, $contentType);
        return $response;
    }

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

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


        $resourcePath = '/3/invoices/{DocumentNumber}/einvoice';
        $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 invoiceControllerDoShowAndEmail
     *
     * Send an invoice as email
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndEmail'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoShowAndEmail($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndEmail'][0])
    {
        list($response) = $this->invoiceControllerDoShowAndEmailWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoShowAndEmailWithHttpInfo
     *
     * Send an invoice as email
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndEmail'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoShowAndEmailWithHttpInfo($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndEmail'][0])
    {
        $request = $this->invoiceControllerDoShowAndEmailRequest($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\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoShowAndEmailAsync
     *
     * Send an invoice as email
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndEmail'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoShowAndEmailAsync($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndEmail'][0])
    {
        return $this->invoiceControllerDoShowAndEmailAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

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


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



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


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

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

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


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

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

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

    /**
     * Operation invoiceControllerDoShowAndEprint
     *
     * Send an invoice as e-print
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndEprint'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoShowAndEprint($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndEprint'][0])
    {
        list($response) = $this->invoiceControllerDoShowAndEprintWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoShowAndEprintWithHttpInfo
     *
     * Send an invoice as e-print
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndEprint'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoShowAndEprintWithHttpInfo($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndEprint'][0])
    {
        $request = $this->invoiceControllerDoShowAndEprintRequest($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\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoShowAndEprintAsync
     *
     * Send an invoice as e-print
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndEprint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoShowAndEprintAsync($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndEprint'][0])
    {
        return $this->invoiceControllerDoShowAndEprintAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

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


        $resourcePath = '/3/invoices/{DocumentNumber}/eprint';
        $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 invoiceControllerDoShowAndPreview
     *
     * Preview an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndPreview'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoShowAndPreview($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndPreview'][0])
    {
        list($response) = $this->invoiceControllerDoShowAndPreviewWithHttpInfo($document_number, $contentType);
        return $response;
    }

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

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


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



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


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

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

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


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

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

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

    /**
     * Operation invoiceControllerDoShowAndPrint
     *
     * Print an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndPrint'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoShowAndPrint($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndPrint'][0])
    {
        list($response) = $this->invoiceControllerDoShowAndPrintWithHttpInfo($document_number, $contentType);
        return $response;
    }

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

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


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



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


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

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

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


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

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

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

    /**
     * Operation invoiceControllerDoShowAndPrintReminder
     *
     * Print an invoice as reminder
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndPrintReminder'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoShowAndPrintReminder($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndPrintReminder'][0])
    {
        list($response) = $this->invoiceControllerDoShowAndPrintReminderWithHttpInfo($document_number, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoShowAndPrintReminderWithHttpInfo
     *
     * Print an invoice as reminder
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndPrintReminder'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoShowAndPrintReminderWithHttpInfo($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndPrintReminder'][0])
    {
        $request = $this->invoiceControllerDoShowAndPrintReminderRequest($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\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoShowAndPrintReminderAsync
     *
     * Print an invoice as reminder
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoShowAndPrintReminder'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoShowAndPrintReminderAsync($document_number, string $contentType = self::contentTypes['invoiceControllerDoShowAndPrintReminder'][0])
    {
        return $this->invoiceControllerDoShowAndPrintReminderAsyncWithHttpInfo($document_number, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

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


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



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


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

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

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


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

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

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

    /**
     * Operation invoiceControllerDoUpdate
     *
     * Update an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $invoice_payload Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdate'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoUpdate($document_number, $invoice_payload = null, string $contentType = self::contentTypes['invoiceControllerDoUpdate'][0])
    {
        list($response) = $this->invoiceControllerDoUpdateWithHttpInfo($document_number, $invoice_payload, $contentType);
        return $response;
    }

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

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



        $resourcePath = '/3/invoices/{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($invoice_payload)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($invoice_payload));
            } else {
                $httpBody = $invoice_payload;
            }
        } 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 invoiceControllerDoUpdateAndBookkeep
     *
     * Bookkeep an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndBookkeep'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoUpdateAndBookkeep($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndBookkeep'][0])
    {
        list($response) = $this->invoiceControllerDoUpdateAndBookkeepWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoUpdateAndBookkeepWithHttpInfo
     *
     * Bookkeep an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndBookkeep'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoUpdateAndBookkeepWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndBookkeep'][0])
    {
        $request = $this->invoiceControllerDoUpdateAndBookkeepRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoUpdateAndBookkeepAsync
     *
     * Bookkeep an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndBookkeep'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndBookkeepAsync($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndBookkeep'][0])
    {
        return $this->invoiceControllerDoUpdateAndBookkeepAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation invoiceControllerDoUpdateAndBookkeepAsyncWithHttpInfo
     *
     * Bookkeep an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndBookkeep'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndBookkeepAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndBookkeep'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxKfInvoiceResponseWrap';
        $request = $this->invoiceControllerDoUpdateAndBookkeepRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

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

    /**
     * Create request for operation 'invoiceControllerDoUpdateAndBookkeep'
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndBookkeep'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function invoiceControllerDoUpdateAndBookkeepRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndBookkeep'][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 invoiceControllerDoUpdateAndBookkeep'
            );
        }



        $resourcePath = '/3/invoices/{DocumentNumber}/bookkeep';
        $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_kf_invoice_single_payload_item_wrap)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fortnox_kf_invoice_single_payload_item_wrap));
            } else {
                $httpBody = $fortnox_kf_invoice_single_payload_item_wrap;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

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


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

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

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

    /**
     * Operation invoiceControllerDoUpdateAndCancel
     *
     * Cancel an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCancel'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoUpdateAndCancel($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCancel'][0])
    {
        list($response) = $this->invoiceControllerDoUpdateAndCancelWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoUpdateAndCancelWithHttpInfo
     *
     * Cancel an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCancel'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoUpdateAndCancelWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCancel'][0])
    {
        $request = $this->invoiceControllerDoUpdateAndCancelRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoUpdateAndCancelAsync
     *
     * Cancel an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCancel'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndCancelAsync($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCancel'][0])
    {
        return $this->invoiceControllerDoUpdateAndCancelAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation invoiceControllerDoUpdateAndCancelAsyncWithHttpInfo
     *
     * Cancel an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCancel'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndCancelAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCancel'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxKfInvoiceResponseWrap';
        $request = $this->invoiceControllerDoUpdateAndCancelRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

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

    /**
     * Create request for operation 'invoiceControllerDoUpdateAndCancel'
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCancel'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function invoiceControllerDoUpdateAndCancelRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCancel'][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 invoiceControllerDoUpdateAndCancel'
            );
        }



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



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


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

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

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


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

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

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

    /**
     * Operation invoiceControllerDoUpdateAndCredit
     *
     * Credit an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCredit'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoUpdateAndCredit($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCredit'][0])
    {
        list($response) = $this->invoiceControllerDoUpdateAndCreditWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoUpdateAndCreditWithHttpInfo
     *
     * Credit an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCredit'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoUpdateAndCreditWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCredit'][0])
    {
        $request = $this->invoiceControllerDoUpdateAndCreditRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoUpdateAndCreditAsync
     *
     * Credit an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCredit'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndCreditAsync($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCredit'][0])
    {
        return $this->invoiceControllerDoUpdateAndCreditAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation invoiceControllerDoUpdateAndCreditAsyncWithHttpInfo
     *
     * Credit an invoice
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCredit'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndCreditAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCredit'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxKfInvoiceResponseWrap';
        $request = $this->invoiceControllerDoUpdateAndCreditRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

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

    /**
     * Create request for operation 'invoiceControllerDoUpdateAndCredit'
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndCredit'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function invoiceControllerDoUpdateAndCreditRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndCredit'][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 invoiceControllerDoUpdateAndCredit'
            );
        }



        $resourcePath = '/3/invoices/{DocumentNumber}/credit';
        $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_kf_invoice_single_payload_item_wrap)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fortnox_kf_invoice_single_payload_item_wrap));
            } else {
                $httpBody = $fortnox_kf_invoice_single_payload_item_wrap;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

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


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

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

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

    /**
     * Operation invoiceControllerDoUpdateAndExternalPrint
     *
     * Set an invoice as sent
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoUpdateAndExternalPrint($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'][0])
    {
        list($response) = $this->invoiceControllerDoUpdateAndExternalPrintWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoUpdateAndExternalPrintWithHttpInfo
     *
     * Set an invoice as sent
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoUpdateAndExternalPrintWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'][0])
    {
        $request = $this->invoiceControllerDoUpdateAndExternalPrintRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoUpdateAndExternalPrintAsync
     *
     * Set an invoice as sent
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndExternalPrintAsync($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'][0])
    {
        return $this->invoiceControllerDoUpdateAndExternalPrintAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation invoiceControllerDoUpdateAndExternalPrintAsyncWithHttpInfo
     *
     * Set an invoice as sent
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndExternalPrintAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxKfInvoiceResponseWrap';
        $request = $this->invoiceControllerDoUpdateAndExternalPrintRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

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

    /**
     * Create request for operation 'invoiceControllerDoUpdateAndExternalPrint'
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function invoiceControllerDoUpdateAndExternalPrintRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndExternalPrint'][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 invoiceControllerDoUpdateAndExternalPrint'
            );
        }



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



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


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

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

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


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

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

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

    /**
     * Operation invoiceControllerDoUpdateAndWarehouseReady
     *
     * Set an invoice as done
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function invoiceControllerDoUpdateAndWarehouseReady($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'][0])
    {
        list($response) = $this->invoiceControllerDoUpdateAndWarehouseReadyWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);
        return $response;
    }

    /**
     * Operation invoiceControllerDoUpdateAndWarehouseReadyWithHttpInfo
     *
     * Set an invoice as done
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'] 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\FortnoxKfInvoiceResponseWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function invoiceControllerDoUpdateAndWarehouseReadyWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'][0])
    {
        $request = $this->invoiceControllerDoUpdateAndWarehouseReadyRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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\FortnoxKfInvoiceResponseWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxKfInvoiceResponseWrap',
                        $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 invoiceControllerDoUpdateAndWarehouseReadyAsync
     *
     * Set an invoice as done
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndWarehouseReadyAsync($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'][0])
    {
        return $this->invoiceControllerDoUpdateAndWarehouseReadyAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation invoiceControllerDoUpdateAndWarehouseReadyAsyncWithHttpInfo
     *
     * Set an invoice as done
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function invoiceControllerDoUpdateAndWarehouseReadyAsyncWithHttpInfo($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxKfInvoiceResponseWrap';
        $request = $this->invoiceControllerDoUpdateAndWarehouseReadyRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap, $contentType);

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

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

    /**
     * Create request for operation 'invoiceControllerDoUpdateAndWarehouseReady'
     *
     * @param  string $document_number identifies the invoice (required)
     * @param  \Fortnox\Model\FortnoxKfInvoiceSinglePayloadItemWrap|null $fortnox_kf_invoice_single_payload_item_wrap Request body for update invoice (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function invoiceControllerDoUpdateAndWarehouseReadyRequest($document_number, $fortnox_kf_invoice_single_payload_item_wrap = null, string $contentType = self::contentTypes['invoiceControllerDoUpdateAndWarehouseReady'][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 invoiceControllerDoUpdateAndWarehouseReady'
            );
        }



        $resourcePath = '/3/invoices/{DocumentNumber}/warehouseready';
        $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_kf_invoice_single_payload_item_wrap)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fortnox_kf_invoice_single_payload_item_wrap));
            } else {
                $httpBody = $fortnox_kf_invoice_single_payload_item_wrap;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

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


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

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

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

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

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

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

        return $options;
    }

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

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

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

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