<?php

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

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'createReceipt' => [
            'application/json',
        ],
        'deleteReceipt' => [
            'application/json',
        ],
        'getReceipt' => [
            'application/json',
        ],
        'getReceiptPreCreateInfo' => [
            'application/json',
        ],
        'getReceiptsMonthlyTotals' => [
            'application/json',
        ],
        'listReceipts' => [
            'application/json',
        ],
        'modifyReceipt' => [
            '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 createReceipt
     *
     * Create Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateReceiptRequest|null $create_receipt_request The Receipt to create. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createReceipt'] 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\CreateReceiptResponse
     */
    public function createReceipt($company_id, $create_receipt_request = null, string $contentType = self::contentTypes['createReceipt'][0])
    {
        list($response) = $this->createReceiptWithHttpInfo($company_id, $create_receipt_request, $contentType);
        return $response;
    }

    /**
     * Operation createReceiptWithHttpInfo
     *
     * Create Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateReceiptRequest|null $create_receipt_request The Receipt to create. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createReceipt'] 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\CreateReceiptResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function createReceiptWithHttpInfo($company_id, $create_receipt_request = null, string $contentType = self::contentTypes['createReceipt'][0])
    {
        $request = $this->createReceiptRequest($company_id, $create_receipt_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\CreateReceiptResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\CreateReceiptResponse' !== '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\CreateReceiptResponse', []),
                        $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\CreateReceiptResponse';
            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\CreateReceiptResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

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

    /**
     * Operation createReceiptAsyncWithHttpInfo
     *
     * Create Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateReceiptRequest|null $create_receipt_request The Receipt to create. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createReceiptAsyncWithHttpInfo($company_id, $create_receipt_request = null, string $contentType = self::contentTypes['createReceipt'][0])
    {
        $returnType = '\FattureInCloud\Model\CreateReceiptResponse';
        $request = $this->createReceiptRequest($company_id, $create_receipt_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 'createReceipt'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  \FattureInCloud\Model\CreateReceiptRequest|null $create_receipt_request The Receipt to create. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['createReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function createReceiptRequest($company_id, $create_receipt_request = null, string $contentType = self::contentTypes['createReceipt'][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 createReceipt'
            );
        }



        $resourcePath = '/c/{company_id}/receipts';
        $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_receipt_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_receipt_request));
            } else {
                $httpBody = $create_receipt_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 deleteReceipt
     *
     * Delete Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteReceipt'] 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 deleteReceipt($company_id, $document_id, string $contentType = self::contentTypes['deleteReceipt'][0])
    {
        $this->deleteReceiptWithHttpInfo($company_id, $document_id, $contentType);
    }

    /**
     * Operation deleteReceiptWithHttpInfo
     *
     * Delete Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteReceipt'] 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 deleteReceiptWithHttpInfo($company_id, $document_id, string $contentType = self::contentTypes['deleteReceipt'][0])
    {
        $request = $this->deleteReceiptRequest($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 deleteReceiptAsync
     *
     * Delete Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteReceiptAsync($company_id, $document_id, string $contentType = self::contentTypes['deleteReceipt'][0])
    {
        return $this->deleteReceiptAsyncWithHttpInfo($company_id, $document_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation deleteReceiptAsyncWithHttpInfo
     *
     * Delete Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteReceiptAsyncWithHttpInfo($company_id, $document_id, string $contentType = self::contentTypes['deleteReceipt'][0])
    {
        $returnType = '';
        $request = $this->deleteReceiptRequest($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 'deleteReceipt'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deleteReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function deleteReceiptRequest($company_id, $document_id, string $contentType = self::contentTypes['deleteReceipt'][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 deleteReceipt'
            );
        }

        // 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 deleteReceipt'
            );
        }


        $resourcePath = '/c/{company_id}/receipts/{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 getReceipt
     *
     * Get Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $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['getReceipt'] 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\GetReceiptResponse
     */
    public function getReceipt($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getReceipt'][0])
    {
        list($response) = $this->getReceiptWithHttpInfo($company_id, $document_id, $fields, $fieldset, $contentType);
        return $response;
    }

    /**
     * Operation getReceiptWithHttpInfo
     *
     * Get Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $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['getReceipt'] 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\GetReceiptResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptWithHttpInfo($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getReceipt'][0])
    {
        $request = $this->getReceiptRequest($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\GetReceiptResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\GetReceiptResponse' !== '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\GetReceiptResponse', []),
                        $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\GetReceiptResponse';
            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\GetReceiptResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation getReceiptAsync
     *
     * Get Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $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['getReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptAsync($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getReceipt'][0])
    {
        return $this->getReceiptAsyncWithHttpInfo($company_id, $document_id, $fields, $fieldset, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getReceiptAsyncWithHttpInfo
     *
     * Get Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $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['getReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptAsyncWithHttpInfo($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getReceipt'][0])
    {
        $returnType = '\FattureInCloud\Model\GetReceiptResponse';
        $request = $this->getReceiptRequest($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 'getReceipt'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $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['getReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getReceiptRequest($company_id, $document_id, $fields = null, $fieldset = null, string $contentType = self::contentTypes['getReceipt'][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 getReceipt'
            );
        }

        // 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 getReceipt'
            );
        }




        $resourcePath = '/c/{company_id}/receipts/{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 getReceiptPreCreateInfo
     *
     * Get Receipt Pre-Create Info
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptPreCreateInfo'] 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\GetReceiptPreCreateInfoResponse
     */
    public function getReceiptPreCreateInfo($company_id, string $contentType = self::contentTypes['getReceiptPreCreateInfo'][0])
    {
        list($response) = $this->getReceiptPreCreateInfoWithHttpInfo($company_id, $contentType);
        return $response;
    }

    /**
     * Operation getReceiptPreCreateInfoWithHttpInfo
     *
     * Get Receipt Pre-Create Info
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptPreCreateInfo'] 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\GetReceiptPreCreateInfoResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptPreCreateInfoWithHttpInfo($company_id, string $contentType = self::contentTypes['getReceiptPreCreateInfo'][0])
    {
        $request = $this->getReceiptPreCreateInfoRequest($company_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\GetReceiptPreCreateInfoResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\GetReceiptPreCreateInfoResponse' !== '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\GetReceiptPreCreateInfoResponse', []),
                        $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\GetReceiptPreCreateInfoResponse';
            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\GetReceiptPreCreateInfoResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation getReceiptPreCreateInfoAsync
     *
     * Get Receipt Pre-Create Info
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptPreCreateInfo'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptPreCreateInfoAsync($company_id, string $contentType = self::contentTypes['getReceiptPreCreateInfo'][0])
    {
        return $this->getReceiptPreCreateInfoAsyncWithHttpInfo($company_id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getReceiptPreCreateInfoAsyncWithHttpInfo
     *
     * Get Receipt Pre-Create Info
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptPreCreateInfo'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptPreCreateInfoAsyncWithHttpInfo($company_id, string $contentType = self::contentTypes['getReceiptPreCreateInfo'][0])
    {
        $returnType = '\FattureInCloud\Model\GetReceiptPreCreateInfoResponse';
        $request = $this->getReceiptPreCreateInfoRequest($company_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 'getReceiptPreCreateInfo'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptPreCreateInfo'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getReceiptPreCreateInfoRequest($company_id, string $contentType = self::contentTypes['getReceiptPreCreateInfo'][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 getReceiptPreCreateInfo'
            );
        }


        $resourcePath = '/c/{company_id}/receipts/info';
        $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 (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 getReceiptsMonthlyTotals
     *
     * Get Receipts Monthly Totals
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $type Receipt Type (required)
     * @param  string $year Year for which you want monthly totals (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptsMonthlyTotals'] 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\GetReceiptsMonthlyTotalsResponse
     */
    public function getReceiptsMonthlyTotals($company_id, $type, $year, string $contentType = self::contentTypes['getReceiptsMonthlyTotals'][0])
    {
        list($response) = $this->getReceiptsMonthlyTotalsWithHttpInfo($company_id, $type, $year, $contentType);
        return $response;
    }

    /**
     * Operation getReceiptsMonthlyTotalsWithHttpInfo
     *
     * Get Receipts Monthly Totals
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $type Receipt Type (required)
     * @param  string $year Year for which you want monthly totals (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptsMonthlyTotals'] 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\GetReceiptsMonthlyTotalsResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptsMonthlyTotalsWithHttpInfo($company_id, $type, $year, string $contentType = self::contentTypes['getReceiptsMonthlyTotals'][0])
    {
        $request = $this->getReceiptsMonthlyTotalsRequest($company_id, $type, $year, $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\GetReceiptsMonthlyTotalsResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\GetReceiptsMonthlyTotalsResponse' !== '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\GetReceiptsMonthlyTotalsResponse', []),
                        $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\GetReceiptsMonthlyTotalsResponse';
            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\GetReceiptsMonthlyTotalsResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation getReceiptsMonthlyTotalsAsync
     *
     * Get Receipts Monthly Totals
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $type Receipt Type (required)
     * @param  string $year Year for which you want monthly totals (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptsMonthlyTotals'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptsMonthlyTotalsAsync($company_id, $type, $year, string $contentType = self::contentTypes['getReceiptsMonthlyTotals'][0])
    {
        return $this->getReceiptsMonthlyTotalsAsyncWithHttpInfo($company_id, $type, $year, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getReceiptsMonthlyTotalsAsyncWithHttpInfo
     *
     * Get Receipts Monthly Totals
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $type Receipt Type (required)
     * @param  string $year Year for which you want monthly totals (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptsMonthlyTotals'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptsMonthlyTotalsAsyncWithHttpInfo($company_id, $type, $year, string $contentType = self::contentTypes['getReceiptsMonthlyTotals'][0])
    {
        $returnType = '\FattureInCloud\Model\GetReceiptsMonthlyTotalsResponse';
        $request = $this->getReceiptsMonthlyTotalsRequest($company_id, $type, $year, $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 'getReceiptsMonthlyTotals'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string $type Receipt Type (required)
     * @param  string $year Year for which you want monthly totals (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getReceiptsMonthlyTotals'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function getReceiptsMonthlyTotalsRequest($company_id, $type, $year, string $contentType = self::contentTypes['getReceiptsMonthlyTotals'][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 getReceiptsMonthlyTotals'
            );
        }

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

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


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

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $type,
            'type', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            true // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $year,
            'year', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            true // 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 listReceipts
     *
     * List Receipts
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  int|null $page The page to retrieve. (optional, default to 1)
     * @param  int|null $per_page The size of the page. (optional, default to 5)
     * @param  string|null $sort List of comma-separated fields for result sorting (minus for desc sorting). (optional)
     * @param  string|null $q Query for filtering the results. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listReceipts'] 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\ListReceiptsResponse
     */
    public function listReceipts($company_id, $fields = null, $fieldset = null, $page = 1, $per_page = 5, $sort = null, $q = null, string $contentType = self::contentTypes['listReceipts'][0])
    {
        list($response) = $this->listReceiptsWithHttpInfo($company_id, $fields, $fieldset, $page, $per_page, $sort, $q, $contentType);
        return $response;
    }

    /**
     * Operation listReceiptsWithHttpInfo
     *
     * List Receipts
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  int|null $page The page to retrieve. (optional, default to 1)
     * @param  int|null $per_page The size of the page. (optional, default to 5)
     * @param  string|null $sort List of comma-separated fields for result sorting (minus for desc sorting). (optional)
     * @param  string|null $q Query for filtering the results. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listReceipts'] 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\ListReceiptsResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function listReceiptsWithHttpInfo($company_id, $fields = null, $fieldset = null, $page = 1, $per_page = 5, $sort = null, $q = null, string $contentType = self::contentTypes['listReceipts'][0])
    {
        $request = $this->listReceiptsRequest($company_id, $fields, $fieldset, $page, $per_page, $sort, $q, $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\ListReceiptsResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\ListReceiptsResponse' !== '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\ListReceiptsResponse', []),
                        $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\ListReceiptsResponse';
            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\ListReceiptsResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation listReceiptsAsync
     *
     * List Receipts
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  int|null $page The page to retrieve. (optional, default to 1)
     * @param  int|null $per_page The size of the page. (optional, default to 5)
     * @param  string|null $sort List of comma-separated fields for result sorting (minus for desc sorting). (optional)
     * @param  string|null $q Query for filtering the results. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listReceipts'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listReceiptsAsync($company_id, $fields = null, $fieldset = null, $page = 1, $per_page = 5, $sort = null, $q = null, string $contentType = self::contentTypes['listReceipts'][0])
    {
        return $this->listReceiptsAsyncWithHttpInfo($company_id, $fields, $fieldset, $page, $per_page, $sort, $q, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation listReceiptsAsyncWithHttpInfo
     *
     * List Receipts
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  int|null $page The page to retrieve. (optional, default to 1)
     * @param  int|null $per_page The size of the page. (optional, default to 5)
     * @param  string|null $sort List of comma-separated fields for result sorting (minus for desc sorting). (optional)
     * @param  string|null $q Query for filtering the results. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listReceipts'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listReceiptsAsyncWithHttpInfo($company_id, $fields = null, $fieldset = null, $page = 1, $per_page = 5, $sort = null, $q = null, string $contentType = self::contentTypes['listReceipts'][0])
    {
        $returnType = '\FattureInCloud\Model\ListReceiptsResponse';
        $request = $this->listReceiptsRequest($company_id, $fields, $fieldset, $page, $per_page, $sort, $q, $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 'listReceipts'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  string|null $fields List of comma-separated fields. (optional)
     * @param  string|null $fieldset Name of the fieldset. (optional)
     * @param  int|null $page The page to retrieve. (optional, default to 1)
     * @param  int|null $per_page The size of the page. (optional, default to 5)
     * @param  string|null $sort List of comma-separated fields for result sorting (minus for desc sorting). (optional)
     * @param  string|null $q Query for filtering the results. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['listReceipts'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function listReceiptsRequest($company_id, $fields = null, $fieldset = null, $page = 1, $per_page = 5, $sort = null, $q = null, string $contentType = self::contentTypes['listReceipts'][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 listReceipts'
            );
        }




        if ($per_page !== null && $per_page > 100) {
            throw new \InvalidArgumentException('invalid value for "$per_page" when calling ReceiptsApi.listReceipts, must be smaller than or equal to 100.');
        }
        if ($per_page !== null && $per_page < 1) {
            throw new \InvalidArgumentException('invalid value for "$per_page" when calling ReceiptsApi.listReceipts, must be bigger than or equal to 1.');
        }




        $resourcePath = '/c/{company_id}/receipts';
        $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
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $page,
            'page', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $per_page,
            'per_page', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $sort,
            'sort', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $q,
            'q', // 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
            );
        }


        $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 modifyReceipt
     *
     * Modify Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyReceiptRequest|null $modify_receipt_request Modified receipt. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyReceipt'] 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\ModifyReceiptResponse
     */
    public function modifyReceipt($company_id, $document_id, $modify_receipt_request = null, string $contentType = self::contentTypes['modifyReceipt'][0])
    {
        list($response) = $this->modifyReceiptWithHttpInfo($company_id, $document_id, $modify_receipt_request, $contentType);
        return $response;
    }

    /**
     * Operation modifyReceiptWithHttpInfo
     *
     * Modify Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyReceiptRequest|null $modify_receipt_request Modified receipt. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyReceipt'] 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\ModifyReceiptResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function modifyReceiptWithHttpInfo($company_id, $document_id, $modify_receipt_request = null, string $contentType = self::contentTypes['modifyReceipt'][0])
    {
        $request = $this->modifyReceiptRequest($company_id, $document_id, $modify_receipt_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\ModifyReceiptResponse' === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ('\FattureInCloud\Model\ModifyReceiptResponse' !== '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\ModifyReceiptResponse', []),
                        $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\ModifyReceiptResponse';
            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\ModifyReceiptResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

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

    /**
     * Operation modifyReceiptAsyncWithHttpInfo
     *
     * Modify Receipt
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyReceiptRequest|null $modify_receipt_request Modified receipt. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function modifyReceiptAsyncWithHttpInfo($company_id, $document_id, $modify_receipt_request = null, string $contentType = self::contentTypes['modifyReceipt'][0])
    {
        $returnType = '\FattureInCloud\Model\ModifyReceiptResponse';
        $request = $this->modifyReceiptRequest($company_id, $document_id, $modify_receipt_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 'modifyReceipt'
     *
     * @param  int $company_id The ID of the company. (required)
     * @param  int $document_id The ID of the document. (required)
     * @param  \FattureInCloud\Model\ModifyReceiptRequest|null $modify_receipt_request Modified receipt. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['modifyReceipt'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function modifyReceiptRequest($company_id, $document_id, $modify_receipt_request = null, string $contentType = self::contentTypes['modifyReceipt'][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 modifyReceipt'
            );
        }

        // 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 modifyReceipt'
            );
        }



        $resourcePath = '/c/{company_id}/receipts/{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_receipt_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_receipt_request));
            } else {
                $httpBody = $modify_receipt_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;
    }
}
