<?php

/**
 * CashbookApi
 * PHP version 7.4
 *
 * @category Class
 * @package  FattureInCloud
 * @author   Fatture In Cloud API team
 * @link     https://fattureincloud.it
 */

/**
 * Fatture in Cloud API v2 - API Reference
 *
 * Connect your software with Fatture in Cloud, the invoicing platform chosen by more than 500.000 businesses in Italy.   The Fatture in Cloud API is based on REST, and makes possible to interact with the user related data prior authorization via OAuth2 protocol.
 *
 * The version of the OpenAPI document: 2.1.5
 * Contact: info@fattureincloud.it
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.12.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 FattureInCloud\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 FattureInCloud\ApiException;
use FattureInCloud\Configuration;
use FattureInCloud\HeaderSelector;
use FattureInCloud\ObjectSerializer;

/**
 * CashbookApi Class Doc Comment
 *
 * @category Class
 * @package  FattureInCloud
 * @author   Fatture In Cloud API team
 * @link     https://fattureincloud.it
 */
class CashbookApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'createCashbookEntry' => [
            'application/json',
        ],
        'deleteCashbookEntry' => [
            'application/json',
        ],
        'getCashbookEntry' => [
            'application/json',
        ],
        'listCashbookEntries' => [
            'application/json',
        ],
        'modifyCashbookEntry' => [
            '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 createCashbookEntry
     *
     * Create Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateCashbookEntryRequest|null $create_cashbook_entry_request Cashbook entry. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \FattureInCloud\Model\CreateCashbookEntryResponse
     */
    public function createCashbookEntry($company_id, $create_cashbook_entry_request = null, string $contentType = self::contentTypes['createCashbookEntry'][0])
    {
        list($response) = $this->createCashbookEntryWithHttpInfo($company_id, $create_cashbook_entry_request, $contentType);
        return $response;
    }

    /**
     * Operation createCashbookEntryWithHttpInfo
     *
     * Create Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateCashbookEntryRequest|null $create_cashbook_entry_request Cashbook entry. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \FattureInCloud\Model\CreateCashbookEntryResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function createCashbookEntryWithHttpInfo($company_id, $create_cashbook_entry_request = null, string $contentType = self::contentTypes['createCashbookEntry'][0])
    {
        $request = $this->createCashbookEntryRequest($company_id, $create_cashbook_entry_request, $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:
                    if ('\FattureInCloud\Model\CreateCashbookEntryResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\CreateCashbookEntryResponse' !== '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()
                                    ),
                                    $statusCode,
                                    $response->getHeaders(),
                                    $content
                                );
                            }
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, '\FattureInCloud\Model\CreateCashbookEntryResponse', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }

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

            $returnType = '\FattureInCloud\Model\CreateCashbookEntryResponse';
            if ($returnType === '\SplFileObject') {
                $content = $response->getBody(); //stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ($returnType !== '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()
                            ),
                            $statusCode,
                            $response->getHeaders(),
                            $content
                        );
                    }
                }
            }

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

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\FattureInCloud\Model\CreateCashbookEntryResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation createCashbookEntryAsync
     *
     * Create Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateCashbookEntryRequest|null $create_cashbook_entry_request Cashbook entry. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createCashbookEntryAsync($company_id, $create_cashbook_entry_request = null, string $contentType = self::contentTypes['createCashbookEntry'][0])
    {
        return $this->createCashbookEntryAsyncWithHttpInfo($company_id, $create_cashbook_entry_request, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation createCashbookEntryAsyncWithHttpInfo
     *
     * Create Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateCashbookEntryRequest|null $create_cashbook_entry_request Cashbook entry. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createCashbookEntryAsyncWithHttpInfo($company_id, $create_cashbook_entry_request = null, string $contentType = self::contentTypes['createCashbookEntry'][0])
    {
        $returnType = '\FattureInCloud\Model\CreateCashbookEntryResponse';
        $request = $this->createCashbookEntryRequest($company_id, $create_cashbook_entry_request, $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 'createCashbookEntry'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateCashbookEntryRequest|null $create_cashbook_entry_request Cashbook entry. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function createCashbookEntryRequest($company_id, $create_cashbook_entry_request = null, string $contentType = self::contentTypes['createCashbookEntry'][0])
    {

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



        $resourcePath = '/c/{company_id}/cashbook';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

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

        // this endpoint requires OAuth (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $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 deleteCashbookEntry
     *
     * Delete Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteCashbookEntry($company_id, $document_id, string $contentType = self::contentTypes['deleteCashbookEntry'][0])
    {
        $this->deleteCashbookEntryWithHttpInfo($company_id, $document_id, $contentType);
    }

    /**
     * Operation deleteCashbookEntryWithHttpInfo
     *
     * Delete Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteCashbookEntryWithHttpInfo($company_id, $document_id, string $contentType = self::contentTypes['deleteCashbookEntry'][0])
    {
        $request = $this->deleteCashbookEntryRequest($company_id, $document_id, $contentType);

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

            $statusCode = $response->getStatusCode();


            return [null, $statusCode, $response->getHeaders()];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
            }
            throw $e;
        }
    }

    /**
     * Operation deleteCashbookEntryAsync
     *
     * Delete Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteCashbookEntryAsync($company_id, $document_id, string $contentType = self::contentTypes['deleteCashbookEntry'][0])
    {
        return $this->deleteCashbookEntryAsyncWithHttpInfo($company_id, $document_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation deleteCashbookEntryAsyncWithHttpInfo
     *
     * Delete Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteCashbookEntryAsyncWithHttpInfo($company_id, $document_id, string $contentType = self::contentTypes['deleteCashbookEntry'][0])
    {
        $returnType = '';
        $request = $this->deleteCashbookEntryRequest($company_id, $document_id, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    return [null, $response->getStatusCode(), $response->getHeaders()];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteCashbookEntry'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function deleteCashbookEntryRequest($company_id, $document_id, string $contentType = self::contentTypes['deleteCashbookEntry'][0])
    {

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

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


        $resourcePath = '/c/{company_id}/cashbook/{document_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


        $headers = $this->headerSelector->selectHeaders(
            [],
            $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);
            }
        }

        // this endpoint requires OAuth (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

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

    /**
     * Operation getCashbookEntry
     *
     * Get Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \FattureInCloud\Model\GetCashbookEntryResponse
     */
    public function getCashbookEntry($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getCashbookEntry'][0])
    {
        list($response) = $this->getCashbookEntryWithHttpInfo($company_id, $document_id, $fields, $fieldset, $contentType);
        return $response;
    }

    /**
     * Operation getCashbookEntryWithHttpInfo
     *
     * Get Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \FattureInCloud\Model\GetCashbookEntryResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCashbookEntryWithHttpInfo($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getCashbookEntry'][0])
    {
        $request = $this->getCashbookEntryRequest($company_id, $document_id, $fields, $fieldset, $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:
                    if ('\FattureInCloud\Model\GetCashbookEntryResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\GetCashbookEntryResponse' !== '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()
                                    ),
                                    $statusCode,
                                    $response->getHeaders(),
                                    $content
                                );
                            }
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, '\FattureInCloud\Model\GetCashbookEntryResponse', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }

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

            $returnType = '\FattureInCloud\Model\GetCashbookEntryResponse';
            if ($returnType === '\SplFileObject') {
                $content = $response->getBody(); //stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ($returnType !== '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()
                            ),
                            $statusCode,
                            $response->getHeaders(),
                            $content
                        );
                    }
                }
            }

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

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\FattureInCloud\Model\GetCashbookEntryResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation getCashbookEntryAsync
     *
     * Get Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCashbookEntryAsync($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getCashbookEntry'][0])
    {
        return $this->getCashbookEntryAsyncWithHttpInfo($company_id, $document_id, $fields, $fieldset, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getCashbookEntryAsyncWithHttpInfo
     *
     * Get Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCashbookEntryAsyncWithHttpInfo($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getCashbookEntry'][0])
    {
        $returnType = '\FattureInCloud\Model\GetCashbookEntryResponse';
        $request = $this->getCashbookEntryRequest($company_id, $document_id, $fields, $fieldset, $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 'getCashbookEntry'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getCashbookEntryRequest($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getCashbookEntry'][0])
    {

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

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




        $resourcePath = '/c/{company_id}/cashbook/{document_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


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


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

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

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

        // this endpoint requires OAuth (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $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 listCashbookEntries
     *
     * List Cashbook Entries
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $date_from Start date. (required)
     * @param  string $date_to End date. (required)
     * @param  int|null $year Filter cashbook by year. (optional)
     * @param  string|null $type Filter cashbook by type. (optional)
     * @param  int|null $payment_account_id Filter by payment account. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listCashbookEntries'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \FattureInCloud\Model\ListCashbookEntriesResponse
     */
    public function listCashbookEntries($company_id, $date_from, $date_to, $year = null, $type = null, $payment_account_id = null, string $contentType = self::contentTypes['listCashbookEntries'][0])
    {
        list($response) = $this->listCashbookEntriesWithHttpInfo($company_id, $date_from, $date_to, $year, $type, $payment_account_id, $contentType);
        return $response;
    }

    /**
     * Operation listCashbookEntriesWithHttpInfo
     *
     * List Cashbook Entries
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $date_from Start date. (required)
     * @param  string $date_to End date. (required)
     * @param  int|null $year Filter cashbook by year. (optional)
     * @param  string|null $type Filter cashbook by type. (optional)
     * @param  int|null $payment_account_id Filter by payment account. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listCashbookEntries'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \FattureInCloud\Model\ListCashbookEntriesResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function listCashbookEntriesWithHttpInfo($company_id, $date_from, $date_to, $year = null, $type = null, $payment_account_id = null, string $contentType = self::contentTypes['listCashbookEntries'][0])
    {
        $request = $this->listCashbookEntriesRequest($company_id, $date_from, $date_to, $year, $type, $payment_account_id, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch ($statusCode) {
                case 200:
                    if ('\FattureInCloud\Model\ListCashbookEntriesResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\ListCashbookEntriesResponse' !== '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()
                                    ),
                                    $statusCode,
                                    $response->getHeaders(),
                                    $content
                                );
                            }
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, '\FattureInCloud\Model\ListCashbookEntriesResponse', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }

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

            $returnType = '\FattureInCloud\Model\ListCashbookEntriesResponse';
            if ($returnType === '\SplFileObject') {
                $content = $response->getBody(); //stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ($returnType !== '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()
                            ),
                            $statusCode,
                            $response->getHeaders(),
                            $content
                        );
                    }
                }
            }

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

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\FattureInCloud\Model\ListCashbookEntriesResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation listCashbookEntriesAsync
     *
     * List Cashbook Entries
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $date_from Start date. (required)
     * @param  string $date_to End date. (required)
     * @param  int|null $year Filter cashbook by year. (optional)
     * @param  string|null $type Filter cashbook by type. (optional)
     * @param  int|null $payment_account_id Filter by payment account. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listCashbookEntries'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listCashbookEntriesAsync($company_id, $date_from, $date_to, $year = null, $type = null, $payment_account_id = null, string $contentType = self::contentTypes['listCashbookEntries'][0])
    {
        return $this->listCashbookEntriesAsyncWithHttpInfo($company_id, $date_from, $date_to, $year, $type, $payment_account_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation listCashbookEntriesAsyncWithHttpInfo
     *
     * List Cashbook Entries
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $date_from Start date. (required)
     * @param  string $date_to End date. (required)
     * @param  int|null $year Filter cashbook by year. (optional)
     * @param  string|null $type Filter cashbook by type. (optional)
     * @param  int|null $payment_account_id Filter by payment account. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listCashbookEntries'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listCashbookEntriesAsyncWithHttpInfo($company_id, $date_from, $date_to, $year = null, $type = null, $payment_account_id = null, string $contentType = self::contentTypes['listCashbookEntries'][0])
    {
        $returnType = '\FattureInCloud\Model\ListCashbookEntriesResponse';
        $request = $this->listCashbookEntriesRequest($company_id, $date_from, $date_to, $year, $type, $payment_account_id, $contentType);

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

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

    /**
     * Create request for operation 'listCashbookEntries'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $date_from Start date. (required)
     * @param  string $date_to End date. (required)
     * @param  int|null $year Filter cashbook by year. (optional)
     * @param  string|null $type Filter cashbook by type. (optional)
     * @param  int|null $payment_account_id Filter by payment account. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listCashbookEntries'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function listCashbookEntriesRequest($company_id, $date_from, $date_to, $year = null, $type = null, $payment_account_id = null, string $contentType = self::contentTypes['listCashbookEntries'][0])
    {

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

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

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





        $resourcePath = '/c/{company_id}/cashbook';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


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


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

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

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

        // this endpoint requires OAuth (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $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 modifyCashbookEntry
     *
     * Modify Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyCashbookEntryRequest|null $modify_cashbook_entry_request Cashbook Entry (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \FattureInCloud\Model\ModifyCashbookEntryResponse
     */
    public function modifyCashbookEntry($company_id, $document_id, $modify_cashbook_entry_request = null, string $contentType = self::contentTypes['modifyCashbookEntry'][0])
    {
        list($response) = $this->modifyCashbookEntryWithHttpInfo($company_id, $document_id, $modify_cashbook_entry_request, $contentType);
        return $response;
    }

    /**
     * Operation modifyCashbookEntryWithHttpInfo
     *
     * Modify Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyCashbookEntryRequest|null $modify_cashbook_entry_request Cashbook Entry (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyCashbookEntry'] to see the possible values for this operation
     *
     * @throws \FattureInCloud\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \FattureInCloud\Model\ModifyCashbookEntryResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function modifyCashbookEntryWithHttpInfo($company_id, $document_id, $modify_cashbook_entry_request = null, string $contentType = self::contentTypes['modifyCashbookEntry'][0])
    {
        $request = $this->modifyCashbookEntryRequest($company_id, $document_id, $modify_cashbook_entry_request, $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:
                    if ('\FattureInCloud\Model\ModifyCashbookEntryResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\ModifyCashbookEntryResponse' !== '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()
                                    ),
                                    $statusCode,
                                    $response->getHeaders(),
                                    $content
                                );
                            }
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, '\FattureInCloud\Model\ModifyCashbookEntryResponse', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }

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

            $returnType = '\FattureInCloud\Model\ModifyCashbookEntryResponse';
            if ($returnType === '\SplFileObject') {
                $content = $response->getBody(); //stream goes to serializer
            } else {
                $content = (string) $response->getBody();
                if ($returnType !== '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()
                            ),
                            $statusCode,
                            $response->getHeaders(),
                            $content
                        );
                    }
                }
            }

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

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\FattureInCloud\Model\ModifyCashbookEntryResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation modifyCashbookEntryAsync
     *
     * Modify Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyCashbookEntryRequest|null $modify_cashbook_entry_request Cashbook Entry (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function modifyCashbookEntryAsync($company_id, $document_id, $modify_cashbook_entry_request = null, string $contentType = self::contentTypes['modifyCashbookEntry'][0])
    {
        return $this->modifyCashbookEntryAsyncWithHttpInfo($company_id, $document_id, $modify_cashbook_entry_request, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation modifyCashbookEntryAsyncWithHttpInfo
     *
     * Modify Cashbook Entry
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyCashbookEntryRequest|null $modify_cashbook_entry_request Cashbook Entry (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function modifyCashbookEntryAsyncWithHttpInfo($company_id, $document_id, $modify_cashbook_entry_request = null, string $contentType = self::contentTypes['modifyCashbookEntry'][0])
    {
        $returnType = '\FattureInCloud\Model\ModifyCashbookEntryResponse';
        $request = $this->modifyCashbookEntryRequest($company_id, $document_id, $modify_cashbook_entry_request, $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 'modifyCashbookEntry'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyCashbookEntryRequest|null $modify_cashbook_entry_request Cashbook Entry (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyCashbookEntry'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function modifyCashbookEntryRequest($company_id, $document_id, $modify_cashbook_entry_request = null, string $contentType = self::contentTypes['modifyCashbookEntry'][0])
    {

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

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



        $resourcePath = '/c/{company_id}/cashbook/{document_id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

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

        // this endpoint requires OAuth (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

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

        return $options;
    }
}
