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

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'voucherControllerDoCreate' => [
            'application/json',
        ],
        'voucherControllerDoIndex' => [
            'application/json',
        ],
        'voucherControllerDoShow' => [
            'application/json',
        ],
        'voucherControllerDoSubList' => [
            'application/json',
        ],
        'voucherControllerDoSublistWithParam' => [
            '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 voucherControllerDoCreate
     *
     * Create a voucher
     *
     * @param  int|null $financialyear Financial year id, used to determine which financial year the voucher is created in (optional)
     * @param  \Fortnox\Model\FortnoxBfVoucherSinglePayloadItemWrap|null $voucher Request body for create voucher (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoCreate'] 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\FortnoxBfVoucherSingleItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function voucherControllerDoCreate($financialyear = null, $voucher = null, string $contentType = self::contentTypes['voucherControllerDoCreate'][0])
    {
        list($response) = $this->voucherControllerDoCreateWithHttpInfo($financialyear, $voucher, $contentType);
        return $response;
    }

    /**
     * Operation voucherControllerDoCreateWithHttpInfo
     *
     * Create a voucher
     *
     * @param  int|null $financialyear Financial year id, used to determine which financial year the voucher is created in (optional)
     * @param  \Fortnox\Model\FortnoxBfVoucherSinglePayloadItemWrap|null $voucher Request body for create voucher (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoCreate'] 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\FortnoxBfVoucherSingleItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function voucherControllerDoCreateWithHttpInfo($financialyear = null, $voucher = null, string $contentType = self::contentTypes['voucherControllerDoCreate'][0])
    {
        $request = $this->voucherControllerDoCreateRequest($financialyear, $voucher, $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\FortnoxBfVoucherSingleItemWrap',
                        $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\FortnoxBfVoucherSingleItemWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 201:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxBfVoucherSingleItemWrap',
                        $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 voucherControllerDoCreateAsync
     *
     * Create a voucher
     *
     * @param  int|null $financialyear Financial year id, used to determine which financial year the voucher is created in (optional)
     * @param  \Fortnox\Model\FortnoxBfVoucherSinglePayloadItemWrap|null $voucher Request body for create voucher (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoCreate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoCreateAsync($financialyear = null, $voucher = null, string $contentType = self::contentTypes['voucherControllerDoCreate'][0])
    {
        return $this->voucherControllerDoCreateAsyncWithHttpInfo($financialyear, $voucher, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation voucherControllerDoCreateAsyncWithHttpInfo
     *
     * Create a voucher
     *
     * @param  int|null $financialyear Financial year id, used to determine which financial year the voucher is created in (optional)
     * @param  \Fortnox\Model\FortnoxBfVoucherSinglePayloadItemWrap|null $voucher Request body for create voucher (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoCreate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoCreateAsyncWithHttpInfo($financialyear = null, $voucher = null, string $contentType = self::contentTypes['voucherControllerDoCreate'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxBfVoucherSingleItemWrap';
        $request = $this->voucherControllerDoCreateRequest($financialyear, $voucher, $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 'voucherControllerDoCreate'
     *
     * @param  int|null $financialyear Financial year id, used to determine which financial year the voucher is created in (optional)
     * @param  \Fortnox\Model\FortnoxBfVoucherSinglePayloadItemWrap|null $voucher Request body for create voucher (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoCreate'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function voucherControllerDoCreateRequest($financialyear = null, $voucher = null, string $contentType = self::contentTypes['voucherControllerDoCreate'][0])
    {




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

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




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

        // for model (json/xml)
        if (isset($voucher)) {
            if (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the body
                $httpBody = \GuzzleHttp\Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($voucher));
            } else {
                $httpBody = $voucher;
            }
        } 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 voucherControllerDoIndex
     *
     * Retrieve all vouchers
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoIndex'] 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\FortnoxBfVoucherListItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function voucherControllerDoIndex($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoIndex'][0])
    {
        list($response) = $this->voucherControllerDoIndexWithHttpInfo($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $financialyear, $contentType);
        return $response;
    }

    /**
     * Operation voucherControllerDoIndexWithHttpInfo
     *
     * Retrieve all vouchers
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoIndex'] 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\FortnoxBfVoucherListItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function voucherControllerDoIndexWithHttpInfo($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoIndex'][0])
    {
        $request = $this->voucherControllerDoIndexRequest($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $financialyear, $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\FortnoxBfVoucherListItemWrap',
                        $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\FortnoxBfVoucherListItemWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxBfVoucherListItemWrap',
                        $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 voucherControllerDoIndexAsync
     *
     * Retrieve all vouchers
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoIndexAsync($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoIndex'][0])
    {
        return $this->voucherControllerDoIndexAsyncWithHttpInfo($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $financialyear, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation voucherControllerDoIndexAsyncWithHttpInfo
     *
     * Retrieve all vouchers
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoIndexAsyncWithHttpInfo($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoIndex'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxBfVoucherListItemWrap';
        $request = $this->voucherControllerDoIndexRequest($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $financialyear, $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 'voucherControllerDoIndex'
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoIndex'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function voucherControllerDoIndexRequest($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoIndex'][0])
    {








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

        // 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(
            $lastmodified,
            'lastmodified', // 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(
            $voucherseries,
            'voucherseries', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $financialyear,
            'financialyear', // param base name
            'integer', // 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 voucherControllerDoShow
     *
     * Retrieve a specific voucher
     *
     * @param  string $voucher_series identifies the voucher series (required)
     * @param  int $voucher_number identifies the voucher number (required)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoShow'] 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\FortnoxBfVoucherSingleItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function voucherControllerDoShow($voucher_series, $voucher_number, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoShow'][0])
    {
        list($response) = $this->voucherControllerDoShowWithHttpInfo($voucher_series, $voucher_number, $financialyear, $contentType);
        return $response;
    }

    /**
     * Operation voucherControllerDoShowWithHttpInfo
     *
     * Retrieve a specific voucher
     *
     * @param  string $voucher_series identifies the voucher series (required)
     * @param  int $voucher_number identifies the voucher number (required)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoShow'] 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\FortnoxBfVoucherSingleItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function voucherControllerDoShowWithHttpInfo($voucher_series, $voucher_number, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoShow'][0])
    {
        $request = $this->voucherControllerDoShowRequest($voucher_series, $voucher_number, $financialyear, $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\FortnoxBfVoucherSingleItemWrap',
                        $request,
                        $response,
                    );
                case 400:
                    return $this->handleResponseWithDataType(
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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\FortnoxBfVoucherSingleItemWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxBfVoucherSingleItemWrap',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxErrorInformationWrap',
                        $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 voucherControllerDoShowAsync
     *
     * Retrieve a specific voucher
     *
     * @param  string $voucher_series identifies the voucher series (required)
     * @param  int $voucher_number identifies the voucher number (required)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoShow'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoShowAsync($voucher_series, $voucher_number, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoShow'][0])
    {
        return $this->voucherControllerDoShowAsyncWithHttpInfo($voucher_series, $voucher_number, $financialyear, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation voucherControllerDoShowAsyncWithHttpInfo
     *
     * Retrieve a specific voucher
     *
     * @param  string $voucher_series identifies the voucher series (required)
     * @param  int $voucher_number identifies the voucher number (required)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoShow'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoShowAsyncWithHttpInfo($voucher_series, $voucher_number, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoShow'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxBfVoucherSingleItemWrap';
        $request = $this->voucherControllerDoShowRequest($voucher_series, $voucher_number, $financialyear, $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 'voucherControllerDoShow'
     *
     * @param  string $voucher_series identifies the voucher series (required)
     * @param  int $voucher_number identifies the voucher number (required)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoShow'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function voucherControllerDoShowRequest($voucher_series, $voucher_number, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoShow'][0])
    {

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

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



        $resourcePath = '/3/vouchers/{VoucherSeries}/{VoucherNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


        // path params
        if ($voucher_series !== null) {
            $resourcePath = str_replace(
                '{' . 'VoucherSeries' . '}',
                ObjectSerializer::toPathValue($voucher_series),
                $resourcePath
            );
        }
        // path params
        if ($voucher_number !== null) {
            $resourcePath = str_replace(
                '{' . 'VoucherNumber' . '}',
                ObjectSerializer::toPathValue($voucher_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 voucherControllerDoSubList
     *
     * Retrieve all vouchers for the current financial year
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSubList'] 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\FortnoxBfVoucherListItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function voucherControllerDoSubList($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, string $contentType = self::contentTypes['voucherControllerDoSubList'][0])
    {
        list($response) = $this->voucherControllerDoSubListWithHttpInfo($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $contentType);
        return $response;
    }

    /**
     * Operation voucherControllerDoSubListWithHttpInfo
     *
     * Retrieve all vouchers for the current financial year
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSubList'] 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\FortnoxBfVoucherListItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function voucherControllerDoSubListWithHttpInfo($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, string $contentType = self::contentTypes['voucherControllerDoSubList'][0])
    {
        $request = $this->voucherControllerDoSubListRequest($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $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\FortnoxBfVoucherListItemWrap',
                        $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\FortnoxBfVoucherListItemWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxBfVoucherListItemWrap',
                        $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 voucherControllerDoSubListAsync
     *
     * Retrieve all vouchers for the current financial year
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSubList'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoSubListAsync($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, string $contentType = self::contentTypes['voucherControllerDoSubList'][0])
    {
        return $this->voucherControllerDoSubListAsyncWithHttpInfo($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation voucherControllerDoSubListAsyncWithHttpInfo
     *
     * Retrieve all vouchers for the current financial year
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSubList'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoSubListAsyncWithHttpInfo($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, string $contentType = self::contentTypes['voucherControllerDoSubList'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxBfVoucherListItemWrap';
        $request = $this->voucherControllerDoSubListRequest($costcenter, $lastmodified, $fromdate, $todate, $voucherseries, $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 'voucherControllerDoSubList'
     *
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  string|null $voucherseries filter on voucher series (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSubList'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function voucherControllerDoSubListRequest($costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $voucherseries = null, string $contentType = self::contentTypes['voucherControllerDoSubList'][0])
    {







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

        // 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(
            $lastmodified,
            'lastmodified', // 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(
            $voucherseries,
            'voucherseries', // 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 voucherControllerDoSublistWithParam
     *
     * Retrieve a list of vouchers for a specific series
     *
     * @param  string $voucher_series Voucher series of vouchers to list (required)
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSublistWithParam'] 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\FortnoxBfVoucherListItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap
     */
    public function voucherControllerDoSublistWithParam($voucher_series, $costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoSublistWithParam'][0])
    {
        list($response) = $this->voucherControllerDoSublistWithParamWithHttpInfo($voucher_series, $costcenter, $lastmodified, $fromdate, $todate, $financialyear, $contentType);
        return $response;
    }

    /**
     * Operation voucherControllerDoSublistWithParamWithHttpInfo
     *
     * Retrieve a list of vouchers for a specific series
     *
     * @param  string $voucher_series Voucher series of vouchers to list (required)
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSublistWithParam'] 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\FortnoxBfVoucherListItemWrap|\Fortnox\Model\FortnoxErrorInformationWrap, HTTP status code, HTTP response headers (array of strings)
     */
    public function voucherControllerDoSublistWithParamWithHttpInfo($voucher_series, $costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoSublistWithParam'][0])
    {
        $request = $this->voucherControllerDoSublistWithParamRequest($voucher_series, $costcenter, $lastmodified, $fromdate, $todate, $financialyear, $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\FortnoxBfVoucherListItemWrap',
                        $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\FortnoxBfVoucherListItemWrap',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Fortnox\Model\FortnoxBfVoucherListItemWrap',
                        $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 voucherControllerDoSublistWithParamAsync
     *
     * Retrieve a list of vouchers for a specific series
     *
     * @param  string $voucher_series Voucher series of vouchers to list (required)
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSublistWithParam'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoSublistWithParamAsync($voucher_series, $costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoSublistWithParam'][0])
    {
        return $this->voucherControllerDoSublistWithParamAsyncWithHttpInfo($voucher_series, $costcenter, $lastmodified, $fromdate, $todate, $financialyear, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation voucherControllerDoSublistWithParamAsyncWithHttpInfo
     *
     * Retrieve a list of vouchers for a specific series
     *
     * @param  string $voucher_series Voucher series of vouchers to list (required)
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSublistWithParam'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function voucherControllerDoSublistWithParamAsyncWithHttpInfo($voucher_series, $costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoSublistWithParam'][0])
    {
        $returnType = '\Fortnox\Model\FortnoxBfVoucherListItemWrap';
        $request = $this->voucherControllerDoSublistWithParamRequest($voucher_series, $costcenter, $lastmodified, $fromdate, $todate, $financialyear, $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 'voucherControllerDoSublistWithParam'
     *
     * @param  string $voucher_series Voucher series of vouchers to list (required)
     * @param  string|null $costcenter filter on cost center (optional)
     * @param  \DateTime|null $lastmodified filter on last modified date (optional)
     * @param  \DateTime|null $fromdate filter on from date (optional)
     * @param  \DateTime|null $todate filter on to date (optional)
     * @param  int|null $financialyear filter on financial year (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['voucherControllerDoSublistWithParam'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function voucherControllerDoSublistWithParamRequest($voucher_series, $costcenter = null, $lastmodified = null, $fromdate = null, $todate = null, $financialyear = null, string $contentType = self::contentTypes['voucherControllerDoSublistWithParam'][0])
    {

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







        $resourcePath = '/3/vouchers/sublist/{VoucherSeries}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // 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(
            $lastmodified,
            'lastmodified', // 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(
            $financialyear,
            'financialyear', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);


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

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