<?php
/**
 * AccountingApi
 * PHP version 5
 *
 * @category Class
 * @package  XeroAPI\XeroPHP Accounting
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * Xero Accounting API
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * OpenAPI spec version: 6.0.0
 * Contact: api@xero.com
 * Generated by: https://openapi-generator.tech
 * OpenAPI Generator version: 5.4.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 XeroAPI\XeroPHP\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use XeroAPI\XeroPHP\ApiException;
use XeroAPI\XeroPHP\Configuration;
use XeroAPI\XeroPHP\HeaderSelector;
use XeroAPI\XeroPHP\AccountingObjectSerializer;

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

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

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

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     */
    public function __construct(
        ClientInterface $client = null,
        Configuration $config = null,
        HeaderSelector $selector = null
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: new Configuration();
        $this->headerSelector = $selector ?: new HeaderSelector();
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation createAccount
     * Creates a new chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Account $account Account object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Accounts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createAccount($xero_tenant_id, $account, $idempotency_key = null)
    {
        list($response) = $this->createAccountWithHttpInfo($xero_tenant_id, $account, $idempotency_key);
        return $response;
    }
    /**
     * Operation createAccountWithHttpInfo
     * Creates a new chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Account $account Account object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Accounts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createAccountWithHttpInfo($xero_tenant_id, $account, $idempotency_key = null)
    {
        $request = $this->createAccountRequest($xero_tenant_id, $account, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Accounts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Accounts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Accounts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createAccountAsync
     * Creates a new chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Account $account Account object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createAccountAsync($xero_tenant_id, $account, $idempotency_key = null)
    {
        return $this->createAccountAsyncWithHttpInfo($xero_tenant_id, $account, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createAccountAsyncWithHttpInfo
     * Creates a new chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Account $account Account object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createAccountAsyncWithHttpInfo($xero_tenant_id, $account, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
        $request = $this->createAccountRequest($xero_tenant_id, $account, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createAccount'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Account $account Account object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createAccountRequest($xero_tenant_id, $account, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createAccount'
            );
        }
        // verify the required parameter 'account' is set
        if ($account === null || (is_array($account) && count($account) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account when calling createAccount'
            );
        }
        $resourcePath = '/Accounts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($account)) {
            $_tempBody = $account;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createAccountAttachmentByFileName
     * Creates an attachment on a specific account
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createAccountAttachmentByFileName($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createAccountAttachmentByFileNameWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createAccountAttachmentByFileNameWithHttpInfo
     * Creates an attachment on a specific account
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createAccountAttachmentByFileNameWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createAccountAttachmentByFileNameAsync
     * Creates an attachment on a specific account
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createAccountAttachmentByFileNameAsync($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createAccountAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createAccountAttachmentByFileNameAsyncWithHttpInfo
     * Creates an attachment on a specific account
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createAccountAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createAccountAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling createAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createAccountAttachmentByFileName'
            );
        }
        $resourcePath = '/Accounts/{AccountID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBankTransactionAttachmentByFileName
     * Creates an attachment for a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBankTransactionAttachmentByFileName($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createBankTransactionAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBankTransactionAttachmentByFileNameWithHttpInfo
     * Creates an attachment for a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBankTransactionAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBankTransactionAttachmentByFileNameAsync
     * Creates an attachment for a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBankTransactionAttachmentByFileNameAsync($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createBankTransactionAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBankTransactionAttachmentByFileNameAsyncWithHttpInfo
     * Creates an attachment for a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBankTransactionAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBankTransactionAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling createBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createBankTransactionAttachmentByFileName'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBankTransactionHistoryRecord
     * Creates a history record for a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBankTransactionHistoryRecord($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createBankTransactionHistoryRecordWithHttpInfo($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBankTransactionHistoryRecordWithHttpInfo
     * Creates a history record for a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBankTransactionHistoryRecordWithHttpInfo($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createBankTransactionHistoryRecordRequest($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBankTransactionHistoryRecordAsync
     * Creates a history record for a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBankTransactionHistoryRecordAsync($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key = null)
    {
        return $this->createBankTransactionHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBankTransactionHistoryRecordAsyncWithHttpInfo
     * Creates a history record for a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBankTransactionHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createBankTransactionHistoryRecordRequest($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBankTransactionHistoryRecord'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBankTransactionHistoryRecordRequest($xero_tenant_id, $bank_transaction_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBankTransactionHistoryRecord'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling createBankTransactionHistoryRecord'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createBankTransactionHistoryRecord'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBankTransactions
     * Creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions BankTransactions with an array of BankTransaction objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBankTransactions($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->createBankTransactionsWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBankTransactionsWithHttpInfo
     * Creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions BankTransactions with an array of BankTransaction objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBankTransactionsWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->createBankTransactionsRequest($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBankTransactionsAsync
     * Creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions BankTransactions with an array of BankTransaction objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBankTransactionsAsync($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->createBankTransactionsAsyncWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBankTransactionsAsyncWithHttpInfo
     * Creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions BankTransactions with an array of BankTransaction objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBankTransactionsAsyncWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
        $request = $this->createBankTransactionsRequest($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBankTransactions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions BankTransactions with an array of BankTransaction objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBankTransactionsRequest($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBankTransactions'
            );
        }
        // verify the required parameter 'bank_transactions' is set
        if ($bank_transactions === null || (is_array($bank_transactions) && count($bank_transactions) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transactions when calling createBankTransactions'
            );
        }
        $resourcePath = '/BankTransactions';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($bank_transactions)) {
            $_tempBody = $bank_transactions;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBankTransfer
     * Creates a bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransfers $bank_transfers BankTransfers with array of BankTransfer objects in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransfers|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBankTransfer($xero_tenant_id, $bank_transfers, $idempotency_key = null)
    {
        list($response) = $this->createBankTransferWithHttpInfo($xero_tenant_id, $bank_transfers, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBankTransferWithHttpInfo
     * Creates a bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransfers $bank_transfers BankTransfers with array of BankTransfer objects in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransfers|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBankTransferWithHttpInfo($xero_tenant_id, $bank_transfers, $idempotency_key = null)
    {
        $request = $this->createBankTransferRequest($xero_tenant_id, $bank_transfers, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransfers' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBankTransferAsync
     * Creates a bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransfers $bank_transfers BankTransfers with array of BankTransfer objects in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBankTransferAsync($xero_tenant_id, $bank_transfers, $idempotency_key = null)
    {
        return $this->createBankTransferAsyncWithHttpInfo($xero_tenant_id, $bank_transfers, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBankTransferAsyncWithHttpInfo
     * Creates a bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransfers $bank_transfers BankTransfers with array of BankTransfer objects in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBankTransferAsyncWithHttpInfo($xero_tenant_id, $bank_transfers, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers';
        $request = $this->createBankTransferRequest($xero_tenant_id, $bank_transfers, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBankTransfer'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransfers $bank_transfers BankTransfers with array of BankTransfer objects in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBankTransferRequest($xero_tenant_id, $bank_transfers, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBankTransfer'
            );
        }
        // verify the required parameter 'bank_transfers' is set
        if ($bank_transfers === null || (is_array($bank_transfers) && count($bank_transfers) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfers when calling createBankTransfer'
            );
        }
        $resourcePath = '/BankTransfers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($bank_transfers)) {
            $_tempBody = $bank_transfers;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBankTransferAttachmentByFileName
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBankTransferAttachmentByFileName($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createBankTransferAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBankTransferAttachmentByFileNameWithHttpInfo
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBankTransferAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBankTransferAttachmentByFileNameAsync
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBankTransferAttachmentByFileNameAsync($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createBankTransferAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBankTransferAttachmentByFileNameAsyncWithHttpInfo
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBankTransferAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBankTransferAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling createBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createBankTransferAttachmentByFileName'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBankTransferHistoryRecord
     * Creates a history record for a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBankTransferHistoryRecord($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createBankTransferHistoryRecordWithHttpInfo($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBankTransferHistoryRecordWithHttpInfo
     * Creates a history record for a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBankTransferHistoryRecordWithHttpInfo($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createBankTransferHistoryRecordRequest($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBankTransferHistoryRecordAsync
     * Creates a history record for a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBankTransferHistoryRecordAsync($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key = null)
    {
        return $this->createBankTransferHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBankTransferHistoryRecordAsyncWithHttpInfo
     * Creates a history record for a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBankTransferHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createBankTransferHistoryRecordRequest($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBankTransferHistoryRecord'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBankTransferHistoryRecordRequest($xero_tenant_id, $bank_transfer_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBankTransferHistoryRecord'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling createBankTransferHistoryRecord'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createBankTransferHistoryRecord'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBatchPayment
     * Creates one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPayments $batch_payments BatchPayments with an array of Payments in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BatchPayments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBatchPayment($xero_tenant_id, $batch_payments, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createBatchPaymentWithHttpInfo($xero_tenant_id, $batch_payments, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBatchPaymentWithHttpInfo
     * Creates one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPayments $batch_payments BatchPayments with an array of Payments in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BatchPayments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBatchPaymentWithHttpInfo($xero_tenant_id, $batch_payments, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createBatchPaymentRequest($xero_tenant_id, $batch_payments, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BatchPayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBatchPaymentAsync
     * Creates one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPayments $batch_payments BatchPayments with an array of Payments in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBatchPaymentAsync($xero_tenant_id, $batch_payments, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createBatchPaymentAsyncWithHttpInfo($xero_tenant_id, $batch_payments, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBatchPaymentAsyncWithHttpInfo
     * Creates one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPayments $batch_payments BatchPayments with an array of Payments in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBatchPaymentAsyncWithHttpInfo($xero_tenant_id, $batch_payments, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
        $request = $this->createBatchPaymentRequest($xero_tenant_id, $batch_payments, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBatchPayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPayments $batch_payments BatchPayments with an array of Payments in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBatchPaymentRequest($xero_tenant_id, $batch_payments, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBatchPayment'
            );
        }
        // verify the required parameter 'batch_payments' is set
        if ($batch_payments === null || (is_array($batch_payments) && count($batch_payments) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $batch_payments when calling createBatchPayment'
            );
        }
        $resourcePath = '/BatchPayments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($batch_payments)) {
            $_tempBody = $batch_payments;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBatchPaymentHistoryRecord
     * Creates a history record for a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBatchPaymentHistoryRecord($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createBatchPaymentHistoryRecordWithHttpInfo($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBatchPaymentHistoryRecordWithHttpInfo
     * Creates a history record for a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBatchPaymentHistoryRecordWithHttpInfo($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createBatchPaymentHistoryRecordRequest($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBatchPaymentHistoryRecordAsync
     * Creates a history record for a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBatchPaymentHistoryRecordAsync($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key = null)
    {
        return $this->createBatchPaymentHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBatchPaymentHistoryRecordAsyncWithHttpInfo
     * Creates a history record for a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBatchPaymentHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createBatchPaymentHistoryRecordRequest($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBatchPaymentHistoryRecord'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBatchPaymentHistoryRecordRequest($xero_tenant_id, $batch_payment_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBatchPaymentHistoryRecord'
            );
        }
        // verify the required parameter 'batch_payment_id' is set
        if ($batch_payment_id === null || (is_array($batch_payment_id) && count($batch_payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $batch_payment_id when calling createBatchPaymentHistoryRecord'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createBatchPaymentHistoryRecord'
            );
        }
        $resourcePath = '/BatchPayments/{BatchPaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($batch_payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BatchPaymentID' . '}',
                AccountingObjectSerializer::toPathValue($batch_payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createBrandingThemePaymentServices
     * Creates a new custom payment service for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PaymentServices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createBrandingThemePaymentServices($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key = null)
    {
        list($response) = $this->createBrandingThemePaymentServicesWithHttpInfo($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key);
        return $response;
    }
    /**
     * Operation createBrandingThemePaymentServicesWithHttpInfo
     * Creates a new custom payment service for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PaymentServices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createBrandingThemePaymentServicesWithHttpInfo($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key = null)
    {
        $request = $this->createBrandingThemePaymentServicesRequest($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PaymentServices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createBrandingThemePaymentServicesAsync
     * Creates a new custom payment service for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createBrandingThemePaymentServicesAsync($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key = null)
    {
        return $this->createBrandingThemePaymentServicesAsyncWithHttpInfo($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createBrandingThemePaymentServicesAsyncWithHttpInfo
     * Creates a new custom payment service for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createBrandingThemePaymentServicesAsyncWithHttpInfo($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
        $request = $this->createBrandingThemePaymentServicesRequest($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createBrandingThemePaymentServices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createBrandingThemePaymentServicesRequest($xero_tenant_id, $branding_theme_id, $payment_services, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createBrandingThemePaymentServices'
            );
        }
        // verify the required parameter 'branding_theme_id' is set
        if ($branding_theme_id === null || (is_array($branding_theme_id) && count($branding_theme_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $branding_theme_id when calling createBrandingThemePaymentServices'
            );
        }
        // verify the required parameter 'payment_services' is set
        if ($payment_services === null || (is_array($payment_services) && count($payment_services) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment_services when calling createBrandingThemePaymentServices'
            );
        }
        $resourcePath = '/BrandingThemes/{BrandingThemeID}/PaymentServices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($branding_theme_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BrandingThemeID' . '}',
                AccountingObjectSerializer::toPathValue($branding_theme_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($payment_services)) {
            $_tempBody = $payment_services;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createContactAttachmentByFileName
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createContactAttachmentByFileName($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createContactAttachmentByFileNameWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createContactAttachmentByFileNameWithHttpInfo
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createContactAttachmentByFileNameWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createContactAttachmentByFileNameAsync
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createContactAttachmentByFileNameAsync($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createContactAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createContactAttachmentByFileNameAsyncWithHttpInfo
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createContactAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createContactAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling createContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createContactAttachmentByFileName'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createContactGroup
     * Creates a contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups ContactGroups with an array of names in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ContactGroups|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createContactGroup($xero_tenant_id, $contact_groups, $idempotency_key = null)
    {
        list($response) = $this->createContactGroupWithHttpInfo($xero_tenant_id, $contact_groups, $idempotency_key);
        return $response;
    }
    /**
     * Operation createContactGroupWithHttpInfo
     * Creates a contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups ContactGroups with an array of names in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ContactGroups|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createContactGroupWithHttpInfo($xero_tenant_id, $contact_groups, $idempotency_key = null)
    {
        $request = $this->createContactGroupRequest($xero_tenant_id, $contact_groups, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ContactGroups' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createContactGroupAsync
     * Creates a contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups ContactGroups with an array of names in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createContactGroupAsync($xero_tenant_id, $contact_groups, $idempotency_key = null)
    {
        return $this->createContactGroupAsyncWithHttpInfo($xero_tenant_id, $contact_groups, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createContactGroupAsyncWithHttpInfo
     * Creates a contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups ContactGroups with an array of names in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createContactGroupAsyncWithHttpInfo($xero_tenant_id, $contact_groups, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
        $request = $this->createContactGroupRequest($xero_tenant_id, $contact_groups, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createContactGroup'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups ContactGroups with an array of names in request body (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createContactGroupRequest($xero_tenant_id, $contact_groups, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createContactGroup'
            );
        }
        // verify the required parameter 'contact_groups' is set
        if ($contact_groups === null || (is_array($contact_groups) && count($contact_groups) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_groups when calling createContactGroup'
            );
        }
        $resourcePath = '/ContactGroups';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($contact_groups)) {
            $_tempBody = $contact_groups;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createContactGroupContacts
     * Creates contacts to a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with array of contacts specifying the ContactID to be added to ContactGroup in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createContactGroupContacts($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key = null)
    {
        list($response) = $this->createContactGroupContactsWithHttpInfo($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key);
        return $response;
    }
    /**
     * Operation createContactGroupContactsWithHttpInfo
     * Creates contacts to a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with array of contacts specifying the ContactID to be added to ContactGroup in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createContactGroupContactsWithHttpInfo($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key = null)
    {
        $request = $this->createContactGroupContactsRequest($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Contacts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Contacts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Contacts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createContactGroupContactsAsync
     * Creates contacts to a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with array of contacts specifying the ContactID to be added to ContactGroup in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createContactGroupContactsAsync($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key = null)
    {
        return $this->createContactGroupContactsAsyncWithHttpInfo($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createContactGroupContactsAsyncWithHttpInfo
     * Creates contacts to a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with array of contacts specifying the ContactID to be added to ContactGroup in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createContactGroupContactsAsyncWithHttpInfo($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
        $request = $this->createContactGroupContactsRequest($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createContactGroupContacts'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with array of contacts specifying the ContactID to be added to ContactGroup in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createContactGroupContactsRequest($xero_tenant_id, $contact_group_id, $contacts, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createContactGroupContacts'
            );
        }
        // verify the required parameter 'contact_group_id' is set
        if ($contact_group_id === null || (is_array($contact_group_id) && count($contact_group_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_group_id when calling createContactGroupContacts'
            );
        }
        // verify the required parameter 'contacts' is set
        if ($contacts === null || (is_array($contacts) && count($contacts) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contacts when calling createContactGroupContacts'
            );
        }
        $resourcePath = '/ContactGroups/{ContactGroupID}/Contacts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($contact_group_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactGroupID' . '}',
                AccountingObjectSerializer::toPathValue($contact_group_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($contacts)) {
            $_tempBody = $contacts;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createContactHistory
     * Creates a new history record for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createContactHistory($xero_tenant_id, $contact_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createContactHistoryWithHttpInfo($xero_tenant_id, $contact_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createContactHistoryWithHttpInfo
     * Creates a new history record for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createContactHistoryWithHttpInfo($xero_tenant_id, $contact_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createContactHistoryRequest($xero_tenant_id, $contact_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createContactHistoryAsync
     * Creates a new history record for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createContactHistoryAsync($xero_tenant_id, $contact_id, $history_records, $idempotency_key = null)
    {
        return $this->createContactHistoryAsyncWithHttpInfo($xero_tenant_id, $contact_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createContactHistoryAsyncWithHttpInfo
     * Creates a new history record for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createContactHistoryAsyncWithHttpInfo($xero_tenant_id, $contact_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createContactHistoryRequest($xero_tenant_id, $contact_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createContactHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createContactHistoryRequest($xero_tenant_id, $contact_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createContactHistory'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling createContactHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createContactHistory'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createContacts
     * Creates multiple contacts (bulk) in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with an array of Contact objects to create in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createContacts($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createContactsWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createContactsWithHttpInfo
     * Creates multiple contacts (bulk) in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with an array of Contact objects to create in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createContactsWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createContactsRequest($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Contacts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Contacts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Contacts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createContactsAsync
     * Creates multiple contacts (bulk) in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with an array of Contact objects to create in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createContactsAsync($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createContactsAsyncWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createContactsAsyncWithHttpInfo
     * Creates multiple contacts (bulk) in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with an array of Contact objects to create in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createContactsAsyncWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
        $request = $this->createContactsRequest($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createContacts'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts Contacts with an array of Contact objects to create in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createContactsRequest($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createContacts'
            );
        }
        // verify the required parameter 'contacts' is set
        if ($contacts === null || (is_array($contacts) && count($contacts) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contacts when calling createContacts'
            );
        }
        $resourcePath = '/Contacts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($contacts)) {
            $_tempBody = $contacts;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createCreditNoteAllocation
     * Creates allocation for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with array of Allocation object in body of request. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Allocations|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createCreditNoteAllocation($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createCreditNoteAllocationWithHttpInfo($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createCreditNoteAllocationWithHttpInfo
     * Creates allocation for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with array of Allocation object in body of request. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Allocations|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createCreditNoteAllocationWithHttpInfo($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createCreditNoteAllocationRequest($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Allocations' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Allocations', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocations';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Allocations',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createCreditNoteAllocationAsync
     * Creates allocation for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with array of Allocation object in body of request. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createCreditNoteAllocationAsync($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createCreditNoteAllocationAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createCreditNoteAllocationAsyncWithHttpInfo
     * Creates allocation for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with array of Allocation object in body of request. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createCreditNoteAllocationAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocations';
        $request = $this->createCreditNoteAllocationRequest($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createCreditNoteAllocation'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with array of Allocation object in body of request. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createCreditNoteAllocationRequest($xero_tenant_id, $credit_note_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createCreditNoteAllocation'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling createCreditNoteAllocation'
            );
        }
        // verify the required parameter 'allocations' is set
        if ($allocations === null || (is_array($allocations) && count($allocations) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $allocations when calling createCreditNoteAllocation'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/Allocations';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($allocations)) {
            $_tempBody = $allocations;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createCreditNoteAttachmentByFileName
     * Creates an attachment for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createCreditNoteAttachmentByFileName($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        list($response) = $this->createCreditNoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online, $idempotency_key);
        return $response;
    }
    /**
     * Operation createCreditNoteAttachmentByFileNameWithHttpInfo
     * Creates an attachment for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createCreditNoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        $request = $this->createCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createCreditNoteAttachmentByFileNameAsync
     * Creates an attachment for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createCreditNoteAttachmentByFileNameAsync($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        return $this->createCreditNoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createCreditNoteAttachmentByFileNameAsyncWithHttpInfo
     * Creates an attachment for a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createCreditNoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createCreditNoteAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling createCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createCreditNoteAttachmentByFileName'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($include_online !== null) {
            $queryParams['IncludeOnline'] = $include_online ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createCreditNoteHistory
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createCreditNoteHistory($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createCreditNoteHistoryWithHttpInfo($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createCreditNoteHistoryWithHttpInfo
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createCreditNoteHistoryWithHttpInfo($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createCreditNoteHistoryRequest($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createCreditNoteHistoryAsync
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createCreditNoteHistoryAsync($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key = null)
    {
        return $this->createCreditNoteHistoryAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createCreditNoteHistoryAsyncWithHttpInfo
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createCreditNoteHistoryAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createCreditNoteHistoryRequest($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createCreditNoteHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createCreditNoteHistoryRequest($xero_tenant_id, $credit_note_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createCreditNoteHistory'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling createCreditNoteHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createCreditNoteHistory'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createCreditNotes
     * Creates a new credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes Credit Notes with array of CreditNote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\CreditNotes|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createCreditNotes($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->createCreditNotesWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation createCreditNotesWithHttpInfo
     * Creates a new credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes Credit Notes with array of CreditNote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\CreditNotes|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createCreditNotesWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->createCreditNotesRequest($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\CreditNotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createCreditNotesAsync
     * Creates a new credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes Credit Notes with array of CreditNote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createCreditNotesAsync($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->createCreditNotesAsyncWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createCreditNotesAsyncWithHttpInfo
     * Creates a new credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes Credit Notes with array of CreditNote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createCreditNotesAsyncWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
        $request = $this->createCreditNotesRequest($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createCreditNotes'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes Credit Notes with array of CreditNote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createCreditNotesRequest($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createCreditNotes'
            );
        }
        // verify the required parameter 'credit_notes' is set
        if ($credit_notes === null || (is_array($credit_notes) && count($credit_notes) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_notes when calling createCreditNotes'
            );
        }
        $resourcePath = '/CreditNotes';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($credit_notes)) {
            $_tempBody = $credit_notes;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createCurrency
     * Create a new currency for a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Currency $currency Currency object in the body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Currencies
     */
    public function createCurrency($xero_tenant_id, $currency, $idempotency_key = null)
    {
        list($response) = $this->createCurrencyWithHttpInfo($xero_tenant_id, $currency, $idempotency_key);
        return $response;
    }
    /**
     * Operation createCurrencyWithHttpInfo
     * Create a new currency for a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Currency $currency Currency object in the body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Currencies, HTTP status code, HTTP response headers (array of strings)
     */
    public function createCurrencyWithHttpInfo($xero_tenant_id, $currency, $idempotency_key = null)
    {
        $request = $this->createCurrencyRequest($xero_tenant_id, $currency, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Currencies' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Currencies', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Currencies';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Currencies',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createCurrencyAsync
     * Create a new currency for a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Currency $currency Currency object in the body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createCurrencyAsync($xero_tenant_id, $currency, $idempotency_key = null)
    {
        return $this->createCurrencyAsyncWithHttpInfo($xero_tenant_id, $currency, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createCurrencyAsyncWithHttpInfo
     * Create a new currency for a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Currency $currency Currency object in the body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createCurrencyAsyncWithHttpInfo($xero_tenant_id, $currency, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Currencies';
        $request = $this->createCurrencyRequest($xero_tenant_id, $currency, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createCurrency'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Currency $currency Currency object in the body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createCurrencyRequest($xero_tenant_id, $currency, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createCurrency'
            );
        }
        // verify the required parameter 'currency' is set
        if ($currency === null || (is_array($currency) && count($currency) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $currency when calling createCurrency'
            );
        }
        $resourcePath = '/Currencies';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($currency)) {
            $_tempBody = $currency;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createEmployees
     * Creates new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Employees|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createEmployees($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createEmployeesWithHttpInfo($xero_tenant_id, $employees, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createEmployeesWithHttpInfo
     * Creates new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Employees|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createEmployeesWithHttpInfo($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createEmployeesRequest($xero_tenant_id, $employees, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Employees' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Employees', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Employees',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createEmployeesAsync
     * Creates new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createEmployeesAsync($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createEmployeesAsyncWithHttpInfo($xero_tenant_id, $employees, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createEmployeesAsyncWithHttpInfo
     * Creates new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createEmployeesAsyncWithHttpInfo($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
        $request = $this->createEmployeesRequest($xero_tenant_id, $employees, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createEmployees'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createEmployeesRequest($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createEmployees'
            );
        }
        // verify the required parameter 'employees' is set
        if ($employees === null || (is_array($employees) && count($employees) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $employees when calling createEmployees'
            );
        }
        $resourcePath = '/Employees';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($employees)) {
            $_tempBody = $employees;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createExpenseClaimHistory
     * Creates a history record for a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function createExpenseClaimHistory($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createExpenseClaimHistoryWithHttpInfo($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createExpenseClaimHistoryWithHttpInfo
     * Creates a history record for a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function createExpenseClaimHistoryWithHttpInfo($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createExpenseClaimHistoryRequest($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createExpenseClaimHistoryAsync
     * Creates a history record for a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createExpenseClaimHistoryAsync($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key = null)
    {
        return $this->createExpenseClaimHistoryAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createExpenseClaimHistoryAsyncWithHttpInfo
     * Creates a history record for a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createExpenseClaimHistoryAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createExpenseClaimHistoryRequest($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createExpenseClaimHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createExpenseClaimHistoryRequest($xero_tenant_id, $expense_claim_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createExpenseClaimHistory'
            );
        }
        // verify the required parameter 'expense_claim_id' is set
        if ($expense_claim_id === null || (is_array($expense_claim_id) && count($expense_claim_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $expense_claim_id when calling createExpenseClaimHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createExpenseClaimHistory'
            );
        }
        $resourcePath = '/ExpenseClaims/{ExpenseClaimID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($expense_claim_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ExpenseClaimID' . '}',
                AccountingObjectSerializer::toPathValue($expense_claim_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createExpenseClaims
     * Creates expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims ExpenseClaims with array of ExpenseClaim object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createExpenseClaims($xero_tenant_id, $expense_claims, $idempotency_key = null)
    {
        list($response) = $this->createExpenseClaimsWithHttpInfo($xero_tenant_id, $expense_claims, $idempotency_key);
        return $response;
    }
    /**
     * Operation createExpenseClaimsWithHttpInfo
     * Creates expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims ExpenseClaims with array of ExpenseClaim object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createExpenseClaimsWithHttpInfo($xero_tenant_id, $expense_claims, $idempotency_key = null)
    {
        $request = $this->createExpenseClaimsRequest($xero_tenant_id, $expense_claims, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createExpenseClaimsAsync
     * Creates expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims ExpenseClaims with array of ExpenseClaim object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createExpenseClaimsAsync($xero_tenant_id, $expense_claims, $idempotency_key = null)
    {
        return $this->createExpenseClaimsAsyncWithHttpInfo($xero_tenant_id, $expense_claims, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createExpenseClaimsAsyncWithHttpInfo
     * Creates expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims ExpenseClaims with array of ExpenseClaim object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createExpenseClaimsAsyncWithHttpInfo($xero_tenant_id, $expense_claims, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
        $request = $this->createExpenseClaimsRequest($xero_tenant_id, $expense_claims, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createExpenseClaims'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims ExpenseClaims with array of ExpenseClaim object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createExpenseClaimsRequest($xero_tenant_id, $expense_claims, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createExpenseClaims'
            );
        }
        // verify the required parameter 'expense_claims' is set
        if ($expense_claims === null || (is_array($expense_claims) && count($expense_claims) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $expense_claims when calling createExpenseClaims'
            );
        }
        $resourcePath = '/ExpenseClaims';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($expense_claims)) {
            $_tempBody = $expense_claims;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createInvoiceAttachmentByFileName
     * Creates an attachment for a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createInvoiceAttachmentByFileName($xero_tenant_id, $invoice_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        list($response) = $this->createInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $include_online, $idempotency_key);
        return $response;
    }
    /**
     * Operation createInvoiceAttachmentByFileNameWithHttpInfo
     * Creates an attachment for a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        $request = $this->createInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $body, $include_online, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createInvoiceAttachmentByFileNameAsync
     * Creates an attachment for a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createInvoiceAttachmentByFileNameAsync($xero_tenant_id, $invoice_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        return $this->createInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $include_online, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createInvoiceAttachmentByFileNameAsyncWithHttpInfo
     * Creates an attachment for a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $body, $include_online, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createInvoiceAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  bool $include_online Allows an attachment to be seen by the end customer within their online invoice (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $body, $include_online = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling createInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createInvoiceAttachmentByFileName'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($include_online !== null) {
            $queryParams['IncludeOnline'] = $include_online ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createInvoiceHistory
     * Creates a history record for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createInvoiceHistory($xero_tenant_id, $invoice_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createInvoiceHistoryWithHttpInfo($xero_tenant_id, $invoice_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createInvoiceHistoryWithHttpInfo
     * Creates a history record for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createInvoiceHistoryWithHttpInfo($xero_tenant_id, $invoice_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createInvoiceHistoryRequest($xero_tenant_id, $invoice_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createInvoiceHistoryAsync
     * Creates a history record for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createInvoiceHistoryAsync($xero_tenant_id, $invoice_id, $history_records, $idempotency_key = null)
    {
        return $this->createInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createInvoiceHistoryAsyncWithHttpInfo
     * Creates a history record for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createInvoiceHistoryRequest($xero_tenant_id, $invoice_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createInvoiceHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createInvoiceHistoryRequest($xero_tenant_id, $invoice_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createInvoiceHistory'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling createInvoiceHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createInvoiceHistory'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createInvoices
     * Creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices Invoices with an array of invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Invoices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createInvoices($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->createInvoicesWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation createInvoicesWithHttpInfo
     * Creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices Invoices with an array of invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Invoices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createInvoicesWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->createInvoicesRequest($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Invoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Invoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Invoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createInvoicesAsync
     * Creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices Invoices with an array of invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createInvoicesAsync($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->createInvoicesAsyncWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createInvoicesAsyncWithHttpInfo
     * Creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices Invoices with an array of invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createInvoicesAsyncWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
        $request = $this->createInvoicesRequest($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createInvoices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices Invoices with an array of invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createInvoicesRequest($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createInvoices'
            );
        }
        // verify the required parameter 'invoices' is set
        if ($invoices === null || (is_array($invoices) && count($invoices) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoices when calling createInvoices'
            );
        }
        $resourcePath = '/Invoices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($invoices)) {
            $_tempBody = $invoices;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createItemHistory
     * Creates a history record for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function createItemHistory($xero_tenant_id, $item_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createItemHistoryWithHttpInfo($xero_tenant_id, $item_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createItemHistoryWithHttpInfo
     * Creates a history record for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function createItemHistoryWithHttpInfo($xero_tenant_id, $item_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createItemHistoryRequest($xero_tenant_id, $item_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createItemHistoryAsync
     * Creates a history record for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createItemHistoryAsync($xero_tenant_id, $item_id, $history_records, $idempotency_key = null)
    {
        return $this->createItemHistoryAsyncWithHttpInfo($xero_tenant_id, $item_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createItemHistoryAsyncWithHttpInfo
     * Creates a history record for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createItemHistoryAsyncWithHttpInfo($xero_tenant_id, $item_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createItemHistoryRequest($xero_tenant_id, $item_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createItemHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createItemHistoryRequest($xero_tenant_id, $item_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createItemHistory'
            );
        }
        // verify the required parameter 'item_id' is set
        if ($item_id === null || (is_array($item_id) && count($item_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $item_id when calling createItemHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createItemHistory'
            );
        }
        $resourcePath = '/Items/{ItemID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($item_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ItemID' . '}',
                AccountingObjectSerializer::toPathValue($item_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createItems
     * Creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items Items with an array of Item objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Items|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createItems($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->createItemsWithHttpInfo($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation createItemsWithHttpInfo
     * Creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items Items with an array of Item objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Items|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createItemsWithHttpInfo($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->createItemsRequest($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Items' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Items', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Items',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createItemsAsync
     * Creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items Items with an array of Item objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createItemsAsync($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->createItemsAsyncWithHttpInfo($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createItemsAsyncWithHttpInfo
     * Creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items Items with an array of Item objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createItemsAsyncWithHttpInfo($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
        $request = $this->createItemsRequest($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createItems'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items Items with an array of Item objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createItemsRequest($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createItems'
            );
        }
        // verify the required parameter 'items' is set
        if ($items === null || (is_array($items) && count($items) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $items when calling createItems'
            );
        }
        $resourcePath = '/Items';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($items)) {
            $_tempBody = $items;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createLinkedTransaction
     * Creates linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransaction $linked_transaction LinkedTransaction object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createLinkedTransaction($xero_tenant_id, $linked_transaction, $idempotency_key = null)
    {
        list($response) = $this->createLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction, $idempotency_key);
        return $response;
    }
    /**
     * Operation createLinkedTransactionWithHttpInfo
     * Creates linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransaction $linked_transaction LinkedTransaction object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction, $idempotency_key = null)
    {
        $request = $this->createLinkedTransactionRequest($xero_tenant_id, $linked_transaction, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createLinkedTransactionAsync
     * Creates linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransaction $linked_transaction LinkedTransaction object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createLinkedTransactionAsync($xero_tenant_id, $linked_transaction, $idempotency_key = null)
    {
        return $this->createLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createLinkedTransactionAsyncWithHttpInfo
     * Creates linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransaction $linked_transaction LinkedTransaction object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
        $request = $this->createLinkedTransactionRequest($xero_tenant_id, $linked_transaction, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createLinkedTransaction'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransaction $linked_transaction LinkedTransaction object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createLinkedTransactionRequest($xero_tenant_id, $linked_transaction, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createLinkedTransaction'
            );
        }
        // verify the required parameter 'linked_transaction' is set
        if ($linked_transaction === null || (is_array($linked_transaction) && count($linked_transaction) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $linked_transaction when calling createLinkedTransaction'
            );
        }
        $resourcePath = '/LinkedTransactions';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($linked_transaction)) {
            $_tempBody = $linked_transaction;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createManualJournalAttachmentByFileName
     * Creates a specific attachment for a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createManualJournalAttachmentByFileName($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createManualJournalAttachmentByFileNameWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createManualJournalAttachmentByFileNameWithHttpInfo
     * Creates a specific attachment for a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createManualJournalAttachmentByFileNameWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createManualJournalAttachmentByFileNameAsync
     * Creates a specific attachment for a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createManualJournalAttachmentByFileNameAsync($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createManualJournalAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createManualJournalAttachmentByFileNameAsyncWithHttpInfo
     * Creates a specific attachment for a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createManualJournalAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createManualJournalAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling createManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createManualJournalAttachmentByFileName'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createManualJournalHistoryRecord
     * Creates a history record for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createManualJournalHistoryRecord($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createManualJournalHistoryRecordWithHttpInfo($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createManualJournalHistoryRecordWithHttpInfo
     * Creates a history record for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createManualJournalHistoryRecordWithHttpInfo($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createManualJournalHistoryRecordRequest($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createManualJournalHistoryRecordAsync
     * Creates a history record for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createManualJournalHistoryRecordAsync($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key = null)
    {
        return $this->createManualJournalHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createManualJournalHistoryRecordAsyncWithHttpInfo
     * Creates a history record for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createManualJournalHistoryRecordAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createManualJournalHistoryRecordRequest($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createManualJournalHistoryRecord'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createManualJournalHistoryRecordRequest($xero_tenant_id, $manual_journal_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createManualJournalHistoryRecord'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling createManualJournalHistoryRecord'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createManualJournalHistoryRecord'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createManualJournals
     * Creates one or more manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ManualJournals|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createManualJournals($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createManualJournalsWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createManualJournalsWithHttpInfo
     * Creates one or more manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ManualJournals|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createManualJournalsWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createManualJournalsRequest($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ManualJournals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createManualJournalsAsync
     * Creates one or more manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createManualJournalsAsync($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createManualJournalsAsyncWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createManualJournalsAsyncWithHttpInfo
     * Creates one or more manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createManualJournalsAsyncWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
        $request = $this->createManualJournalsRequest($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createManualJournals'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createManualJournalsRequest($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createManualJournals'
            );
        }
        // verify the required parameter 'manual_journals' is set
        if ($manual_journals === null || (is_array($manual_journals) && count($manual_journals) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journals when calling createManualJournals'
            );
        }
        $resourcePath = '/ManualJournals';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($manual_journals)) {
            $_tempBody = $manual_journals;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createOverpaymentAllocations
     * Creates a single allocation for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations array with Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Allocations|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createOverpaymentAllocations($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createOverpaymentAllocationsWithHttpInfo($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createOverpaymentAllocationsWithHttpInfo
     * Creates a single allocation for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations array with Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Allocations|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createOverpaymentAllocationsWithHttpInfo($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createOverpaymentAllocationsRequest($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Allocations' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Allocations', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocations';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Allocations',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createOverpaymentAllocationsAsync
     * Creates a single allocation for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations array with Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOverpaymentAllocationsAsync($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createOverpaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createOverpaymentAllocationsAsyncWithHttpInfo
     * Creates a single allocation for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations array with Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createOverpaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocations';
        $request = $this->createOverpaymentAllocationsRequest($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createOverpaymentAllocations'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations array with Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createOverpaymentAllocationsRequest($xero_tenant_id, $overpayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createOverpaymentAllocations'
            );
        }
        // verify the required parameter 'overpayment_id' is set
        if ($overpayment_id === null || (is_array($overpayment_id) && count($overpayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $overpayment_id when calling createOverpaymentAllocations'
            );
        }
        // verify the required parameter 'allocations' is set
        if ($allocations === null || (is_array($allocations) && count($allocations) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $allocations when calling createOverpaymentAllocations'
            );
        }
        $resourcePath = '/Overpayments/{OverpaymentID}/Allocations';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($overpayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'OverpaymentID' . '}',
                AccountingObjectSerializer::toPathValue($overpayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($allocations)) {
            $_tempBody = $allocations;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createOverpaymentHistory
     * Creates a history record for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createOverpaymentHistory($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createOverpaymentHistoryWithHttpInfo($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createOverpaymentHistoryWithHttpInfo
     * Creates a history record for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createOverpaymentHistoryWithHttpInfo($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createOverpaymentHistoryRequest($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createOverpaymentHistoryAsync
     * Creates a history record for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createOverpaymentHistoryAsync($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key = null)
    {
        return $this->createOverpaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createOverpaymentHistoryAsyncWithHttpInfo
     * Creates a history record for a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createOverpaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createOverpaymentHistoryRequest($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createOverpaymentHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createOverpaymentHistoryRequest($xero_tenant_id, $overpayment_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createOverpaymentHistory'
            );
        }
        // verify the required parameter 'overpayment_id' is set
        if ($overpayment_id === null || (is_array($overpayment_id) && count($overpayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $overpayment_id when calling createOverpaymentHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createOverpaymentHistory'
            );
        }
        $resourcePath = '/Overpayments/{OverpaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($overpayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'OverpaymentID' . '}',
                AccountingObjectSerializer::toPathValue($overpayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPayment
     * Creates a single payment for invoice or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payment $payment Request body with a single Payment object (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Payments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPayment($xero_tenant_id, $payment, $idempotency_key = null)
    {
        list($response) = $this->createPaymentWithHttpInfo($xero_tenant_id, $payment, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPaymentWithHttpInfo
     * Creates a single payment for invoice or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payment $payment Request body with a single Payment object (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Payments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPaymentWithHttpInfo($xero_tenant_id, $payment, $idempotency_key = null)
    {
        $request = $this->createPaymentRequest($xero_tenant_id, $payment, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Payments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Payments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Payments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPaymentAsync
     * Creates a single payment for invoice or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payment $payment Request body with a single Payment object (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPaymentAsync($xero_tenant_id, $payment, $idempotency_key = null)
    {
        return $this->createPaymentAsyncWithHttpInfo($xero_tenant_id, $payment, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPaymentAsyncWithHttpInfo
     * Creates a single payment for invoice or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payment $payment Request body with a single Payment object (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPaymentAsyncWithHttpInfo($xero_tenant_id, $payment, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
        $request = $this->createPaymentRequest($xero_tenant_id, $payment, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payment $payment Request body with a single Payment object (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPaymentRequest($xero_tenant_id, $payment, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPayment'
            );
        }
        // verify the required parameter 'payment' is set
        if ($payment === null || (is_array($payment) && count($payment) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment when calling createPayment'
            );
        }
        $resourcePath = '/Payments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($payment)) {
            $_tempBody = $payment;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPaymentHistory
     * Creates a history record for a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPaymentHistory($xero_tenant_id, $payment_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createPaymentHistoryWithHttpInfo($xero_tenant_id, $payment_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPaymentHistoryWithHttpInfo
     * Creates a history record for a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPaymentHistoryWithHttpInfo($xero_tenant_id, $payment_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createPaymentHistoryRequest($xero_tenant_id, $payment_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPaymentHistoryAsync
     * Creates a history record for a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPaymentHistoryAsync($xero_tenant_id, $payment_id, $history_records, $idempotency_key = null)
    {
        return $this->createPaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $payment_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPaymentHistoryAsyncWithHttpInfo
     * Creates a history record for a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $payment_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createPaymentHistoryRequest($xero_tenant_id, $payment_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPaymentHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPaymentHistoryRequest($xero_tenant_id, $payment_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPaymentHistory'
            );
        }
        // verify the required parameter 'payment_id' is set
        if ($payment_id === null || (is_array($payment_id) && count($payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment_id when calling createPaymentHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createPaymentHistory'
            );
        }
        $resourcePath = '/Payments/{PaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PaymentID' . '}',
                AccountingObjectSerializer::toPathValue($payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPaymentService
     * Creates a payment service
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PaymentServices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPaymentService($xero_tenant_id, $payment_services, $idempotency_key = null)
    {
        list($response) = $this->createPaymentServiceWithHttpInfo($xero_tenant_id, $payment_services, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPaymentServiceWithHttpInfo
     * Creates a payment service
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PaymentServices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPaymentServiceWithHttpInfo($xero_tenant_id, $payment_services, $idempotency_key = null)
    {
        $request = $this->createPaymentServiceRequest($xero_tenant_id, $payment_services, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PaymentServices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPaymentServiceAsync
     * Creates a payment service
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPaymentServiceAsync($xero_tenant_id, $payment_services, $idempotency_key = null)
    {
        return $this->createPaymentServiceAsyncWithHttpInfo($xero_tenant_id, $payment_services, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPaymentServiceAsyncWithHttpInfo
     * Creates a payment service
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPaymentServiceAsyncWithHttpInfo($xero_tenant_id, $payment_services, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
        $request = $this->createPaymentServiceRequest($xero_tenant_id, $payment_services, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPaymentService'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentServices $payment_services PaymentServices array with PaymentService object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPaymentServiceRequest($xero_tenant_id, $payment_services, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPaymentService'
            );
        }
        // verify the required parameter 'payment_services' is set
        if ($payment_services === null || (is_array($payment_services) && count($payment_services) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment_services when calling createPaymentService'
            );
        }
        $resourcePath = '/PaymentServices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($payment_services)) {
            $_tempBody = $payment_services;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPayments
     * Creates multiple payments for invoices or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payments $payments Payments array with Payment object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Payments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPayments($xero_tenant_id, $payments, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createPaymentsWithHttpInfo($xero_tenant_id, $payments, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPaymentsWithHttpInfo
     * Creates multiple payments for invoices or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payments $payments Payments array with Payment object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Payments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPaymentsWithHttpInfo($xero_tenant_id, $payments, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createPaymentsRequest($xero_tenant_id, $payments, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Payments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Payments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Payments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPaymentsAsync
     * Creates multiple payments for invoices or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payments $payments Payments array with Payment object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPaymentsAsync($xero_tenant_id, $payments, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createPaymentsAsyncWithHttpInfo($xero_tenant_id, $payments, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPaymentsAsyncWithHttpInfo
     * Creates multiple payments for invoices or credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payments $payments Payments array with Payment object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPaymentsAsyncWithHttpInfo($xero_tenant_id, $payments, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
        $request = $this->createPaymentsRequest($xero_tenant_id, $payments, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPayments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Payments $payments Payments array with Payment object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPaymentsRequest($xero_tenant_id, $payments, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPayments'
            );
        }
        // verify the required parameter 'payments' is set
        if ($payments === null || (is_array($payments) && count($payments) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payments when calling createPayments'
            );
        }
        $resourcePath = '/Payments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($payments)) {
            $_tempBody = $payments;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPrepaymentAllocations
     * Allows you to create an Allocation for prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with an array of Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Allocations|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPrepaymentAllocations($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createPrepaymentAllocationsWithHttpInfo($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPrepaymentAllocationsWithHttpInfo
     * Allows you to create an Allocation for prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with an array of Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Allocations|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPrepaymentAllocationsWithHttpInfo($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createPrepaymentAllocationsRequest($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Allocations' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Allocations', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocations';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Allocations',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPrepaymentAllocationsAsync
     * Allows you to create an Allocation for prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with an array of Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPrepaymentAllocationsAsync($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createPrepaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPrepaymentAllocationsAsyncWithHttpInfo
     * Allows you to create an Allocation for prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with an array of Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPrepaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocations';
        $request = $this->createPrepaymentAllocationsRequest($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPrepaymentAllocations'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Allocations $allocations Allocations with an array of Allocation object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPrepaymentAllocationsRequest($xero_tenant_id, $prepayment_id, $allocations, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPrepaymentAllocations'
            );
        }
        // verify the required parameter 'prepayment_id' is set
        if ($prepayment_id === null || (is_array($prepayment_id) && count($prepayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $prepayment_id when calling createPrepaymentAllocations'
            );
        }
        // verify the required parameter 'allocations' is set
        if ($allocations === null || (is_array($allocations) && count($allocations) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $allocations when calling createPrepaymentAllocations'
            );
        }
        $resourcePath = '/Prepayments/{PrepaymentID}/Allocations';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($prepayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PrepaymentID' . '}',
                AccountingObjectSerializer::toPathValue($prepayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($allocations)) {
            $_tempBody = $allocations;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPrepaymentHistory
     * Creates a history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPrepaymentHistory($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createPrepaymentHistoryWithHttpInfo($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPrepaymentHistoryWithHttpInfo
     * Creates a history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPrepaymentHistoryWithHttpInfo($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createPrepaymentHistoryRequest($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPrepaymentHistoryAsync
     * Creates a history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPrepaymentHistoryAsync($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key = null)
    {
        return $this->createPrepaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPrepaymentHistoryAsyncWithHttpInfo
     * Creates a history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPrepaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createPrepaymentHistoryRequest($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPrepaymentHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPrepaymentHistoryRequest($xero_tenant_id, $prepayment_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPrepaymentHistory'
            );
        }
        // verify the required parameter 'prepayment_id' is set
        if ($prepayment_id === null || (is_array($prepayment_id) && count($prepayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $prepayment_id when calling createPrepaymentHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createPrepaymentHistory'
            );
        }
        $resourcePath = '/Prepayments/{PrepaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($prepayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PrepaymentID' . '}',
                AccountingObjectSerializer::toPathValue($prepayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPurchaseOrderAttachmentByFileName
     * Creates attachment for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPurchaseOrderAttachmentByFileName($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createPurchaseOrderAttachmentByFileNameWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPurchaseOrderAttachmentByFileNameWithHttpInfo
     * Creates attachment for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPurchaseOrderAttachmentByFileNameWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createPurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPurchaseOrderAttachmentByFileNameAsync
     * Creates attachment for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPurchaseOrderAttachmentByFileNameAsync($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createPurchaseOrderAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPurchaseOrderAttachmentByFileNameAsyncWithHttpInfo
     * Creates attachment for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPurchaseOrderAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createPurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPurchaseOrderAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling createPurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createPurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createPurchaseOrderAttachmentByFileName'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPurchaseOrderHistory
     * Creates a history record for a specific purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPurchaseOrderHistory($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createPurchaseOrderHistoryWithHttpInfo($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPurchaseOrderHistoryWithHttpInfo
     * Creates a history record for a specific purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPurchaseOrderHistoryWithHttpInfo($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createPurchaseOrderHistoryRequest($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPurchaseOrderHistoryAsync
     * Creates a history record for a specific purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPurchaseOrderHistoryAsync($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key = null)
    {
        return $this->createPurchaseOrderHistoryAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPurchaseOrderHistoryAsyncWithHttpInfo
     * Creates a history record for a specific purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPurchaseOrderHistoryAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createPurchaseOrderHistoryRequest($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPurchaseOrderHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPurchaseOrderHistoryRequest($xero_tenant_id, $purchase_order_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPurchaseOrderHistory'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling createPurchaseOrderHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createPurchaseOrderHistory'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createPurchaseOrders
     * Creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders PurchaseOrders with an array of PurchaseOrder object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createPurchaseOrders($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createPurchaseOrdersWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createPurchaseOrdersWithHttpInfo
     * Creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders PurchaseOrders with an array of PurchaseOrder object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createPurchaseOrdersWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createPurchaseOrdersRequest($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createPurchaseOrdersAsync
     * Creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders PurchaseOrders with an array of PurchaseOrder object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createPurchaseOrdersAsync($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createPurchaseOrdersAsyncWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createPurchaseOrdersAsyncWithHttpInfo
     * Creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders PurchaseOrders with an array of PurchaseOrder object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createPurchaseOrdersAsyncWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
        $request = $this->createPurchaseOrdersRequest($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createPurchaseOrders'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders PurchaseOrders with an array of PurchaseOrder object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createPurchaseOrdersRequest($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createPurchaseOrders'
            );
        }
        // verify the required parameter 'purchase_orders' is set
        if ($purchase_orders === null || (is_array($purchase_orders) && count($purchase_orders) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_orders when calling createPurchaseOrders'
            );
        }
        $resourcePath = '/PurchaseOrders';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($purchase_orders)) {
            $_tempBody = $purchase_orders;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createQuoteAttachmentByFileName
     * Creates attachment for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createQuoteAttachmentByFileName($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createQuoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createQuoteAttachmentByFileNameWithHttpInfo
     * Creates attachment for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createQuoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createQuoteAttachmentByFileNameAsync
     * Creates attachment for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createQuoteAttachmentByFileNameAsync($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createQuoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createQuoteAttachmentByFileNameAsyncWithHttpInfo
     * Creates attachment for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createQuoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createQuoteAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling createQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createQuoteAttachmentByFileName'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createQuoteHistory
     * Creates a history record for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createQuoteHistory($xero_tenant_id, $quote_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createQuoteHistoryWithHttpInfo($xero_tenant_id, $quote_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createQuoteHistoryWithHttpInfo
     * Creates a history record for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createQuoteHistoryWithHttpInfo($xero_tenant_id, $quote_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createQuoteHistoryRequest($xero_tenant_id, $quote_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createQuoteHistoryAsync
     * Creates a history record for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createQuoteHistoryAsync($xero_tenant_id, $quote_id, $history_records, $idempotency_key = null)
    {
        return $this->createQuoteHistoryAsyncWithHttpInfo($xero_tenant_id, $quote_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createQuoteHistoryAsyncWithHttpInfo
     * Creates a history record for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createQuoteHistoryAsyncWithHttpInfo($xero_tenant_id, $quote_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createQuoteHistoryRequest($xero_tenant_id, $quote_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createQuoteHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createQuoteHistoryRequest($xero_tenant_id, $quote_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createQuoteHistory'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling createQuoteHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createQuoteHistory'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createQuotes
     * Create one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes Quotes with an array of Quote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Quotes|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createQuotes($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createQuotesWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createQuotesWithHttpInfo
     * Create one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes Quotes with an array of Quote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Quotes|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createQuotesWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createQuotesRequest($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Quotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Quotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Quotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createQuotesAsync
     * Create one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes Quotes with an array of Quote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createQuotesAsync($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createQuotesAsyncWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createQuotesAsyncWithHttpInfo
     * Create one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes Quotes with an array of Quote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createQuotesAsyncWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
        $request = $this->createQuotesRequest($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createQuotes'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes Quotes with an array of Quote object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createQuotesRequest($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createQuotes'
            );
        }
        // verify the required parameter 'quotes' is set
        if ($quotes === null || (is_array($quotes) && count($quotes) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quotes when calling createQuotes'
            );
        }
        $resourcePath = '/Quotes';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($quotes)) {
            $_tempBody = $quotes;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createReceipt
     * Creates draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts Receipts with an array of Receipt object in body of request (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Receipts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createReceipt($xero_tenant_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->createReceiptWithHttpInfo($xero_tenant_id, $receipts, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation createReceiptWithHttpInfo
     * Creates draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts Receipts with an array of Receipt object in body of request (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Receipts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createReceiptWithHttpInfo($xero_tenant_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->createReceiptRequest($xero_tenant_id, $receipts, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Receipts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Receipts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Receipts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createReceiptAsync
     * Creates draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts Receipts with an array of Receipt object in body of request (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createReceiptAsync($xero_tenant_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        return $this->createReceiptAsyncWithHttpInfo($xero_tenant_id, $receipts, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createReceiptAsyncWithHttpInfo
     * Creates draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts Receipts with an array of Receipt object in body of request (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createReceiptAsyncWithHttpInfo($xero_tenant_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
        $request = $this->createReceiptRequest($xero_tenant_id, $receipts, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createReceipt'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts Receipts with an array of Receipt object in body of request (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createReceiptRequest($xero_tenant_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createReceipt'
            );
        }
        // verify the required parameter 'receipts' is set
        if ($receipts === null || (is_array($receipts) && count($receipts) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipts when calling createReceipt'
            );
        }
        $resourcePath = '/Receipts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($receipts)) {
            $_tempBody = $receipts;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createReceiptAttachmentByFileName
     * Creates an attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createReceiptAttachmentByFileName($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createReceiptAttachmentByFileNameWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createReceiptAttachmentByFileNameWithHttpInfo
     * Creates an attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createReceiptAttachmentByFileNameWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createReceiptAttachmentByFileNameAsync
     * Creates an attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createReceiptAttachmentByFileNameAsync($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createReceiptAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createReceiptAttachmentByFileNameAsyncWithHttpInfo
     * Creates an attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createReceiptAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createReceiptAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling createReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createReceiptAttachmentByFileName'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createReceiptHistory
     * Creates a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createReceiptHistory($xero_tenant_id, $receipt_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createReceiptHistoryWithHttpInfo($xero_tenant_id, $receipt_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createReceiptHistoryWithHttpInfo
     * Creates a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createReceiptHistoryWithHttpInfo($xero_tenant_id, $receipt_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createReceiptHistoryRequest($xero_tenant_id, $receipt_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createReceiptHistoryAsync
     * Creates a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createReceiptHistoryAsync($xero_tenant_id, $receipt_id, $history_records, $idempotency_key = null)
    {
        return $this->createReceiptHistoryAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createReceiptHistoryAsyncWithHttpInfo
     * Creates a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createReceiptHistoryAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createReceiptHistoryRequest($xero_tenant_id, $receipt_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createReceiptHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createReceiptHistoryRequest($xero_tenant_id, $receipt_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createReceiptHistory'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling createReceiptHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createReceiptHistory'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createRepeatingInvoiceAttachmentByFileName
     * Creates an attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createRepeatingInvoiceAttachmentByFileName($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->createRepeatingInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation createRepeatingInvoiceAttachmentByFileNameWithHttpInfo
     * Creates an attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createRepeatingInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->createRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createRepeatingInvoiceAttachmentByFileNameAsync
     * Creates an attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createRepeatingInvoiceAttachmentByFileNameAsync($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->createRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo
     * Creates an attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->createRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createRepeatingInvoiceAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling createRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling createRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling createRepeatingInvoiceAttachmentByFileName'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createRepeatingInvoiceHistory
     * Creates a  history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createRepeatingInvoiceHistory($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key = null)
    {
        list($response) = $this->createRepeatingInvoiceHistoryWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key);
        return $response;
    }
    /**
     * Operation createRepeatingInvoiceHistoryWithHttpInfo
     * Creates a  history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createRepeatingInvoiceHistoryWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key = null)
    {
        $request = $this->createRepeatingInvoiceHistoryRequest($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createRepeatingInvoiceHistoryAsync
     * Creates a  history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createRepeatingInvoiceHistoryAsync($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key = null)
    {
        return $this->createRepeatingInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createRepeatingInvoiceHistoryAsyncWithHttpInfo
     * Creates a  history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createRepeatingInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->createRepeatingInvoiceHistoryRequest($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createRepeatingInvoiceHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords $history_records HistoryRecords containing an array of HistoryRecord objects in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createRepeatingInvoiceHistoryRequest($xero_tenant_id, $repeating_invoice_id, $history_records, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createRepeatingInvoiceHistory'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling createRepeatingInvoiceHistory'
            );
        }
        // verify the required parameter 'history_records' is set
        if ($history_records === null || (is_array($history_records) && count($history_records) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $history_records when calling createRepeatingInvoiceHistory'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($history_records)) {
            $_tempBody = $history_records;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createRepeatingInvoices
     * Creates one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createRepeatingInvoices($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->createRepeatingInvoicesWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation createRepeatingInvoicesWithHttpInfo
     * Creates one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createRepeatingInvoicesWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->createRepeatingInvoicesRequest($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createRepeatingInvoicesAsync
     * Creates one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createRepeatingInvoicesAsync($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->createRepeatingInvoicesAsyncWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createRepeatingInvoicesAsyncWithHttpInfo
     * Creates one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createRepeatingInvoicesAsyncWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
        $request = $this->createRepeatingInvoicesRequest($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createRepeatingInvoices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createRepeatingInvoicesRequest($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createRepeatingInvoices'
            );
        }
        // verify the required parameter 'repeating_invoices' is set
        if ($repeating_invoices === null || (is_array($repeating_invoices) && count($repeating_invoices) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoices when calling createRepeatingInvoices'
            );
        }
        $resourcePath = '/RepeatingInvoices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($repeating_invoices)) {
            $_tempBody = $repeating_invoices;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createTaxRates
     * Creates one or more tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates TaxRates array with TaxRate object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TaxRates|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createTaxRates($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        list($response) = $this->createTaxRatesWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key);
        return $response;
    }
    /**
     * Operation createTaxRatesWithHttpInfo
     * Creates one or more tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates TaxRates array with TaxRate object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TaxRates|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createTaxRatesWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        $request = $this->createTaxRatesRequest($xero_tenant_id, $tax_rates, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TaxRates' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TaxRates', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TaxRates',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createTaxRatesAsync
     * Creates one or more tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates TaxRates array with TaxRate object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createTaxRatesAsync($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        return $this->createTaxRatesAsyncWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createTaxRatesAsyncWithHttpInfo
     * Creates one or more tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates TaxRates array with TaxRate object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createTaxRatesAsyncWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
        $request = $this->createTaxRatesRequest($xero_tenant_id, $tax_rates, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createTaxRates'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates TaxRates array with TaxRate object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createTaxRatesRequest($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createTaxRates'
            );
        }
        // verify the required parameter 'tax_rates' is set
        if ($tax_rates === null || (is_array($tax_rates) && count($tax_rates) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tax_rates when calling createTaxRates'
            );
        }
        $resourcePath = '/TaxRates';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($tax_rates)) {
            $_tempBody = $tax_rates;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createTrackingCategory
     * Create tracking categories
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category TrackingCategory object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createTrackingCategory($xero_tenant_id, $tracking_category, $idempotency_key = null)
    {
        list($response) = $this->createTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category, $idempotency_key);
        return $response;
    }
    /**
     * Operation createTrackingCategoryWithHttpInfo
     * Create tracking categories
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category TrackingCategory object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category, $idempotency_key = null)
    {
        $request = $this->createTrackingCategoryRequest($xero_tenant_id, $tracking_category, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createTrackingCategoryAsync
     * Create tracking categories
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category TrackingCategory object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createTrackingCategoryAsync($xero_tenant_id, $tracking_category, $idempotency_key = null)
    {
        return $this->createTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createTrackingCategoryAsyncWithHttpInfo
     * Create tracking categories
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category TrackingCategory object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
        $request = $this->createTrackingCategoryRequest($xero_tenant_id, $tracking_category, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createTrackingCategory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category TrackingCategory object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createTrackingCategoryRequest($xero_tenant_id, $tracking_category, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createTrackingCategory'
            );
        }
        // verify the required parameter 'tracking_category' is set
        if ($tracking_category === null || (is_array($tracking_category) && count($tracking_category) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category when calling createTrackingCategory'
            );
        }
        $resourcePath = '/TrackingCategories';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($tracking_category)) {
            $_tempBody = $tracking_category;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createTrackingOptions
     * Creates options for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option TrackingOption object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingOptions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function createTrackingOptions($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key = null)
    {
        list($response) = $this->createTrackingOptionsWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key);
        return $response;
    }
    /**
     * Operation createTrackingOptionsWithHttpInfo
     * Creates options for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option TrackingOption object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingOptions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function createTrackingOptionsWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key = null)
    {
        $request = $this->createTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation createTrackingOptionsAsync
     * Creates options for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option TrackingOption object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createTrackingOptionsAsync($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key = null)
    {
        return $this->createTrackingOptionsAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation createTrackingOptionsAsyncWithHttpInfo
     * Creates options for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option TrackingOption object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function createTrackingOptionsAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions';
        $request = $this->createTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createTrackingOptions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option TrackingOption object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function createTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling createTrackingOptions'
            );
        }
        // verify the required parameter 'tracking_category_id' is set
        if ($tracking_category_id === null || (is_array($tracking_category_id) && count($tracking_category_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category_id when calling createTrackingOptions'
            );
        }
        // verify the required parameter 'tracking_option' is set
        if ($tracking_option === null || (is_array($tracking_option) && count($tracking_option) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_option when calling createTrackingOptions'
            );
        }
        $resourcePath = '/TrackingCategories/{TrackingCategoryID}/Options';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($tracking_category_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingCategoryID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_category_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($tracking_option)) {
            $_tempBody = $tracking_option;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteAccount
     * Deletes a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Accounts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function deleteAccount($xero_tenant_id, $account_id)
    {
        list($response) = $this->deleteAccountWithHttpInfo($xero_tenant_id, $account_id);
        return $response;
    }
    /**
     * Operation deleteAccountWithHttpInfo
     * Deletes a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Accounts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteAccountWithHttpInfo($xero_tenant_id, $account_id)
    {
        $request = $this->deleteAccountRequest($xero_tenant_id, $account_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Accounts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Accounts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Accounts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteAccountAsync
     * Deletes a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteAccountAsync($xero_tenant_id, $account_id)
    {
        return $this->deleteAccountAsyncWithHttpInfo($xero_tenant_id, $account_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteAccountAsyncWithHttpInfo
     * Deletes a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteAccountAsyncWithHttpInfo($xero_tenant_id, $account_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
        $request = $this->deleteAccountRequest($xero_tenant_id, $account_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteAccount'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteAccountRequest($xero_tenant_id, $account_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteAccount'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling deleteAccount'
            );
        }
        $resourcePath = '/Accounts/{AccountID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteBatchPayment
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDelete $batch_payment_delete batch_payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BatchPayments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function deleteBatchPayment($xero_tenant_id, $batch_payment_delete, $idempotency_key = null)
    {
        list($response) = $this->deleteBatchPaymentWithHttpInfo($xero_tenant_id, $batch_payment_delete, $idempotency_key);
        return $response;
    }
    /**
     * Operation deleteBatchPaymentWithHttpInfo
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDelete $batch_payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BatchPayments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteBatchPaymentWithHttpInfo($xero_tenant_id, $batch_payment_delete, $idempotency_key = null)
    {
        $request = $this->deleteBatchPaymentRequest($xero_tenant_id, $batch_payment_delete, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BatchPayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteBatchPaymentAsync
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDelete $batch_payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteBatchPaymentAsync($xero_tenant_id, $batch_payment_delete, $idempotency_key = null)
    {
        return $this->deleteBatchPaymentAsyncWithHttpInfo($xero_tenant_id, $batch_payment_delete, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteBatchPaymentAsyncWithHttpInfo
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDelete $batch_payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteBatchPaymentAsyncWithHttpInfo($xero_tenant_id, $batch_payment_delete, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
        $request = $this->deleteBatchPaymentRequest($xero_tenant_id, $batch_payment_delete, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteBatchPayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDelete $batch_payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteBatchPaymentRequest($xero_tenant_id, $batch_payment_delete, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteBatchPayment'
            );
        }
        // verify the required parameter 'batch_payment_delete' is set
        if ($batch_payment_delete === null || (is_array($batch_payment_delete) && count($batch_payment_delete) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $batch_payment_delete when calling deleteBatchPayment'
            );
        }
        $resourcePath = '/BatchPayments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($batch_payment_delete)) {
            $_tempBody = $batch_payment_delete;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteBatchPaymentByUrlParam
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDeleteByUrlParam $batch_payment_delete_by_url_param batch_payment_delete_by_url_param (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BatchPayments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function deleteBatchPaymentByUrlParam($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key = null)
    {
        list($response) = $this->deleteBatchPaymentByUrlParamWithHttpInfo($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key);
        return $response;
    }
    /**
     * Operation deleteBatchPaymentByUrlParamWithHttpInfo
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDeleteByUrlParam $batch_payment_delete_by_url_param (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BatchPayments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteBatchPaymentByUrlParamWithHttpInfo($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key = null)
    {
        $request = $this->deleteBatchPaymentByUrlParamRequest($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BatchPayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteBatchPaymentByUrlParamAsync
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDeleteByUrlParam $batch_payment_delete_by_url_param (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteBatchPaymentByUrlParamAsync($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key = null)
    {
        return $this->deleteBatchPaymentByUrlParamAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteBatchPaymentByUrlParamAsyncWithHttpInfo
     * Updates a specific batch payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDeleteByUrlParam $batch_payment_delete_by_url_param (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteBatchPaymentByUrlParamAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
        $request = $this->deleteBatchPaymentByUrlParamRequest($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteBatchPaymentByUrlParam'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BatchPaymentDeleteByUrlParam $batch_payment_delete_by_url_param (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteBatchPaymentByUrlParamRequest($xero_tenant_id, $batch_payment_id, $batch_payment_delete_by_url_param, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteBatchPaymentByUrlParam'
            );
        }
        // verify the required parameter 'batch_payment_id' is set
        if ($batch_payment_id === null || (is_array($batch_payment_id) && count($batch_payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $batch_payment_id when calling deleteBatchPaymentByUrlParam'
            );
        }
        // verify the required parameter 'batch_payment_delete_by_url_param' is set
        if ($batch_payment_delete_by_url_param === null || (is_array($batch_payment_delete_by_url_param) && count($batch_payment_delete_by_url_param) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $batch_payment_delete_by_url_param when calling deleteBatchPaymentByUrlParam'
            );
        }
        $resourcePath = '/BatchPayments/{BatchPaymentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($batch_payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BatchPaymentID' . '}',
                AccountingObjectSerializer::toPathValue($batch_payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($batch_payment_delete_by_url_param)) {
            $_tempBody = $batch_payment_delete_by_url_param;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteContactGroupContact
     * Deletes a specific contact from a contact group using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteContactGroupContact($xero_tenant_id, $contact_group_id, $contact_id)
    {
        $this->deleteContactGroupContactWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_id);
    }
    /**
     * Operation deleteContactGroupContactWithHttpInfo
     * Deletes a specific contact from a contact group using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteContactGroupContactWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_id)
    {
        $request = $this->deleteContactGroupContactRequest($xero_tenant_id, $contact_group_id, $contact_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteContactGroupContactAsync
     * Deletes a specific contact from a contact group using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteContactGroupContactAsync($xero_tenant_id, $contact_group_id, $contact_id)
    {
        return $this->deleteContactGroupContactAsyncWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteContactGroupContactAsyncWithHttpInfo
     * Deletes a specific contact from a contact group using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteContactGroupContactAsyncWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_id)
    {
        $returnType = '';
        $request = $this->deleteContactGroupContactRequest($xero_tenant_id, $contact_group_id, $contact_id);
        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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteContactGroupContact'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteContactGroupContactRequest($xero_tenant_id, $contact_group_id, $contact_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteContactGroupContact'
            );
        }
        // verify the required parameter 'contact_group_id' is set
        if ($contact_group_id === null || (is_array($contact_group_id) && count($contact_group_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_group_id when calling deleteContactGroupContact'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling deleteContactGroupContact'
            );
        }
        $resourcePath = '/ContactGroups/{ContactGroupID}/Contacts/{ContactID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_group_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactGroupID' . '}',
                AccountingObjectSerializer::toPathValue($contact_group_id),
                $resourcePath
            );
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteContactGroupContacts
     * Deletes all contacts from a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteContactGroupContacts($xero_tenant_id, $contact_group_id)
    {
        $this->deleteContactGroupContactsWithHttpInfo($xero_tenant_id, $contact_group_id);
    }
    /**
     * Operation deleteContactGroupContactsWithHttpInfo
     * Deletes all contacts from a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteContactGroupContactsWithHttpInfo($xero_tenant_id, $contact_group_id)
    {
        $request = $this->deleteContactGroupContactsRequest($xero_tenant_id, $contact_group_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
            }
            throw $e;
        }
    }
    /**
     * Operation deleteContactGroupContactsAsync
     * Deletes all contacts from a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteContactGroupContactsAsync($xero_tenant_id, $contact_group_id)
    {
        return $this->deleteContactGroupContactsAsyncWithHttpInfo($xero_tenant_id, $contact_group_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteContactGroupContactsAsyncWithHttpInfo
     * Deletes all contacts from a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteContactGroupContactsAsyncWithHttpInfo($xero_tenant_id, $contact_group_id)
    {
        $returnType = '';
        $request = $this->deleteContactGroupContactsRequest($xero_tenant_id, $contact_group_id);
        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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteContactGroupContacts'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteContactGroupContactsRequest($xero_tenant_id, $contact_group_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteContactGroupContacts'
            );
        }
        // verify the required parameter 'contact_group_id' is set
        if ($contact_group_id === null || (is_array($contact_group_id) && count($contact_group_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_group_id when calling deleteContactGroupContacts'
            );
        }
        $resourcePath = '/ContactGroups/{ContactGroupID}/Contacts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_group_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactGroupID' . '}',
                AccountingObjectSerializer::toPathValue($contact_group_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                []
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                [],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteCreditNoteAllocations
     * Deletes an Allocation from a Credit Note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Allocation
     */
    public function deleteCreditNoteAllocations($xero_tenant_id, $credit_note_id, $allocation_id)
    {
        list($response) = $this->deleteCreditNoteAllocationsWithHttpInfo($xero_tenant_id, $credit_note_id, $allocation_id);
        return $response;
    }
    /**
     * Operation deleteCreditNoteAllocationsWithHttpInfo
     * Deletes an Allocation from a Credit Note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Allocation, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteCreditNoteAllocationsWithHttpInfo($xero_tenant_id, $credit_note_id, $allocation_id)
    {
        $request = $this->deleteCreditNoteAllocationsRequest($xero_tenant_id, $credit_note_id, $allocation_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Allocation' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Allocation', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocation';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Allocation',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteCreditNoteAllocationsAsync
     * Deletes an Allocation from a Credit Note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteCreditNoteAllocationsAsync($xero_tenant_id, $credit_note_id, $allocation_id)
    {
        return $this->deleteCreditNoteAllocationsAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $allocation_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteCreditNoteAllocationsAsyncWithHttpInfo
     * Deletes an Allocation from a Credit Note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteCreditNoteAllocationsAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $allocation_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocation';
        $request = $this->deleteCreditNoteAllocationsRequest($xero_tenant_id, $credit_note_id, $allocation_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteCreditNoteAllocations'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteCreditNoteAllocationsRequest($xero_tenant_id, $credit_note_id, $allocation_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteCreditNoteAllocations'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling deleteCreditNoteAllocations'
            );
        }
        // verify the required parameter 'allocation_id' is set
        if ($allocation_id === null || (is_array($allocation_id) && count($allocation_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $allocation_id when calling deleteCreditNoteAllocations'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/Allocations/{AllocationID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // path params
        if ($allocation_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AllocationID' . '}',
                AccountingObjectSerializer::toPathValue($allocation_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteItem
     * Deletes a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteItem($xero_tenant_id, $item_id)
    {
        $this->deleteItemWithHttpInfo($xero_tenant_id, $item_id);
    }
    /**
     * Operation deleteItemWithHttpInfo
     * Deletes a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteItemWithHttpInfo($xero_tenant_id, $item_id)
    {
        $request = $this->deleteItemRequest($xero_tenant_id, $item_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteItemAsync
     * Deletes a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteItemAsync($xero_tenant_id, $item_id)
    {
        return $this->deleteItemAsyncWithHttpInfo($xero_tenant_id, $item_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteItemAsyncWithHttpInfo
     * Deletes a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteItemAsyncWithHttpInfo($xero_tenant_id, $item_id)
    {
        $returnType = '';
        $request = $this->deleteItemRequest($xero_tenant_id, $item_id);
        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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteItem'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteItemRequest($xero_tenant_id, $item_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteItem'
            );
        }
        // verify the required parameter 'item_id' is set
        if ($item_id === null || (is_array($item_id) && count($item_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $item_id when calling deleteItem'
            );
        }
        $resourcePath = '/Items/{ItemID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($item_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ItemID' . '}',
                AccountingObjectSerializer::toPathValue($item_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteLinkedTransaction
     * Deletes a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deleteLinkedTransaction($xero_tenant_id, $linked_transaction_id)
    {
        $this->deleteLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction_id);
    }
    /**
     * Operation deleteLinkedTransactionWithHttpInfo
     * Deletes a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction_id)
    {
        $request = $this->deleteLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteLinkedTransactionAsync
     * Deletes a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteLinkedTransactionAsync($xero_tenant_id, $linked_transaction_id)
    {
        return $this->deleteLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteLinkedTransactionAsyncWithHttpInfo
     * Deletes a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction_id)
    {
        $returnType = '';
        $request = $this->deleteLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id);
        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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteLinkedTransaction'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteLinkedTransaction'
            );
        }
        // verify the required parameter 'linked_transaction_id' is set
        if ($linked_transaction_id === null || (is_array($linked_transaction_id) && count($linked_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $linked_transaction_id when calling deleteLinkedTransaction'
            );
        }
        $resourcePath = '/LinkedTransactions/{LinkedTransactionID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($linked_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'LinkedTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($linked_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteOverpaymentAllocations
     * Deletes an Allocation from an overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Allocation
     */
    public function deleteOverpaymentAllocations($xero_tenant_id, $overpayment_id, $allocation_id)
    {
        list($response) = $this->deleteOverpaymentAllocationsWithHttpInfo($xero_tenant_id, $overpayment_id, $allocation_id);
        return $response;
    }
    /**
     * Operation deleteOverpaymentAllocationsWithHttpInfo
     * Deletes an Allocation from an overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Allocation, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteOverpaymentAllocationsWithHttpInfo($xero_tenant_id, $overpayment_id, $allocation_id)
    {
        $request = $this->deleteOverpaymentAllocationsRequest($xero_tenant_id, $overpayment_id, $allocation_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Allocation' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Allocation', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocation';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Allocation',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteOverpaymentAllocationsAsync
     * Deletes an Allocation from an overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteOverpaymentAllocationsAsync($xero_tenant_id, $overpayment_id, $allocation_id)
    {
        return $this->deleteOverpaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $overpayment_id, $allocation_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteOverpaymentAllocationsAsyncWithHttpInfo
     * Deletes an Allocation from an overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteOverpaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $overpayment_id, $allocation_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocation';
        $request = $this->deleteOverpaymentAllocationsRequest($xero_tenant_id, $overpayment_id, $allocation_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteOverpaymentAllocations'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteOverpaymentAllocationsRequest($xero_tenant_id, $overpayment_id, $allocation_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteOverpaymentAllocations'
            );
        }
        // verify the required parameter 'overpayment_id' is set
        if ($overpayment_id === null || (is_array($overpayment_id) && count($overpayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $overpayment_id when calling deleteOverpaymentAllocations'
            );
        }
        // verify the required parameter 'allocation_id' is set
        if ($allocation_id === null || (is_array($allocation_id) && count($allocation_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $allocation_id when calling deleteOverpaymentAllocations'
            );
        }
        $resourcePath = '/Overpayments/{OverpaymentID}/Allocations/{AllocationID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($overpayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'OverpaymentID' . '}',
                AccountingObjectSerializer::toPathValue($overpayment_id),
                $resourcePath
            );
        }
        // path params
        if ($allocation_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AllocationID' . '}',
                AccountingObjectSerializer::toPathValue($allocation_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deletePayment
     * Updates a specific payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentDelete $payment_delete payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Payments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function deletePayment($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key = null)
    {
        list($response) = $this->deletePaymentWithHttpInfo($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key);
        return $response;
    }
    /**
     * Operation deletePaymentWithHttpInfo
     * Updates a specific payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentDelete $payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Payments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function deletePaymentWithHttpInfo($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key = null)
    {
        $request = $this->deletePaymentRequest($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Payments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Payments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Payments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deletePaymentAsync
     * Updates a specific payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentDelete $payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deletePaymentAsync($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key = null)
    {
        return $this->deletePaymentAsyncWithHttpInfo($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deletePaymentAsyncWithHttpInfo
     * Updates a specific payment for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentDelete $payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deletePaymentAsyncWithHttpInfo($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
        $request = $this->deletePaymentRequest($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deletePayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PaymentDelete $payment_delete (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deletePaymentRequest($xero_tenant_id, $payment_id, $payment_delete, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deletePayment'
            );
        }
        // verify the required parameter 'payment_id' is set
        if ($payment_id === null || (is_array($payment_id) && count($payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment_id when calling deletePayment'
            );
        }
        // verify the required parameter 'payment_delete' is set
        if ($payment_delete === null || (is_array($payment_delete) && count($payment_delete) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment_delete when calling deletePayment'
            );
        }
        $resourcePath = '/Payments/{PaymentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PaymentID' . '}',
                AccountingObjectSerializer::toPathValue($payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($payment_delete)) {
            $_tempBody = $payment_delete;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deletePrepaymentAllocations
     * Deletes an Allocation from a Prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Allocation
     */
    public function deletePrepaymentAllocations($xero_tenant_id, $prepayment_id, $allocation_id)
    {
        list($response) = $this->deletePrepaymentAllocationsWithHttpInfo($xero_tenant_id, $prepayment_id, $allocation_id);
        return $response;
    }
    /**
     * Operation deletePrepaymentAllocationsWithHttpInfo
     * Deletes an Allocation from a Prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Allocation, HTTP status code, HTTP response headers (array of strings)
     */
    public function deletePrepaymentAllocationsWithHttpInfo($xero_tenant_id, $prepayment_id, $allocation_id)
    {
        $request = $this->deletePrepaymentAllocationsRequest($xero_tenant_id, $prepayment_id, $allocation_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Allocation' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Allocation', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocation';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Allocation',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deletePrepaymentAllocationsAsync
     * Deletes an Allocation from a Prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deletePrepaymentAllocationsAsync($xero_tenant_id, $prepayment_id, $allocation_id)
    {
        return $this->deletePrepaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $prepayment_id, $allocation_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deletePrepaymentAllocationsAsyncWithHttpInfo
     * Deletes an Allocation from a Prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deletePrepaymentAllocationsAsyncWithHttpInfo($xero_tenant_id, $prepayment_id, $allocation_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Allocation';
        $request = $this->deletePrepaymentAllocationsRequest($xero_tenant_id, $prepayment_id, $allocation_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deletePrepaymentAllocations'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @param  string $allocation_id Unique identifier for Allocation object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deletePrepaymentAllocationsRequest($xero_tenant_id, $prepayment_id, $allocation_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deletePrepaymentAllocations'
            );
        }
        // verify the required parameter 'prepayment_id' is set
        if ($prepayment_id === null || (is_array($prepayment_id) && count($prepayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $prepayment_id when calling deletePrepaymentAllocations'
            );
        }
        // verify the required parameter 'allocation_id' is set
        if ($allocation_id === null || (is_array($allocation_id) && count($allocation_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $allocation_id when calling deletePrepaymentAllocations'
            );
        }
        $resourcePath = '/Prepayments/{PrepaymentID}/Allocations/{AllocationID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($prepayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PrepaymentID' . '}',
                AccountingObjectSerializer::toPathValue($prepayment_id),
                $resourcePath
            );
        }
        // path params
        if ($allocation_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AllocationID' . '}',
                AccountingObjectSerializer::toPathValue($allocation_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteTrackingCategory
     * Deletes a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function deleteTrackingCategory($xero_tenant_id, $tracking_category_id)
    {
        list($response) = $this->deleteTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category_id);
        return $response;
    }
    /**
     * Operation deleteTrackingCategoryWithHttpInfo
     * Deletes a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category_id)
    {
        $request = $this->deleteTrackingCategoryRequest($xero_tenant_id, $tracking_category_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteTrackingCategoryAsync
     * Deletes a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteTrackingCategoryAsync($xero_tenant_id, $tracking_category_id)
    {
        return $this->deleteTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteTrackingCategoryAsyncWithHttpInfo
     * Deletes a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
        $request = $this->deleteTrackingCategoryRequest($xero_tenant_id, $tracking_category_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteTrackingCategory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteTrackingCategoryRequest($xero_tenant_id, $tracking_category_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteTrackingCategory'
            );
        }
        // verify the required parameter 'tracking_category_id' is set
        if ($tracking_category_id === null || (is_array($tracking_category_id) && count($tracking_category_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category_id when calling deleteTrackingCategory'
            );
        }
        $resourcePath = '/TrackingCategories/{TrackingCategoryID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($tracking_category_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingCategoryID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_category_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation deleteTrackingOptions
     * Deletes a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingOptions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function deleteTrackingOptions($xero_tenant_id, $tracking_category_id, $tracking_option_id)
    {
        list($response) = $this->deleteTrackingOptionsWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id);
        return $response;
    }
    /**
     * Operation deleteTrackingOptionsWithHttpInfo
     * Deletes a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingOptions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function deleteTrackingOptionsWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id)
    {
        $request = $this->deleteTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation deleteTrackingOptionsAsync
     * Deletes a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function deleteTrackingOptionsAsync($xero_tenant_id, $tracking_category_id, $tracking_option_id)
    {
        return $this->deleteTrackingOptionsAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation deleteTrackingOptionsAsyncWithHttpInfo
     * Deletes a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function deleteTrackingOptionsAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions';
        $request = $this->deleteTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'deleteTrackingOptions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function deleteTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling deleteTrackingOptions'
            );
        }
        // verify the required parameter 'tracking_category_id' is set
        if ($tracking_category_id === null || (is_array($tracking_category_id) && count($tracking_category_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category_id when calling deleteTrackingOptions'
            );
        }
        // verify the required parameter 'tracking_option_id' is set
        if ($tracking_option_id === null || (is_array($tracking_option_id) && count($tracking_option_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_option_id when calling deleteTrackingOptions'
            );
        }
        $resourcePath = '/TrackingCategories/{TrackingCategoryID}/Options/{TrackingOptionID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($tracking_category_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingCategoryID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_category_id),
                $resourcePath
            );
        }
        // path params
        if ($tracking_option_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingOptionID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_option_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation emailInvoice
     * Sends a copy of a specific invoice to related contact via email
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RequestEmpty $request_empty request_empty (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return void
     */
    public function emailInvoice($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key = null)
    {
        $this->emailInvoiceWithHttpInfo($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key);
    }
    /**
     * Operation emailInvoiceWithHttpInfo
     * Sends a copy of a specific invoice to related contact via email
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RequestEmpty $request_empty (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function emailInvoiceWithHttpInfo($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key = null)
    {
        $request = $this->emailInvoiceRequest($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation emailInvoiceAsync
     * Sends a copy of a specific invoice to related contact via email
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RequestEmpty $request_empty (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function emailInvoiceAsync($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key = null)
    {
        return $this->emailInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation emailInvoiceAsyncWithHttpInfo
     * Sends a copy of a specific invoice to related contact via email
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RequestEmpty $request_empty (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function emailInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key = null)
    {
        $returnType = '';
        $request = $this->emailInvoiceRequest($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key);
        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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'emailInvoice'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RequestEmpty $request_empty (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function emailInvoiceRequest($xero_tenant_id, $invoice_id, $request_empty, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling emailInvoice'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling emailInvoice'
            );
        }
        // verify the required parameter 'request_empty' is set
        if ($request_empty === null || (is_array($request_empty) && count($request_empty) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $request_empty when calling emailInvoice'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/Email';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($request_empty)) {
            $_tempBody = $request_empty;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAccount
     * Retrieves a single chart of accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Accounts
     */
    public function getAccount($xero_tenant_id, $account_id)
    {
        list($response) = $this->getAccountWithHttpInfo($xero_tenant_id, $account_id);
        return $response;
    }
    /**
     * Operation getAccountWithHttpInfo
     * Retrieves a single chart of accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Accounts, HTTP status code, HTTP response headers (array of strings)
     */
    public function getAccountWithHttpInfo($xero_tenant_id, $account_id)
    {
        $request = $this->getAccountRequest($xero_tenant_id, $account_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Accounts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Accounts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Accounts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getAccountAsync
     * Retrieves a single chart of accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAccountAsync($xero_tenant_id, $account_id)
    {
        return $this->getAccountAsyncWithHttpInfo($xero_tenant_id, $account_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getAccountAsyncWithHttpInfo
     * Retrieves a single chart of accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getAccountAsyncWithHttpInfo($xero_tenant_id, $account_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
        $request = $this->getAccountRequest($xero_tenant_id, $account_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getAccount'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getAccountRequest($xero_tenant_id, $account_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getAccount'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling getAccount'
            );
        }
        $resourcePath = '/Accounts/{AccountID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAccountAttachmentByFileName
     * Retrieves an attachment for a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getAccountAttachmentByFileName($xero_tenant_id, $account_id, $file_name, $content_type)
    {
        list($response) = $this->getAccountAttachmentByFileNameWithHttpInfo($xero_tenant_id, $account_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getAccountAttachmentByFileNameWithHttpInfo
     * Retrieves an attachment for a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getAccountAttachmentByFileNameWithHttpInfo($xero_tenant_id, $account_id, $file_name, $content_type)
    {
        $request = $this->getAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getAccountAttachmentByFileNameAsync
     * Retrieves an attachment for a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAccountAttachmentByFileNameAsync($xero_tenant_id, $account_id, $file_name, $content_type)
    {
        return $this->getAccountAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $account_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getAccountAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves an attachment for a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getAccountAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $account_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getAccountAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling getAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getAccountAttachmentByFileName'
            );
        }
        $resourcePath = '/Accounts/{AccountID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAccountAttachmentById
     * Retrieves a specific attachment from a specific account using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getAccountAttachmentById($xero_tenant_id, $account_id, $attachment_id, $content_type)
    {
        list($response) = $this->getAccountAttachmentByIdWithHttpInfo($xero_tenant_id, $account_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getAccountAttachmentByIdWithHttpInfo
     * Retrieves a specific attachment from a specific account using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getAccountAttachmentByIdWithHttpInfo($xero_tenant_id, $account_id, $attachment_id, $content_type)
    {
        $request = $this->getAccountAttachmentByIdRequest($xero_tenant_id, $account_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getAccountAttachmentByIdAsync
     * Retrieves a specific attachment from a specific account using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAccountAttachmentByIdAsync($xero_tenant_id, $account_id, $attachment_id, $content_type)
    {
        return $this->getAccountAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $account_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getAccountAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific account using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getAccountAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $account_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getAccountAttachmentByIdRequest($xero_tenant_id, $account_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getAccountAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getAccountAttachmentByIdRequest($xero_tenant_id, $account_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getAccountAttachmentById'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling getAccountAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getAccountAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getAccountAttachmentById'
            );
        }
        $resourcePath = '/Accounts/{AccountID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAccountAttachments
     * Retrieves attachments for a specific accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getAccountAttachments($xero_tenant_id, $account_id)
    {
        list($response) = $this->getAccountAttachmentsWithHttpInfo($xero_tenant_id, $account_id);
        return $response;
    }
    /**
     * Operation getAccountAttachmentsWithHttpInfo
     * Retrieves attachments for a specific accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getAccountAttachmentsWithHttpInfo($xero_tenant_id, $account_id)
    {
        $request = $this->getAccountAttachmentsRequest($xero_tenant_id, $account_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getAccountAttachmentsAsync
     * Retrieves attachments for a specific accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAccountAttachmentsAsync($xero_tenant_id, $account_id)
    {
        return $this->getAccountAttachmentsAsyncWithHttpInfo($xero_tenant_id, $account_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getAccountAttachmentsAsyncWithHttpInfo
     * Retrieves attachments for a specific accounts by using a unique account Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getAccountAttachmentsAsyncWithHttpInfo($xero_tenant_id, $account_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getAccountAttachmentsRequest($xero_tenant_id, $account_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getAccountAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getAccountAttachmentsRequest($xero_tenant_id, $account_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getAccountAttachments'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling getAccountAttachments'
            );
        }
        $resourcePath = '/Accounts/{AccountID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAccounts
     * Retrieves the full chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Accounts
     */
    public function getAccounts($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        list($response) = $this->getAccountsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order);
        return $response;
    }
    /**
     * Operation getAccountsWithHttpInfo
     * Retrieves the full chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Accounts, HTTP status code, HTTP response headers (array of strings)
     */
    public function getAccountsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $request = $this->getAccountsRequest($xero_tenant_id, $if_modified_since, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Accounts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Accounts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Accounts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getAccountsAsync
     * Retrieves the full chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getAccountsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        return $this->getAccountsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getAccountsAsyncWithHttpInfo
     * Retrieves the full chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getAccountsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
        $request = $this->getAccountsRequest($xero_tenant_id, $if_modified_since, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getAccounts'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getAccountsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getAccounts'
            );
        }
        $resourcePath = '/Accounts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransaction
     * Retrieves a single spent or received money transaction by using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransactions
     */
    public function getBankTransaction($xero_tenant_id, $bank_transaction_id, $unitdp = null)
    {
        list($response) = $this->getBankTransactionWithHttpInfo($xero_tenant_id, $bank_transaction_id, $unitdp);
        return $response;
    }
    /**
     * Operation getBankTransactionWithHttpInfo
     * Retrieves a single spent or received money transaction by using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransactions, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransactionWithHttpInfo($xero_tenant_id, $bank_transaction_id, $unitdp = null)
    {
        $request = $this->getBankTransactionRequest($xero_tenant_id, $bank_transaction_id, $unitdp);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransactionAsync
     * Retrieves a single spent or received money transaction by using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransactionAsync($xero_tenant_id, $bank_transaction_id, $unitdp = null)
    {
        return $this->getBankTransactionAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $unitdp)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransactionAsyncWithHttpInfo
     * Retrieves a single spent or received money transaction by using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransactionAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $unitdp = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
        $request = $this->getBankTransactionRequest($xero_tenant_id, $bank_transaction_id, $unitdp);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransaction'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransactionRequest($xero_tenant_id, $bank_transaction_id, $unitdp = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransaction'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling getBankTransaction'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransactionAttachmentByFileName
     * Retrieves a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getBankTransactionAttachmentByFileName($xero_tenant_id, $bank_transaction_id, $file_name, $content_type)
    {
        list($response) = $this->getBankTransactionAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getBankTransactionAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransactionAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $content_type)
    {
        $request = $this->getBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransactionAttachmentByFileNameAsync
     * Retrieves a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransactionAttachmentByFileNameAsync($xero_tenant_id, $bank_transaction_id, $file_name, $content_type)
    {
        return $this->getBankTransactionAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransactionAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransactionAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransactionAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling getBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getBankTransactionAttachmentByFileName'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransactionAttachmentById
     * Retrieves specific attachments from a specific BankTransaction using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getBankTransactionAttachmentById($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type)
    {
        list($response) = $this->getBankTransactionAttachmentByIdWithHttpInfo($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getBankTransactionAttachmentByIdWithHttpInfo
     * Retrieves specific attachments from a specific BankTransaction using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransactionAttachmentByIdWithHttpInfo($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type)
    {
        $request = $this->getBankTransactionAttachmentByIdRequest($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransactionAttachmentByIdAsync
     * Retrieves specific attachments from a specific BankTransaction using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransactionAttachmentByIdAsync($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type)
    {
        return $this->getBankTransactionAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransactionAttachmentByIdAsyncWithHttpInfo
     * Retrieves specific attachments from a specific BankTransaction using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransactionAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getBankTransactionAttachmentByIdRequest($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransactionAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransactionAttachmentByIdRequest($xero_tenant_id, $bank_transaction_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransactionAttachmentById'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling getBankTransactionAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getBankTransactionAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getBankTransactionAttachmentById'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransactionAttachments
     * Retrieves any attachments from a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getBankTransactionAttachments($xero_tenant_id, $bank_transaction_id)
    {
        list($response) = $this->getBankTransactionAttachmentsWithHttpInfo($xero_tenant_id, $bank_transaction_id);
        return $response;
    }
    /**
     * Operation getBankTransactionAttachmentsWithHttpInfo
     * Retrieves any attachments from a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransactionAttachmentsWithHttpInfo($xero_tenant_id, $bank_transaction_id)
    {
        $request = $this->getBankTransactionAttachmentsRequest($xero_tenant_id, $bank_transaction_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransactionAttachmentsAsync
     * Retrieves any attachments from a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransactionAttachmentsAsync($xero_tenant_id, $bank_transaction_id)
    {
        return $this->getBankTransactionAttachmentsAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransactionAttachmentsAsyncWithHttpInfo
     * Retrieves any attachments from a specific bank transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransactionAttachmentsAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getBankTransactionAttachmentsRequest($xero_tenant_id, $bank_transaction_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransactionAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransactionAttachmentsRequest($xero_tenant_id, $bank_transaction_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransactionAttachments'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling getBankTransactionAttachments'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransactions
     * Retrieves any spent or received money transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 bank transactions will be returned in a single API call with line items details (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransactions
     */
    public function getBankTransactions($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        list($response) = $this->getBankTransactionsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $response;
    }
    /**
     * Operation getBankTransactionsWithHttpInfo
     * Retrieves any spent or received money transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 bank transactions will be returned in a single API call with line items details (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransactions, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransactionsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $request = $this->getBankTransactionsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransactionsAsync
     * Retrieves any spent or received money transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 bank transactions will be returned in a single API call with line items details (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransactionsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        return $this->getBankTransactionsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransactionsAsyncWithHttpInfo
     * Retrieves any spent or received money transactions
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 bank transactions will be returned in a single API call with line items details (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransactionsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
        $request = $this->getBankTransactionsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransactions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 bank transactions will be returned in a single API call with line items details (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransactionsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransactions'
            );
        }
        $resourcePath = '/BankTransactions';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransactionsHistory
     * Retrieves history from a specific bank transaction using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getBankTransactionsHistory($xero_tenant_id, $bank_transaction_id)
    {
        list($response) = $this->getBankTransactionsHistoryWithHttpInfo($xero_tenant_id, $bank_transaction_id);
        return $response;
    }
    /**
     * Operation getBankTransactionsHistoryWithHttpInfo
     * Retrieves history from a specific bank transaction using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransactionsHistoryWithHttpInfo($xero_tenant_id, $bank_transaction_id)
    {
        $request = $this->getBankTransactionsHistoryRequest($xero_tenant_id, $bank_transaction_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransactionsHistoryAsync
     * Retrieves history from a specific bank transaction using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransactionsHistoryAsync($xero_tenant_id, $bank_transaction_id)
    {
        return $this->getBankTransactionsHistoryAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransactionsHistoryAsyncWithHttpInfo
     * Retrieves history from a specific bank transaction using a unique bank transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransactionsHistoryAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getBankTransactionsHistoryRequest($xero_tenant_id, $bank_transaction_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransactionsHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransactionsHistoryRequest($xero_tenant_id, $bank_transaction_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransactionsHistory'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling getBankTransactionsHistory'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransfer
     * Retrieves specific bank transfers by using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransfers
     */
    public function getBankTransfer($xero_tenant_id, $bank_transfer_id)
    {
        list($response) = $this->getBankTransferWithHttpInfo($xero_tenant_id, $bank_transfer_id);
        return $response;
    }
    /**
     * Operation getBankTransferWithHttpInfo
     * Retrieves specific bank transfers by using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransfers, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransferWithHttpInfo($xero_tenant_id, $bank_transfer_id)
    {
        $request = $this->getBankTransferRequest($xero_tenant_id, $bank_transfer_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransfers' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransferAsync
     * Retrieves specific bank transfers by using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransferAsync($xero_tenant_id, $bank_transfer_id)
    {
        return $this->getBankTransferAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransferAsyncWithHttpInfo
     * Retrieves specific bank transfers by using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransferAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers';
        $request = $this->getBankTransferRequest($xero_tenant_id, $bank_transfer_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransfer'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransferRequest($xero_tenant_id, $bank_transfer_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransfer'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling getBankTransfer'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransferAttachmentByFileName
     * Retrieves a specific attachment on a specific bank transfer by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getBankTransferAttachmentByFileName($xero_tenant_id, $bank_transfer_id, $file_name, $content_type)
    {
        list($response) = $this->getBankTransferAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getBankTransferAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment on a specific bank transfer by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransferAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $content_type)
    {
        $request = $this->getBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransferAttachmentByFileNameAsync
     * Retrieves a specific attachment on a specific bank transfer by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransferAttachmentByFileNameAsync($xero_tenant_id, $bank_transfer_id, $file_name, $content_type)
    {
        return $this->getBankTransferAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransferAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment on a specific bank transfer by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransferAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransferAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling getBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getBankTransferAttachmentByFileName'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransferAttachmentById
     * Retrieves a specific attachment from a specific bank transfer using a unique attachment ID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getBankTransferAttachmentById($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type)
    {
        list($response) = $this->getBankTransferAttachmentByIdWithHttpInfo($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getBankTransferAttachmentByIdWithHttpInfo
     * Retrieves a specific attachment from a specific bank transfer using a unique attachment ID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransferAttachmentByIdWithHttpInfo($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type)
    {
        $request = $this->getBankTransferAttachmentByIdRequest($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransferAttachmentByIdAsync
     * Retrieves a specific attachment from a specific bank transfer using a unique attachment ID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransferAttachmentByIdAsync($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type)
    {
        return $this->getBankTransferAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransferAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific bank transfer using a unique attachment ID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransferAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getBankTransferAttachmentByIdRequest($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransferAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransferAttachmentByIdRequest($xero_tenant_id, $bank_transfer_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransferAttachmentById'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling getBankTransferAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getBankTransferAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getBankTransferAttachmentById'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransferAttachments
     * Retrieves attachments from a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getBankTransferAttachments($xero_tenant_id, $bank_transfer_id)
    {
        list($response) = $this->getBankTransferAttachmentsWithHttpInfo($xero_tenant_id, $bank_transfer_id);
        return $response;
    }
    /**
     * Operation getBankTransferAttachmentsWithHttpInfo
     * Retrieves attachments from a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransferAttachmentsWithHttpInfo($xero_tenant_id, $bank_transfer_id)
    {
        $request = $this->getBankTransferAttachmentsRequest($xero_tenant_id, $bank_transfer_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransferAttachmentsAsync
     * Retrieves attachments from a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransferAttachmentsAsync($xero_tenant_id, $bank_transfer_id)
    {
        return $this->getBankTransferAttachmentsAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransferAttachmentsAsyncWithHttpInfo
     * Retrieves attachments from a specific bank transfer
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransferAttachmentsAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getBankTransferAttachmentsRequest($xero_tenant_id, $bank_transfer_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransferAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransferAttachmentsRequest($xero_tenant_id, $bank_transfer_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransferAttachments'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling getBankTransferAttachments'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransferHistory
     * Retrieves history from a specific bank transfer using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getBankTransferHistory($xero_tenant_id, $bank_transfer_id)
    {
        list($response) = $this->getBankTransferHistoryWithHttpInfo($xero_tenant_id, $bank_transfer_id);
        return $response;
    }
    /**
     * Operation getBankTransferHistoryWithHttpInfo
     * Retrieves history from a specific bank transfer using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransferHistoryWithHttpInfo($xero_tenant_id, $bank_transfer_id)
    {
        $request = $this->getBankTransferHistoryRequest($xero_tenant_id, $bank_transfer_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransferHistoryAsync
     * Retrieves history from a specific bank transfer using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransferHistoryAsync($xero_tenant_id, $bank_transfer_id)
    {
        return $this->getBankTransferHistoryAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransferHistoryAsyncWithHttpInfo
     * Retrieves history from a specific bank transfer using a unique bank transfer Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransferHistoryAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getBankTransferHistoryRequest($xero_tenant_id, $bank_transfer_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransferHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransferHistoryRequest($xero_tenant_id, $bank_transfer_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransferHistory'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling getBankTransferHistory'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBankTransfers
     * Retrieves all bank transfers
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransfers
     */
    public function getBankTransfers($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        list($response) = $this->getBankTransfersWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order);
        return $response;
    }
    /**
     * Operation getBankTransfersWithHttpInfo
     * Retrieves all bank transfers
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransfers, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBankTransfersWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $request = $this->getBankTransfersRequest($xero_tenant_id, $if_modified_since, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransfers' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBankTransfersAsync
     * Retrieves all bank transfers
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBankTransfersAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        return $this->getBankTransfersAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBankTransfersAsyncWithHttpInfo
     * Retrieves all bank transfers
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBankTransfersAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransfers';
        $request = $this->getBankTransfersRequest($xero_tenant_id, $if_modified_since, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBankTransfers'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBankTransfersRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBankTransfers'
            );
        }
        $resourcePath = '/BankTransfers';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBatchPayment
     * Retrieves a specific batch payment using a unique batch payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BatchPayments
     */
    public function getBatchPayment($xero_tenant_id, $batch_payment_id)
    {
        list($response) = $this->getBatchPaymentWithHttpInfo($xero_tenant_id, $batch_payment_id);
        return $response;
    }
    /**
     * Operation getBatchPaymentWithHttpInfo
     * Retrieves a specific batch payment using a unique batch payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BatchPayments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBatchPaymentWithHttpInfo($xero_tenant_id, $batch_payment_id)
    {
        $request = $this->getBatchPaymentRequest($xero_tenant_id, $batch_payment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BatchPayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBatchPaymentAsync
     * Retrieves a specific batch payment using a unique batch payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBatchPaymentAsync($xero_tenant_id, $batch_payment_id)
    {
        return $this->getBatchPaymentAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBatchPaymentAsyncWithHttpInfo
     * Retrieves a specific batch payment using a unique batch payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBatchPaymentAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
        $request = $this->getBatchPaymentRequest($xero_tenant_id, $batch_payment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBatchPayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBatchPaymentRequest($xero_tenant_id, $batch_payment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBatchPayment'
            );
        }
        // verify the required parameter 'batch_payment_id' is set
        if ($batch_payment_id === null || (is_array($batch_payment_id) && count($batch_payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $batch_payment_id when calling getBatchPayment'
            );
        }
        $resourcePath = '/BatchPayments/{BatchPaymentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($batch_payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BatchPaymentID' . '}',
                AccountingObjectSerializer::toPathValue($batch_payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBatchPaymentHistory
     * Retrieves history from a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getBatchPaymentHistory($xero_tenant_id, $batch_payment_id)
    {
        list($response) = $this->getBatchPaymentHistoryWithHttpInfo($xero_tenant_id, $batch_payment_id);
        return $response;
    }
    /**
     * Operation getBatchPaymentHistoryWithHttpInfo
     * Retrieves history from a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBatchPaymentHistoryWithHttpInfo($xero_tenant_id, $batch_payment_id)
    {
        $request = $this->getBatchPaymentHistoryRequest($xero_tenant_id, $batch_payment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBatchPaymentHistoryAsync
     * Retrieves history from a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBatchPaymentHistoryAsync($xero_tenant_id, $batch_payment_id)
    {
        return $this->getBatchPaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBatchPaymentHistoryAsyncWithHttpInfo
     * Retrieves history from a specific batch payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBatchPaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $batch_payment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getBatchPaymentHistoryRequest($xero_tenant_id, $batch_payment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBatchPaymentHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $batch_payment_id Unique identifier for BatchPayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBatchPaymentHistoryRequest($xero_tenant_id, $batch_payment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBatchPaymentHistory'
            );
        }
        // verify the required parameter 'batch_payment_id' is set
        if ($batch_payment_id === null || (is_array($batch_payment_id) && count($batch_payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $batch_payment_id when calling getBatchPaymentHistory'
            );
        }
        $resourcePath = '/BatchPayments/{BatchPaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($batch_payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BatchPaymentID' . '}',
                AccountingObjectSerializer::toPathValue($batch_payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBatchPayments
     * Retrieves either one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BatchPayments
     */
    public function getBatchPayments($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        list($response) = $this->getBatchPaymentsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order);
        return $response;
    }
    /**
     * Operation getBatchPaymentsWithHttpInfo
     * Retrieves either one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BatchPayments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBatchPaymentsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $request = $this->getBatchPaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BatchPayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBatchPaymentsAsync
     * Retrieves either one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBatchPaymentsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        return $this->getBatchPaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBatchPaymentsAsyncWithHttpInfo
     * Retrieves either one or many batch payments for invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBatchPaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BatchPayments';
        $request = $this->getBatchPaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBatchPayments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBatchPaymentsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBatchPayments'
            );
        }
        $resourcePath = '/BatchPayments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBrandingTheme
     * Retrieves a specific branding theme using a unique branding theme Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BrandingThemes
     */
    public function getBrandingTheme($xero_tenant_id, $branding_theme_id)
    {
        list($response) = $this->getBrandingThemeWithHttpInfo($xero_tenant_id, $branding_theme_id);
        return $response;
    }
    /**
     * Operation getBrandingThemeWithHttpInfo
     * Retrieves a specific branding theme using a unique branding theme Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BrandingThemes, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBrandingThemeWithHttpInfo($xero_tenant_id, $branding_theme_id)
    {
        $request = $this->getBrandingThemeRequest($xero_tenant_id, $branding_theme_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBrandingThemeAsync
     * Retrieves a specific branding theme using a unique branding theme Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBrandingThemeAsync($xero_tenant_id, $branding_theme_id)
    {
        return $this->getBrandingThemeAsyncWithHttpInfo($xero_tenant_id, $branding_theme_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBrandingThemeAsyncWithHttpInfo
     * Retrieves a specific branding theme using a unique branding theme Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBrandingThemeAsyncWithHttpInfo($xero_tenant_id, $branding_theme_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes';
        $request = $this->getBrandingThemeRequest($xero_tenant_id, $branding_theme_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBrandingTheme'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBrandingThemeRequest($xero_tenant_id, $branding_theme_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBrandingTheme'
            );
        }
        // verify the required parameter 'branding_theme_id' is set
        if ($branding_theme_id === null || (is_array($branding_theme_id) && count($branding_theme_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $branding_theme_id when calling getBrandingTheme'
            );
        }
        $resourcePath = '/BrandingThemes/{BrandingThemeID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($branding_theme_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BrandingThemeID' . '}',
                AccountingObjectSerializer::toPathValue($branding_theme_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBrandingThemePaymentServices
     * Retrieves the payment services for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PaymentServices
     */
    public function getBrandingThemePaymentServices($xero_tenant_id, $branding_theme_id)
    {
        list($response) = $this->getBrandingThemePaymentServicesWithHttpInfo($xero_tenant_id, $branding_theme_id);
        return $response;
    }
    /**
     * Operation getBrandingThemePaymentServicesWithHttpInfo
     * Retrieves the payment services for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PaymentServices, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBrandingThemePaymentServicesWithHttpInfo($xero_tenant_id, $branding_theme_id)
    {
        $request = $this->getBrandingThemePaymentServicesRequest($xero_tenant_id, $branding_theme_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PaymentServices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBrandingThemePaymentServicesAsync
     * Retrieves the payment services for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBrandingThemePaymentServicesAsync($xero_tenant_id, $branding_theme_id)
    {
        return $this->getBrandingThemePaymentServicesAsyncWithHttpInfo($xero_tenant_id, $branding_theme_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBrandingThemePaymentServicesAsyncWithHttpInfo
     * Retrieves the payment services for a specific branding theme
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBrandingThemePaymentServicesAsyncWithHttpInfo($xero_tenant_id, $branding_theme_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
        $request = $this->getBrandingThemePaymentServicesRequest($xero_tenant_id, $branding_theme_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBrandingThemePaymentServices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $branding_theme_id Unique identifier for a Branding Theme (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBrandingThemePaymentServicesRequest($xero_tenant_id, $branding_theme_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBrandingThemePaymentServices'
            );
        }
        // verify the required parameter 'branding_theme_id' is set
        if ($branding_theme_id === null || (is_array($branding_theme_id) && count($branding_theme_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $branding_theme_id when calling getBrandingThemePaymentServices'
            );
        }
        $resourcePath = '/BrandingThemes/{BrandingThemeID}/PaymentServices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($branding_theme_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BrandingThemeID' . '}',
                AccountingObjectSerializer::toPathValue($branding_theme_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBrandingThemes
     * Retrieves all the branding themes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BrandingThemes
     */
    public function getBrandingThemes($xero_tenant_id)
    {
        list($response) = $this->getBrandingThemesWithHttpInfo($xero_tenant_id);
        return $response;
    }
    /**
     * Operation getBrandingThemesWithHttpInfo
     * Retrieves all the branding themes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BrandingThemes, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBrandingThemesWithHttpInfo($xero_tenant_id)
    {
        $request = $this->getBrandingThemesRequest($xero_tenant_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBrandingThemesAsync
     * Retrieves all the branding themes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBrandingThemesAsync($xero_tenant_id)
    {
        return $this->getBrandingThemesAsyncWithHttpInfo($xero_tenant_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBrandingThemesAsyncWithHttpInfo
     * Retrieves all the branding themes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBrandingThemesAsyncWithHttpInfo($xero_tenant_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BrandingThemes';
        $request = $this->getBrandingThemesRequest($xero_tenant_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBrandingThemes'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBrandingThemesRequest($xero_tenant_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBrandingThemes'
            );
        }
        $resourcePath = '/BrandingThemes';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBudget
     * Retrieves a specific budget, which includes budget lines
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $budget_id Unique identifier for Budgets (required)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Budgets
     */
    public function getBudget($xero_tenant_id, $budget_id, $date_to = null, $date_from = null)
    {
        list($response) = $this->getBudgetWithHttpInfo($xero_tenant_id, $budget_id, $date_to, $date_from);
        return $response;
    }
    /**
     * Operation getBudgetWithHttpInfo
     * Retrieves a specific budget, which includes budget lines
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $budget_id Unique identifier for Budgets (required)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Budgets, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBudgetWithHttpInfo($xero_tenant_id, $budget_id, $date_to = null, $date_from = null)
    {
        $request = $this->getBudgetRequest($xero_tenant_id, $budget_id, $date_to, $date_from);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Budgets' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Budgets', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Budgets';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Budgets',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBudgetAsync
     * Retrieves a specific budget, which includes budget lines
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $budget_id Unique identifier for Budgets (required)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBudgetAsync($xero_tenant_id, $budget_id, $date_to = null, $date_from = null)
    {
        return $this->getBudgetAsyncWithHttpInfo($xero_tenant_id, $budget_id, $date_to, $date_from)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBudgetAsyncWithHttpInfo
     * Retrieves a specific budget, which includes budget lines
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $budget_id Unique identifier for Budgets (required)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBudgetAsyncWithHttpInfo($xero_tenant_id, $budget_id, $date_to = null, $date_from = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Budgets';
        $request = $this->getBudgetRequest($xero_tenant_id, $budget_id, $date_to, $date_from);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBudget'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $budget_id Unique identifier for Budgets (required)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBudgetRequest($xero_tenant_id, $budget_id, $date_to = null, $date_from = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBudget'
            );
        }
        // verify the required parameter 'budget_id' is set
        if ($budget_id === null || (is_array($budget_id) && count($budget_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $budget_id when calling getBudget'
            );
        }
        $resourcePath = '/Budgets/{BudgetID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($date_to !== null) {
            $queryParams['DateTo'] = AccountingObjectSerializer::toQueryValue($date_to);
        }
        // query params
        if ($date_from !== null) {
            $queryParams['DateFrom'] = AccountingObjectSerializer::toQueryValue($date_from);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($budget_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BudgetID' . '}',
                AccountingObjectSerializer::toPathValue($budget_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getBudgets
     * Retrieve a list of budgets
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string[] $ids Filter by BudgetID. Allows you to retrieve a specific individual budget. (optional)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Budgets
     */
    public function getBudgets($xero_tenant_id, $ids = null, $date_to = null, $date_from = null)
    {
        list($response) = $this->getBudgetsWithHttpInfo($xero_tenant_id, $ids, $date_to, $date_from);
        return $response;
    }
    /**
     * Operation getBudgetsWithHttpInfo
     * Retrieve a list of budgets
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string[] $ids Filter by BudgetID. Allows you to retrieve a specific individual budget. (optional)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Budgets, HTTP status code, HTTP response headers (array of strings)
     */
    public function getBudgetsWithHttpInfo($xero_tenant_id, $ids = null, $date_to = null, $date_from = null)
    {
        $request = $this->getBudgetsRequest($xero_tenant_id, $ids, $date_to, $date_from);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Budgets' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Budgets', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Budgets';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Budgets',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getBudgetsAsync
     * Retrieve a list of budgets
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string[] $ids Filter by BudgetID. Allows you to retrieve a specific individual budget. (optional)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getBudgetsAsync($xero_tenant_id, $ids = null, $date_to = null, $date_from = null)
    {
        return $this->getBudgetsAsyncWithHttpInfo($xero_tenant_id, $ids, $date_to, $date_from)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getBudgetsAsyncWithHttpInfo
     * Retrieve a list of budgets
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string[] $ids Filter by BudgetID. Allows you to retrieve a specific individual budget. (optional)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getBudgetsAsyncWithHttpInfo($xero_tenant_id, $ids = null, $date_to = null, $date_from = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Budgets';
        $request = $this->getBudgetsRequest($xero_tenant_id, $ids, $date_to, $date_from);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getBudgets'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string[] $ids Filter by BudgetID. Allows you to retrieve a specific individual budget. (optional)
     * @param  \DateTime $date_to Filter by start date (optional)
     * @param  \DateTime $date_from Filter by end date (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getBudgetsRequest($xero_tenant_id, $ids = null, $date_to = null, $date_from = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getBudgets'
            );
        }
        $resourcePath = '/Budgets';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if (is_array($ids)) {
            $ids = AccountingObjectSerializer::serializeCollection($ids, 'csv', true);
        }
        if ($ids !== null) {
            $queryParams['IDs'] = AccountingObjectSerializer::toQueryValue($ids);
        }
        // query params
        if ($date_to !== null) {
            $queryParams['DateTo'] = AccountingObjectSerializer::toQueryValue($date_to);
        }
        // query params
        if ($date_from !== null) {
            $queryParams['DateFrom'] = AccountingObjectSerializer::toQueryValue($date_from);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContact
     * Retrieves a specific contacts in a Xero organisation using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Contacts
     */
    public function getContact($xero_tenant_id, $contact_id)
    {
        list($response) = $this->getContactWithHttpInfo($xero_tenant_id, $contact_id);
        return $response;
    }
    /**
     * Operation getContactWithHttpInfo
     * Retrieves a specific contacts in a Xero organisation using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Contacts, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $request = $this->getContactRequest($xero_tenant_id, $contact_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Contacts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Contacts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Contacts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactAsync
     * Retrieves a specific contacts in a Xero organisation using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactAsync($xero_tenant_id, $contact_id)
    {
        return $this->getContactAsyncWithHttpInfo($xero_tenant_id, $contact_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactAsyncWithHttpInfo
     * Retrieves a specific contacts in a Xero organisation using a unique contact Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactAsyncWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
        $request = $this->getContactRequest($xero_tenant_id, $contact_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContact'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactRequest($xero_tenant_id, $contact_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContact'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getContact'
            );
        }
        $resourcePath = '/Contacts/{ContactID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactAttachmentByFileName
     * Retrieves a specific attachment from a specific contact by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getContactAttachmentByFileName($xero_tenant_id, $contact_id, $file_name, $content_type)
    {
        list($response) = $this->getContactAttachmentByFileNameWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getContactAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment from a specific contact by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactAttachmentByFileNameWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $content_type)
    {
        $request = $this->getContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactAttachmentByFileNameAsync
     * Retrieves a specific attachment from a specific contact by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactAttachmentByFileNameAsync($xero_tenant_id, $contact_id, $file_name, $content_type)
    {
        return $this->getContactAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific contact by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getContactAttachmentByFileName'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactAttachmentById
     * Retrieves a specific attachment from a specific contact using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getContactAttachmentById($xero_tenant_id, $contact_id, $attachment_id, $content_type)
    {
        list($response) = $this->getContactAttachmentByIdWithHttpInfo($xero_tenant_id, $contact_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getContactAttachmentByIdWithHttpInfo
     * Retrieves a specific attachment from a specific contact using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactAttachmentByIdWithHttpInfo($xero_tenant_id, $contact_id, $attachment_id, $content_type)
    {
        $request = $this->getContactAttachmentByIdRequest($xero_tenant_id, $contact_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactAttachmentByIdAsync
     * Retrieves a specific attachment from a specific contact using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactAttachmentByIdAsync($xero_tenant_id, $contact_id, $attachment_id, $content_type)
    {
        return $this->getContactAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $contact_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific contact using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $contact_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getContactAttachmentByIdRequest($xero_tenant_id, $contact_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactAttachmentByIdRequest($xero_tenant_id, $contact_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactAttachmentById'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getContactAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getContactAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getContactAttachmentById'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactAttachments
     * Retrieves attachments for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getContactAttachments($xero_tenant_id, $contact_id)
    {
        list($response) = $this->getContactAttachmentsWithHttpInfo($xero_tenant_id, $contact_id);
        return $response;
    }
    /**
     * Operation getContactAttachmentsWithHttpInfo
     * Retrieves attachments for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactAttachmentsWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $request = $this->getContactAttachmentsRequest($xero_tenant_id, $contact_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactAttachmentsAsync
     * Retrieves attachments for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactAttachmentsAsync($xero_tenant_id, $contact_id)
    {
        return $this->getContactAttachmentsAsyncWithHttpInfo($xero_tenant_id, $contact_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactAttachmentsAsyncWithHttpInfo
     * Retrieves attachments for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactAttachmentsAsyncWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getContactAttachmentsRequest($xero_tenant_id, $contact_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactAttachmentsRequest($xero_tenant_id, $contact_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactAttachments'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getContactAttachments'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactByContactNumber
     * Retrieves a specific contact by contact number in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_number This field is read only on the Xero contact screen, used to identify contacts in external systems (max length &#x3D; 50). (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Contacts
     */
    public function getContactByContactNumber($xero_tenant_id, $contact_number)
    {
        list($response) = $this->getContactByContactNumberWithHttpInfo($xero_tenant_id, $contact_number);
        return $response;
    }
    /**
     * Operation getContactByContactNumberWithHttpInfo
     * Retrieves a specific contact by contact number in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_number This field is read only on the Xero contact screen, used to identify contacts in external systems (max length &#x3D; 50). (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Contacts, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactByContactNumberWithHttpInfo($xero_tenant_id, $contact_number)
    {
        $request = $this->getContactByContactNumberRequest($xero_tenant_id, $contact_number);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Contacts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Contacts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Contacts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactByContactNumberAsync
     * Retrieves a specific contact by contact number in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_number This field is read only on the Xero contact screen, used to identify contacts in external systems (max length &#x3D; 50). (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactByContactNumberAsync($xero_tenant_id, $contact_number)
    {
        return $this->getContactByContactNumberAsyncWithHttpInfo($xero_tenant_id, $contact_number)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactByContactNumberAsyncWithHttpInfo
     * Retrieves a specific contact by contact number in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_number This field is read only on the Xero contact screen, used to identify contacts in external systems (max length &#x3D; 50). (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactByContactNumberAsyncWithHttpInfo($xero_tenant_id, $contact_number)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
        $request = $this->getContactByContactNumberRequest($xero_tenant_id, $contact_number);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactByContactNumber'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_number This field is read only on the Xero contact screen, used to identify contacts in external systems (max length &#x3D; 50). (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactByContactNumberRequest($xero_tenant_id, $contact_number)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactByContactNumber'
            );
        }
        // verify the required parameter 'contact_number' is set
        if ($contact_number === null || (is_array($contact_number) && count($contact_number) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_number when calling getContactByContactNumber'
            );
        }
        $resourcePath = '/Contacts/{ContactNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_number !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactNumber' . '}',
                AccountingObjectSerializer::toPathValue($contact_number),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactCISSettings
     * Retrieves CIS settings for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\CISSettings
     */
    public function getContactCISSettings($xero_tenant_id, $contact_id)
    {
        list($response) = $this->getContactCISSettingsWithHttpInfo($xero_tenant_id, $contact_id);
        return $response;
    }
    /**
     * Operation getContactCISSettingsWithHttpInfo
     * Retrieves CIS settings for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\CISSettings, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactCISSettingsWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $request = $this->getContactCISSettingsRequest($xero_tenant_id, $contact_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\CISSettings' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\CISSettings', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CISSettings';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\CISSettings',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactCISSettingsAsync
     * Retrieves CIS settings for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactCISSettingsAsync($xero_tenant_id, $contact_id)
    {
        return $this->getContactCISSettingsAsyncWithHttpInfo($xero_tenant_id, $contact_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactCISSettingsAsyncWithHttpInfo
     * Retrieves CIS settings for a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactCISSettingsAsyncWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CISSettings';
        $request = $this->getContactCISSettingsRequest($xero_tenant_id, $contact_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactCISSettings'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactCISSettingsRequest($xero_tenant_id, $contact_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactCISSettings'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getContactCISSettings'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/CISSettings';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactGroup
     * Retrieves a specific contact group by using a unique contact group Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ContactGroups
     */
    public function getContactGroup($xero_tenant_id, $contact_group_id)
    {
        list($response) = $this->getContactGroupWithHttpInfo($xero_tenant_id, $contact_group_id);
        return $response;
    }
    /**
     * Operation getContactGroupWithHttpInfo
     * Retrieves a specific contact group by using a unique contact group Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ContactGroups, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactGroupWithHttpInfo($xero_tenant_id, $contact_group_id)
    {
        $request = $this->getContactGroupRequest($xero_tenant_id, $contact_group_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ContactGroups' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactGroupAsync
     * Retrieves a specific contact group by using a unique contact group Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactGroupAsync($xero_tenant_id, $contact_group_id)
    {
        return $this->getContactGroupAsyncWithHttpInfo($xero_tenant_id, $contact_group_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactGroupAsyncWithHttpInfo
     * Retrieves a specific contact group by using a unique contact group Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactGroupAsyncWithHttpInfo($xero_tenant_id, $contact_group_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
        $request = $this->getContactGroupRequest($xero_tenant_id, $contact_group_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactGroup'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactGroupRequest($xero_tenant_id, $contact_group_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactGroup'
            );
        }
        // verify the required parameter 'contact_group_id' is set
        if ($contact_group_id === null || (is_array($contact_group_id) && count($contact_group_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_group_id when calling getContactGroup'
            );
        }
        $resourcePath = '/ContactGroups/{ContactGroupID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_group_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactGroupID' . '}',
                AccountingObjectSerializer::toPathValue($contact_group_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactGroups
     * Retrieves the contact Id and name of each contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ContactGroups
     */
    public function getContactGroups($xero_tenant_id, $where = null, $order = null)
    {
        list($response) = $this->getContactGroupsWithHttpInfo($xero_tenant_id, $where, $order);
        return $response;
    }
    /**
     * Operation getContactGroupsWithHttpInfo
     * Retrieves the contact Id and name of each contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ContactGroups, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactGroupsWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $request = $this->getContactGroupsRequest($xero_tenant_id, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ContactGroups' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactGroupsAsync
     * Retrieves the contact Id and name of each contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactGroupsAsync($xero_tenant_id, $where = null, $order = null)
    {
        return $this->getContactGroupsAsyncWithHttpInfo($xero_tenant_id, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactGroupsAsyncWithHttpInfo
     * Retrieves the contact Id and name of each contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactGroupsAsyncWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
        $request = $this->getContactGroupsRequest($xero_tenant_id, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactGroups'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactGroupsRequest($xero_tenant_id, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactGroups'
            );
        }
        $resourcePath = '/ContactGroups';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContactHistory
     * Retrieves history records for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getContactHistory($xero_tenant_id, $contact_id)
    {
        list($response) = $this->getContactHistoryWithHttpInfo($xero_tenant_id, $contact_id);
        return $response;
    }
    /**
     * Operation getContactHistoryWithHttpInfo
     * Retrieves history records for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactHistoryWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $request = $this->getContactHistoryRequest($xero_tenant_id, $contact_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactHistoryAsync
     * Retrieves history records for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactHistoryAsync($xero_tenant_id, $contact_id)
    {
        return $this->getContactHistoryAsyncWithHttpInfo($xero_tenant_id, $contact_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactHistoryAsyncWithHttpInfo
     * Retrieves history records for a specific contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactHistoryAsyncWithHttpInfo($xero_tenant_id, $contact_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getContactHistoryRequest($xero_tenant_id, $contact_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContactHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactHistoryRequest($xero_tenant_id, $contact_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContactHistory'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getContactHistory'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getContacts
     * Retrieves all contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma separated list of ContactIDs. Allows you to retrieve a specific set of contacts in a single call. (optional)
     * @param  int $page e.g. page&#x3D;1 - Up to 100 contacts will be returned in a single API call. (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Contacts with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Contacts
     */
    public function getContacts($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $page = null, $include_archived = null, $summary_only = false, $search_term = null, $page_size = null)
    {
        list($response) = $this->getContactsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $ids, $page, $include_archived, $summary_only, $search_term, $page_size);
        return $response;
    }
    /**
     * Operation getContactsWithHttpInfo
     * Retrieves all contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma separated list of ContactIDs. Allows you to retrieve a specific set of contacts in a single call. (optional)
     * @param  int $page e.g. page&#x3D;1 - Up to 100 contacts will be returned in a single API call. (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Contacts with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Contacts, HTTP status code, HTTP response headers (array of strings)
     */
    public function getContactsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $page = null, $include_archived = null, $summary_only = false, $search_term = null, $page_size = null)
    {
        $request = $this->getContactsRequest($xero_tenant_id, $if_modified_since, $where, $order, $ids, $page, $include_archived, $summary_only, $search_term, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Contacts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Contacts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Contacts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getContactsAsync
     * Retrieves all contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma separated list of ContactIDs. Allows you to retrieve a specific set of contacts in a single call. (optional)
     * @param  int $page e.g. page&#x3D;1 - Up to 100 contacts will be returned in a single API call. (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Contacts with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getContactsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $page = null, $include_archived = null, $summary_only = false, $search_term = null, $page_size = null)
    {
        return $this->getContactsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $ids, $page, $include_archived, $summary_only, $search_term, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getContactsAsyncWithHttpInfo
     * Retrieves all contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma separated list of ContactIDs. Allows you to retrieve a specific set of contacts in a single call. (optional)
     * @param  int $page e.g. page&#x3D;1 - Up to 100 contacts will be returned in a single API call. (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Contacts with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getContactsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $page = null, $include_archived = null, $summary_only = false, $search_term = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
        $request = $this->getContactsRequest($xero_tenant_id, $if_modified_since, $where, $order, $ids, $page, $include_archived, $summary_only, $search_term, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getContacts'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma separated list of ContactIDs. Allows you to retrieve a specific set of contacts in a single call. (optional)
     * @param  int $page e.g. page&#x3D;1 - Up to 100 contacts will be returned in a single API call. (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Contacts with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the Name, FirstName, LastName, ContactNumber and EmailAddress fields. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getContactsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $page = null, $include_archived = null, $summary_only = false, $search_term = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getContacts'
            );
        }
        $resourcePath = '/Contacts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if (is_array($ids)) {
            $ids = AccountingObjectSerializer::serializeCollection($ids, 'csv', true);
        }
        if ($ids !== null) {
            $queryParams['IDs'] = AccountingObjectSerializer::toQueryValue($ids);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($include_archived !== null) {
            $queryParams['includeArchived'] = $include_archived ? 'true' : 'false';
        }
        // query params
        if ($summary_only !== null) {
            $queryParams['summaryOnly'] = $summary_only ? 'true' : 'false';
        }
        // query params
        if ($search_term !== null) {
            $queryParams['searchTerm'] = AccountingObjectSerializer::toQueryValue($search_term);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCreditNote
     * Retrieves a specific credit note using a unique credit note Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\CreditNotes
     */
    public function getCreditNote($xero_tenant_id, $credit_note_id, $unitdp = null)
    {
        list($response) = $this->getCreditNoteWithHttpInfo($xero_tenant_id, $credit_note_id, $unitdp);
        return $response;
    }
    /**
     * Operation getCreditNoteWithHttpInfo
     * Retrieves a specific credit note using a unique credit note Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\CreditNotes, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCreditNoteWithHttpInfo($xero_tenant_id, $credit_note_id, $unitdp = null)
    {
        $request = $this->getCreditNoteRequest($xero_tenant_id, $credit_note_id, $unitdp);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\CreditNotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCreditNoteAsync
     * Retrieves a specific credit note using a unique credit note Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCreditNoteAsync($xero_tenant_id, $credit_note_id, $unitdp = null)
    {
        return $this->getCreditNoteAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $unitdp)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCreditNoteAsyncWithHttpInfo
     * Retrieves a specific credit note using a unique credit note Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCreditNoteAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $unitdp = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
        $request = $this->getCreditNoteRequest($xero_tenant_id, $credit_note_id, $unitdp);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCreditNote'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCreditNoteRequest($xero_tenant_id, $credit_note_id, $unitdp = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCreditNote'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling getCreditNote'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCreditNoteAsPdf
     * Retrieves credit notes as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getCreditNoteAsPdf($xero_tenant_id, $credit_note_id)
    {
        list($response) = $this->getCreditNoteAsPdfWithHttpInfo($xero_tenant_id, $credit_note_id);
        return $response;
    }
    /**
     * Operation getCreditNoteAsPdfWithHttpInfo
     * Retrieves credit notes as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCreditNoteAsPdfWithHttpInfo($xero_tenant_id, $credit_note_id)
    {
        $request = $this->getCreditNoteAsPdfRequest($xero_tenant_id, $credit_note_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCreditNoteAsPdfAsync
     * Retrieves credit notes as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCreditNoteAsPdfAsync($xero_tenant_id, $credit_note_id)
    {
        return $this->getCreditNoteAsPdfAsyncWithHttpInfo($xero_tenant_id, $credit_note_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCreditNoteAsPdfAsyncWithHttpInfo
     * Retrieves credit notes as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCreditNoteAsPdfAsyncWithHttpInfo($xero_tenant_id, $credit_note_id)
    {
        $returnType = '\SplFileObject';
        $request = $this->getCreditNoteAsPdfRequest($xero_tenant_id, $credit_note_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCreditNoteAsPdf'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCreditNoteAsPdfRequest($xero_tenant_id, $credit_note_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCreditNoteAsPdf'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling getCreditNoteAsPdf'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/pdf']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/pdf'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCreditNoteAttachmentByFileName
     * Retrieves a specific attachment on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getCreditNoteAttachmentByFileName($xero_tenant_id, $credit_note_id, $file_name, $content_type)
    {
        list($response) = $this->getCreditNoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getCreditNoteAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCreditNoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $content_type)
    {
        $request = $this->getCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCreditNoteAttachmentByFileNameAsync
     * Retrieves a specific attachment on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCreditNoteAttachmentByFileNameAsync($xero_tenant_id, $credit_note_id, $file_name, $content_type)
    {
        return $this->getCreditNoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCreditNoteAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCreditNoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCreditNoteAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling getCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getCreditNoteAttachmentByFileName'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCreditNoteAttachmentById
     * Retrieves a specific attachment from a specific credit note using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getCreditNoteAttachmentById($xero_tenant_id, $credit_note_id, $attachment_id, $content_type)
    {
        list($response) = $this->getCreditNoteAttachmentByIdWithHttpInfo($xero_tenant_id, $credit_note_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getCreditNoteAttachmentByIdWithHttpInfo
     * Retrieves a specific attachment from a specific credit note using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCreditNoteAttachmentByIdWithHttpInfo($xero_tenant_id, $credit_note_id, $attachment_id, $content_type)
    {
        $request = $this->getCreditNoteAttachmentByIdRequest($xero_tenant_id, $credit_note_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCreditNoteAttachmentByIdAsync
     * Retrieves a specific attachment from a specific credit note using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCreditNoteAttachmentByIdAsync($xero_tenant_id, $credit_note_id, $attachment_id, $content_type)
    {
        return $this->getCreditNoteAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCreditNoteAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific credit note using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCreditNoteAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getCreditNoteAttachmentByIdRequest($xero_tenant_id, $credit_note_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCreditNoteAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCreditNoteAttachmentByIdRequest($xero_tenant_id, $credit_note_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCreditNoteAttachmentById'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling getCreditNoteAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getCreditNoteAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getCreditNoteAttachmentById'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCreditNoteAttachments
     * Retrieves attachments for a specific credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getCreditNoteAttachments($xero_tenant_id, $credit_note_id)
    {
        list($response) = $this->getCreditNoteAttachmentsWithHttpInfo($xero_tenant_id, $credit_note_id);
        return $response;
    }
    /**
     * Operation getCreditNoteAttachmentsWithHttpInfo
     * Retrieves attachments for a specific credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCreditNoteAttachmentsWithHttpInfo($xero_tenant_id, $credit_note_id)
    {
        $request = $this->getCreditNoteAttachmentsRequest($xero_tenant_id, $credit_note_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCreditNoteAttachmentsAsync
     * Retrieves attachments for a specific credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCreditNoteAttachmentsAsync($xero_tenant_id, $credit_note_id)
    {
        return $this->getCreditNoteAttachmentsAsyncWithHttpInfo($xero_tenant_id, $credit_note_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCreditNoteAttachmentsAsyncWithHttpInfo
     * Retrieves attachments for a specific credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCreditNoteAttachmentsAsyncWithHttpInfo($xero_tenant_id, $credit_note_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getCreditNoteAttachmentsRequest($xero_tenant_id, $credit_note_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCreditNoteAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCreditNoteAttachmentsRequest($xero_tenant_id, $credit_note_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCreditNoteAttachments'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling getCreditNoteAttachments'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCreditNoteHistory
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getCreditNoteHistory($xero_tenant_id, $credit_note_id)
    {
        list($response) = $this->getCreditNoteHistoryWithHttpInfo($xero_tenant_id, $credit_note_id);
        return $response;
    }
    /**
     * Operation getCreditNoteHistoryWithHttpInfo
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCreditNoteHistoryWithHttpInfo($xero_tenant_id, $credit_note_id)
    {
        $request = $this->getCreditNoteHistoryRequest($xero_tenant_id, $credit_note_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCreditNoteHistoryAsync
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCreditNoteHistoryAsync($xero_tenant_id, $credit_note_id)
    {
        return $this->getCreditNoteHistoryAsyncWithHttpInfo($xero_tenant_id, $credit_note_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCreditNoteHistoryAsyncWithHttpInfo
     * Retrieves history records of a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCreditNoteHistoryAsyncWithHttpInfo($xero_tenant_id, $credit_note_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getCreditNoteHistoryRequest($xero_tenant_id, $credit_note_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCreditNoteHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCreditNoteHistoryRequest($xero_tenant_id, $credit_note_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCreditNoteHistory'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling getCreditNoteHistory'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCreditNotes
     * Retrieves any credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 credit notes will be returned in a single API call with line items shown for each credit note (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\CreditNotes
     */
    public function getCreditNotes($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        list($response) = $this->getCreditNotesWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $response;
    }
    /**
     * Operation getCreditNotesWithHttpInfo
     * Retrieves any credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 credit notes will be returned in a single API call with line items shown for each credit note (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\CreditNotes, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCreditNotesWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $request = $this->getCreditNotesRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\CreditNotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCreditNotesAsync
     * Retrieves any credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 credit notes will be returned in a single API call with line items shown for each credit note (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCreditNotesAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        return $this->getCreditNotesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCreditNotesAsyncWithHttpInfo
     * Retrieves any credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 credit notes will be returned in a single API call with line items shown for each credit note (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCreditNotesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
        $request = $this->getCreditNotesRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCreditNotes'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 credit notes will be returned in a single API call with line items shown for each credit note (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCreditNotesRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCreditNotes'
            );
        }
        $resourcePath = '/CreditNotes';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getCurrencies
     * Retrieves currencies for your Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Currencies
     */
    public function getCurrencies($xero_tenant_id, $where = null, $order = null)
    {
        list($response) = $this->getCurrenciesWithHttpInfo($xero_tenant_id, $where, $order);
        return $response;
    }
    /**
     * Operation getCurrenciesWithHttpInfo
     * Retrieves currencies for your Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Currencies, HTTP status code, HTTP response headers (array of strings)
     */
    public function getCurrenciesWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $request = $this->getCurrenciesRequest($xero_tenant_id, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Currencies' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Currencies', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Currencies';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Currencies',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getCurrenciesAsync
     * Retrieves currencies for your Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getCurrenciesAsync($xero_tenant_id, $where = null, $order = null)
    {
        return $this->getCurrenciesAsyncWithHttpInfo($xero_tenant_id, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getCurrenciesAsyncWithHttpInfo
     * Retrieves currencies for your Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getCurrenciesAsyncWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Currencies';
        $request = $this->getCurrenciesRequest($xero_tenant_id, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getCurrencies'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getCurrenciesRequest($xero_tenant_id, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getCurrencies'
            );
        }
        $resourcePath = '/Currencies';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getEmployee
     * Retrieves a specific employee used in Xero payrun using a unique employee Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $employee_id Unique identifier for a Employee (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Employees
     */
    public function getEmployee($xero_tenant_id, $employee_id)
    {
        list($response) = $this->getEmployeeWithHttpInfo($xero_tenant_id, $employee_id);
        return $response;
    }
    /**
     * Operation getEmployeeWithHttpInfo
     * Retrieves a specific employee used in Xero payrun using a unique employee Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $employee_id Unique identifier for a Employee (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Employees, HTTP status code, HTTP response headers (array of strings)
     */
    public function getEmployeeWithHttpInfo($xero_tenant_id, $employee_id)
    {
        $request = $this->getEmployeeRequest($xero_tenant_id, $employee_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Employees' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Employees', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Employees',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getEmployeeAsync
     * Retrieves a specific employee used in Xero payrun using a unique employee Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $employee_id Unique identifier for a Employee (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getEmployeeAsync($xero_tenant_id, $employee_id)
    {
        return $this->getEmployeeAsyncWithHttpInfo($xero_tenant_id, $employee_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getEmployeeAsyncWithHttpInfo
     * Retrieves a specific employee used in Xero payrun using a unique employee Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $employee_id Unique identifier for a Employee (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getEmployeeAsyncWithHttpInfo($xero_tenant_id, $employee_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
        $request = $this->getEmployeeRequest($xero_tenant_id, $employee_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getEmployee'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $employee_id Unique identifier for a Employee (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getEmployeeRequest($xero_tenant_id, $employee_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getEmployee'
            );
        }
        // verify the required parameter 'employee_id' is set
        if ($employee_id === null || (is_array($employee_id) && count($employee_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $employee_id when calling getEmployee'
            );
        }
        $resourcePath = '/Employees/{EmployeeID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($employee_id !== null) {
            $resourcePath = str_replace(
                '{' . 'EmployeeID' . '}',
                AccountingObjectSerializer::toPathValue($employee_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getEmployees
     * Retrieves employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Employees
     */
    public function getEmployees($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        list($response) = $this->getEmployeesWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order);
        return $response;
    }
    /**
     * Operation getEmployeesWithHttpInfo
     * Retrieves employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Employees, HTTP status code, HTTP response headers (array of strings)
     */
    public function getEmployeesWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $request = $this->getEmployeesRequest($xero_tenant_id, $if_modified_since, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Employees' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Employees', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Employees',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getEmployeesAsync
     * Retrieves employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getEmployeesAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        return $this->getEmployeesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getEmployeesAsyncWithHttpInfo
     * Retrieves employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getEmployeesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
        $request = $this->getEmployeesRequest($xero_tenant_id, $if_modified_since, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getEmployees'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getEmployeesRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getEmployees'
            );
        }
        $resourcePath = '/Employees';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getExpenseClaim
     * Retrieves a specific expense claim using a unique expense claim Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims
     */
    public function getExpenseClaim($xero_tenant_id, $expense_claim_id)
    {
        list($response) = $this->getExpenseClaimWithHttpInfo($xero_tenant_id, $expense_claim_id);
        return $response;
    }
    /**
     * Operation getExpenseClaimWithHttpInfo
     * Retrieves a specific expense claim using a unique expense claim Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims, HTTP status code, HTTP response headers (array of strings)
     */
    public function getExpenseClaimWithHttpInfo($xero_tenant_id, $expense_claim_id)
    {
        $request = $this->getExpenseClaimRequest($xero_tenant_id, $expense_claim_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getExpenseClaimAsync
     * Retrieves a specific expense claim using a unique expense claim Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getExpenseClaimAsync($xero_tenant_id, $expense_claim_id)
    {
        return $this->getExpenseClaimAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getExpenseClaimAsyncWithHttpInfo
     * Retrieves a specific expense claim using a unique expense claim Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getExpenseClaimAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
        $request = $this->getExpenseClaimRequest($xero_tenant_id, $expense_claim_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getExpenseClaim'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getExpenseClaimRequest($xero_tenant_id, $expense_claim_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getExpenseClaim'
            );
        }
        // verify the required parameter 'expense_claim_id' is set
        if ($expense_claim_id === null || (is_array($expense_claim_id) && count($expense_claim_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $expense_claim_id when calling getExpenseClaim'
            );
        }
        $resourcePath = '/ExpenseClaims/{ExpenseClaimID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($expense_claim_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ExpenseClaimID' . '}',
                AccountingObjectSerializer::toPathValue($expense_claim_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getExpenseClaimHistory
     * Retrieves history records of a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getExpenseClaimHistory($xero_tenant_id, $expense_claim_id)
    {
        list($response) = $this->getExpenseClaimHistoryWithHttpInfo($xero_tenant_id, $expense_claim_id);
        return $response;
    }
    /**
     * Operation getExpenseClaimHistoryWithHttpInfo
     * Retrieves history records of a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getExpenseClaimHistoryWithHttpInfo($xero_tenant_id, $expense_claim_id)
    {
        $request = $this->getExpenseClaimHistoryRequest($xero_tenant_id, $expense_claim_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getExpenseClaimHistoryAsync
     * Retrieves history records of a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getExpenseClaimHistoryAsync($xero_tenant_id, $expense_claim_id)
    {
        return $this->getExpenseClaimHistoryAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getExpenseClaimHistoryAsyncWithHttpInfo
     * Retrieves history records of a specific expense claim
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getExpenseClaimHistoryAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getExpenseClaimHistoryRequest($xero_tenant_id, $expense_claim_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getExpenseClaimHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getExpenseClaimHistoryRequest($xero_tenant_id, $expense_claim_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getExpenseClaimHistory'
            );
        }
        // verify the required parameter 'expense_claim_id' is set
        if ($expense_claim_id === null || (is_array($expense_claim_id) && count($expense_claim_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $expense_claim_id when calling getExpenseClaimHistory'
            );
        }
        $resourcePath = '/ExpenseClaims/{ExpenseClaimID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($expense_claim_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ExpenseClaimID' . '}',
                AccountingObjectSerializer::toPathValue($expense_claim_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getExpenseClaims
     * Retrieves expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims
     */
    public function getExpenseClaims($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        list($response) = $this->getExpenseClaimsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order);
        return $response;
    }
    /**
     * Operation getExpenseClaimsWithHttpInfo
     * Retrieves expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims, HTTP status code, HTTP response headers (array of strings)
     */
    public function getExpenseClaimsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $request = $this->getExpenseClaimsRequest($xero_tenant_id, $if_modified_since, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getExpenseClaimsAsync
     * Retrieves expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getExpenseClaimsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        return $this->getExpenseClaimsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getExpenseClaimsAsyncWithHttpInfo
     * Retrieves expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getExpenseClaimsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
        $request = $this->getExpenseClaimsRequest($xero_tenant_id, $if_modified_since, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getExpenseClaims'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getExpenseClaimsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getExpenseClaims'
            );
        }
        $resourcePath = '/ExpenseClaims';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoice
     * Retrieves a specific sales invoice or purchase bill using a unique invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Invoices
     */
    public function getInvoice($xero_tenant_id, $invoice_id, $unitdp = null)
    {
        list($response) = $this->getInvoiceWithHttpInfo($xero_tenant_id, $invoice_id, $unitdp);
        return $response;
    }
    /**
     * Operation getInvoiceWithHttpInfo
     * Retrieves a specific sales invoice or purchase bill using a unique invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Invoices, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoiceWithHttpInfo($xero_tenant_id, $invoice_id, $unitdp = null)
    {
        $request = $this->getInvoiceRequest($xero_tenant_id, $invoice_id, $unitdp);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Invoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Invoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Invoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoiceAsync
     * Retrieves a specific sales invoice or purchase bill using a unique invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoiceAsync($xero_tenant_id, $invoice_id, $unitdp = null)
    {
        return $this->getInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $unitdp)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoiceAsyncWithHttpInfo
     * Retrieves a specific sales invoice or purchase bill using a unique invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $unitdp = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
        $request = $this->getInvoiceRequest($xero_tenant_id, $invoice_id, $unitdp);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoice'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoiceRequest($xero_tenant_id, $invoice_id, $unitdp = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoice'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling getInvoice'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoiceAsPdf
     * Retrieves invoices or purchase bills as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getInvoiceAsPdf($xero_tenant_id, $invoice_id)
    {
        list($response) = $this->getInvoiceAsPdfWithHttpInfo($xero_tenant_id, $invoice_id);
        return $response;
    }
    /**
     * Operation getInvoiceAsPdfWithHttpInfo
     * Retrieves invoices or purchase bills as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoiceAsPdfWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $request = $this->getInvoiceAsPdfRequest($xero_tenant_id, $invoice_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoiceAsPdfAsync
     * Retrieves invoices or purchase bills as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoiceAsPdfAsync($xero_tenant_id, $invoice_id)
    {
        return $this->getInvoiceAsPdfAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoiceAsPdfAsyncWithHttpInfo
     * Retrieves invoices or purchase bills as PDF files
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoiceAsPdfAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $returnType = '\SplFileObject';
        $request = $this->getInvoiceAsPdfRequest($xero_tenant_id, $invoice_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoiceAsPdf'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoiceAsPdfRequest($xero_tenant_id, $invoice_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoiceAsPdf'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling getInvoiceAsPdf'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/pdf']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/pdf'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoiceAttachmentByFileName
     * Retrieves an attachment from a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getInvoiceAttachmentByFileName($xero_tenant_id, $invoice_id, $file_name, $content_type)
    {
        list($response) = $this->getInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getInvoiceAttachmentByFileNameWithHttpInfo
     * Retrieves an attachment from a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $content_type)
    {
        $request = $this->getInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoiceAttachmentByFileNameAsync
     * Retrieves an attachment from a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoiceAttachmentByFileNameAsync($xero_tenant_id, $invoice_id, $file_name, $content_type)
    {
        return $this->getInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoiceAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves an attachment from a specific invoice or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoiceAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling getInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getInvoiceAttachmentByFileName'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoiceAttachmentById
     * Retrieves a specific attachment from a specific invoices or purchase bills by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getInvoiceAttachmentById($xero_tenant_id, $invoice_id, $attachment_id, $content_type)
    {
        list($response) = $this->getInvoiceAttachmentByIdWithHttpInfo($xero_tenant_id, $invoice_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getInvoiceAttachmentByIdWithHttpInfo
     * Retrieves a specific attachment from a specific invoices or purchase bills by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoiceAttachmentByIdWithHttpInfo($xero_tenant_id, $invoice_id, $attachment_id, $content_type)
    {
        $request = $this->getInvoiceAttachmentByIdRequest($xero_tenant_id, $invoice_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoiceAttachmentByIdAsync
     * Retrieves a specific attachment from a specific invoices or purchase bills by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoiceAttachmentByIdAsync($xero_tenant_id, $invoice_id, $attachment_id, $content_type)
    {
        return $this->getInvoiceAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoiceAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific invoices or purchase bills by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoiceAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getInvoiceAttachmentByIdRequest($xero_tenant_id, $invoice_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoiceAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoiceAttachmentByIdRequest($xero_tenant_id, $invoice_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoiceAttachmentById'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling getInvoiceAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getInvoiceAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getInvoiceAttachmentById'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoiceAttachments
     * Retrieves attachments for a specific invoice or purchase bill
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getInvoiceAttachments($xero_tenant_id, $invoice_id)
    {
        list($response) = $this->getInvoiceAttachmentsWithHttpInfo($xero_tenant_id, $invoice_id);
        return $response;
    }
    /**
     * Operation getInvoiceAttachmentsWithHttpInfo
     * Retrieves attachments for a specific invoice or purchase bill
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoiceAttachmentsWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $request = $this->getInvoiceAttachmentsRequest($xero_tenant_id, $invoice_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoiceAttachmentsAsync
     * Retrieves attachments for a specific invoice or purchase bill
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoiceAttachmentsAsync($xero_tenant_id, $invoice_id)
    {
        return $this->getInvoiceAttachmentsAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoiceAttachmentsAsyncWithHttpInfo
     * Retrieves attachments for a specific invoice or purchase bill
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoiceAttachmentsAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getInvoiceAttachmentsRequest($xero_tenant_id, $invoice_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoiceAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoiceAttachmentsRequest($xero_tenant_id, $invoice_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoiceAttachments'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling getInvoiceAttachments'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoiceHistory
     * Retrieves history records for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getInvoiceHistory($xero_tenant_id, $invoice_id)
    {
        list($response) = $this->getInvoiceHistoryWithHttpInfo($xero_tenant_id, $invoice_id);
        return $response;
    }
    /**
     * Operation getInvoiceHistoryWithHttpInfo
     * Retrieves history records for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoiceHistoryWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $request = $this->getInvoiceHistoryRequest($xero_tenant_id, $invoice_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoiceHistoryAsync
     * Retrieves history records for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoiceHistoryAsync($xero_tenant_id, $invoice_id)
    {
        return $this->getInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoiceHistoryAsyncWithHttpInfo
     * Retrieves history records for a specific invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getInvoiceHistoryRequest($xero_tenant_id, $invoice_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoiceHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoiceHistoryRequest($xero_tenant_id, $invoice_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoiceHistory'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling getInvoiceHistory'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoiceReminders
     * Retrieves invoice reminder settings
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\InvoiceReminders
     */
    public function getInvoiceReminders($xero_tenant_id)
    {
        list($response) = $this->getInvoiceRemindersWithHttpInfo($xero_tenant_id);
        return $response;
    }
    /**
     * Operation getInvoiceRemindersWithHttpInfo
     * Retrieves invoice reminder settings
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\InvoiceReminders, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoiceRemindersWithHttpInfo($xero_tenant_id)
    {
        $request = $this->getInvoiceRemindersRequest($xero_tenant_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\InvoiceReminders' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\InvoiceReminders', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\InvoiceReminders';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\InvoiceReminders',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoiceRemindersAsync
     * Retrieves invoice reminder settings
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoiceRemindersAsync($xero_tenant_id)
    {
        return $this->getInvoiceRemindersAsyncWithHttpInfo($xero_tenant_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoiceRemindersAsyncWithHttpInfo
     * Retrieves invoice reminder settings
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoiceRemindersAsyncWithHttpInfo($xero_tenant_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\InvoiceReminders';
        $request = $this->getInvoiceRemindersRequest($xero_tenant_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoiceReminders'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoiceRemindersRequest($xero_tenant_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoiceReminders'
            );
        }
        $resourcePath = '/InvoiceReminders/Settings';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getInvoices
     * Retrieves sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma-separated list of InvoicesIDs. (optional)
     * @param  string[] $invoice_numbers Filter by a comma-separated list of InvoiceNumbers. (optional)
     * @param  string[] $contact_ids Filter by a comma-separated list of ContactIDs. (optional)
     * @param  string[] $statuses Filter by a comma-separated list Statuses. For faster response times we recommend using these explicit parameters instead of passing OR conditions into the Where filter. (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 invoices will be returned in a single API call with line items shown for each invoice (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Invoices with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $created_by_my_app When set to true you&#39;ll only retrieve Invoices created by your app (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the fields e.g. InvoiceNumber, Reference. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Invoices
     */
    public function getInvoices($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $invoice_numbers = null, $contact_ids = null, $statuses = null, $page = null, $include_archived = null, $created_by_my_app = null, $unitdp = null, $summary_only = false, $page_size = null, $search_term = null)
    {
        list($response) = $this->getInvoicesWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $ids, $invoice_numbers, $contact_ids, $statuses, $page, $include_archived, $created_by_my_app, $unitdp, $summary_only, $page_size, $search_term);
        return $response;
    }
    /**
     * Operation getInvoicesWithHttpInfo
     * Retrieves sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma-separated list of InvoicesIDs. (optional)
     * @param  string[] $invoice_numbers Filter by a comma-separated list of InvoiceNumbers. (optional)
     * @param  string[] $contact_ids Filter by a comma-separated list of ContactIDs. (optional)
     * @param  string[] $statuses Filter by a comma-separated list Statuses. For faster response times we recommend using these explicit parameters instead of passing OR conditions into the Where filter. (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 invoices will be returned in a single API call with line items shown for each invoice (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Invoices with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $created_by_my_app When set to true you&#39;ll only retrieve Invoices created by your app (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the fields e.g. InvoiceNumber, Reference. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Invoices, HTTP status code, HTTP response headers (array of strings)
     */
    public function getInvoicesWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $invoice_numbers = null, $contact_ids = null, $statuses = null, $page = null, $include_archived = null, $created_by_my_app = null, $unitdp = null, $summary_only = false, $page_size = null, $search_term = null)
    {
        $request = $this->getInvoicesRequest($xero_tenant_id, $if_modified_since, $where, $order, $ids, $invoice_numbers, $contact_ids, $statuses, $page, $include_archived, $created_by_my_app, $unitdp, $summary_only, $page_size, $search_term);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Invoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Invoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Invoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getInvoicesAsync
     * Retrieves sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma-separated list of InvoicesIDs. (optional)
     * @param  string[] $invoice_numbers Filter by a comma-separated list of InvoiceNumbers. (optional)
     * @param  string[] $contact_ids Filter by a comma-separated list of ContactIDs. (optional)
     * @param  string[] $statuses Filter by a comma-separated list Statuses. For faster response times we recommend using these explicit parameters instead of passing OR conditions into the Where filter. (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 invoices will be returned in a single API call with line items shown for each invoice (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Invoices with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $created_by_my_app When set to true you&#39;ll only retrieve Invoices created by your app (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the fields e.g. InvoiceNumber, Reference. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getInvoicesAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $invoice_numbers = null, $contact_ids = null, $statuses = null, $page = null, $include_archived = null, $created_by_my_app = null, $unitdp = null, $summary_only = false, $page_size = null, $search_term = null)
    {
        return $this->getInvoicesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $ids, $invoice_numbers, $contact_ids, $statuses, $page, $include_archived, $created_by_my_app, $unitdp, $summary_only, $page_size, $search_term)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getInvoicesAsyncWithHttpInfo
     * Retrieves sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma-separated list of InvoicesIDs. (optional)
     * @param  string[] $invoice_numbers Filter by a comma-separated list of InvoiceNumbers. (optional)
     * @param  string[] $contact_ids Filter by a comma-separated list of ContactIDs. (optional)
     * @param  string[] $statuses Filter by a comma-separated list Statuses. For faster response times we recommend using these explicit parameters instead of passing OR conditions into the Where filter. (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 invoices will be returned in a single API call with line items shown for each invoice (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Invoices with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $created_by_my_app When set to true you&#39;ll only retrieve Invoices created by your app (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the fields e.g. InvoiceNumber, Reference. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getInvoicesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $invoice_numbers = null, $contact_ids = null, $statuses = null, $page = null, $include_archived = null, $created_by_my_app = null, $unitdp = null, $summary_only = false, $page_size = null, $search_term = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
        $request = $this->getInvoicesRequest($xero_tenant_id, $if_modified_since, $where, $order, $ids, $invoice_numbers, $contact_ids, $statuses, $page, $include_archived, $created_by_my_app, $unitdp, $summary_only, $page_size, $search_term);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getInvoices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string[] $ids Filter by a comma-separated list of InvoicesIDs. (optional)
     * @param  string[] $invoice_numbers Filter by a comma-separated list of InvoiceNumbers. (optional)
     * @param  string[] $contact_ids Filter by a comma-separated list of ContactIDs. (optional)
     * @param  string[] $statuses Filter by a comma-separated list Statuses. For faster response times we recommend using these explicit parameters instead of passing OR conditions into the Where filter. (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 invoices will be returned in a single API call with line items shown for each invoice (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Invoices with a status of ARCHIVED will be included in the response (optional)
     * @param  bool $created_by_my_app When set to true you&#39;ll only retrieve Invoices created by your app (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  bool $summary_only Use summaryOnly&#x3D;true in GET Contacts and Invoices endpoint to retrieve a smaller version of the response object. This returns only lightweight fields, excluding computation-heavy fields from the response, making the API calls quick and efficient. (optional, default to false)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @param  string $search_term Search parameter that performs a case-insensitive text search across the fields e.g. InvoiceNumber, Reference. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getInvoicesRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $ids = null, $invoice_numbers = null, $contact_ids = null, $statuses = null, $page = null, $include_archived = null, $created_by_my_app = null, $unitdp = null, $summary_only = false, $page_size = null, $search_term = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getInvoices'
            );
        }
        $resourcePath = '/Invoices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if (is_array($ids)) {
            $ids = AccountingObjectSerializer::serializeCollection($ids, 'csv', true);
        }
        if ($ids !== null) {
            $queryParams['IDs'] = AccountingObjectSerializer::toQueryValue($ids);
        }
        // query params
        if (is_array($invoice_numbers)) {
            $invoice_numbers = AccountingObjectSerializer::serializeCollection($invoice_numbers, 'csv', true);
        }
        if ($invoice_numbers !== null) {
            $queryParams['InvoiceNumbers'] = AccountingObjectSerializer::toQueryValue($invoice_numbers);
        }
        // query params
        if (is_array($contact_ids)) {
            $contact_ids = AccountingObjectSerializer::serializeCollection($contact_ids, 'csv', true);
        }
        if ($contact_ids !== null) {
            $queryParams['ContactIDs'] = AccountingObjectSerializer::toQueryValue($contact_ids);
        }
        // query params
        if (is_array($statuses)) {
            $statuses = AccountingObjectSerializer::serializeCollection($statuses, 'csv', true);
        }
        if ($statuses !== null) {
            $queryParams['Statuses'] = AccountingObjectSerializer::toQueryValue($statuses);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($include_archived !== null) {
            $queryParams['includeArchived'] = $include_archived ? 'true' : 'false';
        }
        // query params
        if ($created_by_my_app !== null) {
            $queryParams['createdByMyApp'] = $created_by_my_app ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // query params
        if ($summary_only !== null) {
            $queryParams['summaryOnly'] = $summary_only ? 'true' : 'false';
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // query params
        if ($search_term !== null) {
            $queryParams['searchTerm'] = AccountingObjectSerializer::toQueryValue($search_term);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getItem
     * Retrieves a specific item using a unique item Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Items
     */
    public function getItem($xero_tenant_id, $item_id, $unitdp = null)
    {
        list($response) = $this->getItemWithHttpInfo($xero_tenant_id, $item_id, $unitdp);
        return $response;
    }
    /**
     * Operation getItemWithHttpInfo
     * Retrieves a specific item using a unique item Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Items, HTTP status code, HTTP response headers (array of strings)
     */
    public function getItemWithHttpInfo($xero_tenant_id, $item_id, $unitdp = null)
    {
        $request = $this->getItemRequest($xero_tenant_id, $item_id, $unitdp);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Items' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Items', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Items',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getItemAsync
     * Retrieves a specific item using a unique item Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getItemAsync($xero_tenant_id, $item_id, $unitdp = null)
    {
        return $this->getItemAsyncWithHttpInfo($xero_tenant_id, $item_id, $unitdp)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getItemAsyncWithHttpInfo
     * Retrieves a specific item using a unique item Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getItemAsyncWithHttpInfo($xero_tenant_id, $item_id, $unitdp = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
        $request = $this->getItemRequest($xero_tenant_id, $item_id, $unitdp);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getItem'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getItemRequest($xero_tenant_id, $item_id, $unitdp = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getItem'
            );
        }
        // verify the required parameter 'item_id' is set
        if ($item_id === null || (is_array($item_id) && count($item_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $item_id when calling getItem'
            );
        }
        $resourcePath = '/Items/{ItemID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($item_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ItemID' . '}',
                AccountingObjectSerializer::toPathValue($item_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getItemHistory
     * Retrieves history for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getItemHistory($xero_tenant_id, $item_id)
    {
        list($response) = $this->getItemHistoryWithHttpInfo($xero_tenant_id, $item_id);
        return $response;
    }
    /**
     * Operation getItemHistoryWithHttpInfo
     * Retrieves history for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getItemHistoryWithHttpInfo($xero_tenant_id, $item_id)
    {
        $request = $this->getItemHistoryRequest($xero_tenant_id, $item_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getItemHistoryAsync
     * Retrieves history for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getItemHistoryAsync($xero_tenant_id, $item_id)
    {
        return $this->getItemHistoryAsyncWithHttpInfo($xero_tenant_id, $item_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getItemHistoryAsyncWithHttpInfo
     * Retrieves history for a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getItemHistoryAsyncWithHttpInfo($xero_tenant_id, $item_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getItemHistoryRequest($xero_tenant_id, $item_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getItemHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getItemHistoryRequest($xero_tenant_id, $item_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getItemHistory'
            );
        }
        // verify the required parameter 'item_id' is set
        if ($item_id === null || (is_array($item_id) && count($item_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $item_id when calling getItemHistory'
            );
        }
        $resourcePath = '/Items/{ItemID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($item_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ItemID' . '}',
                AccountingObjectSerializer::toPathValue($item_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getItems
     * Retrieves items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Items
     */
    public function getItems($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        list($response) = $this->getItemsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $unitdp);
        return $response;
    }
    /**
     * Operation getItemsWithHttpInfo
     * Retrieves items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Items, HTTP status code, HTTP response headers (array of strings)
     */
    public function getItemsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        $request = $this->getItemsRequest($xero_tenant_id, $if_modified_since, $where, $order, $unitdp);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Items' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Items', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Items',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getItemsAsync
     * Retrieves items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getItemsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        return $this->getItemsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $unitdp)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getItemsAsyncWithHttpInfo
     * Retrieves items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getItemsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
        $request = $this->getItemsRequest($xero_tenant_id, $if_modified_since, $where, $order, $unitdp);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getItems'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getItemsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getItems'
            );
        }
        $resourcePath = '/Items';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getJournal
     * Retrieves a specific journal using a unique journal Id.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $journal_id Unique identifier for a Journal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Journals
     */
    public function getJournal($xero_tenant_id, $journal_id)
    {
        list($response) = $this->getJournalWithHttpInfo($xero_tenant_id, $journal_id);
        return $response;
    }
    /**
     * Operation getJournalWithHttpInfo
     * Retrieves a specific journal using a unique journal Id.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $journal_id Unique identifier for a Journal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Journals, HTTP status code, HTTP response headers (array of strings)
     */
    public function getJournalWithHttpInfo($xero_tenant_id, $journal_id)
    {
        $request = $this->getJournalRequest($xero_tenant_id, $journal_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Journals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Journals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Journals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Journals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getJournalAsync
     * Retrieves a specific journal using a unique journal Id.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $journal_id Unique identifier for a Journal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getJournalAsync($xero_tenant_id, $journal_id)
    {
        return $this->getJournalAsyncWithHttpInfo($xero_tenant_id, $journal_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getJournalAsyncWithHttpInfo
     * Retrieves a specific journal using a unique journal Id.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $journal_id Unique identifier for a Journal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getJournalAsyncWithHttpInfo($xero_tenant_id, $journal_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Journals';
        $request = $this->getJournalRequest($xero_tenant_id, $journal_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getJournal'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $journal_id Unique identifier for a Journal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getJournalRequest($xero_tenant_id, $journal_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getJournal'
            );
        }
        // verify the required parameter 'journal_id' is set
        if ($journal_id === null || (is_array($journal_id) && count($journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $journal_id when calling getJournal'
            );
        }
        $resourcePath = '/Journals/{JournalID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'JournalID' . '}',
                AccountingObjectSerializer::toPathValue($journal_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getJournalByNumber
     * Retrieves a specific journal using a unique journal number.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $journal_number Number of a Journal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Journals
     */
    public function getJournalByNumber($xero_tenant_id, $journal_number)
    {
        list($response) = $this->getJournalByNumberWithHttpInfo($xero_tenant_id, $journal_number);
        return $response;
    }
    /**
     * Operation getJournalByNumberWithHttpInfo
     * Retrieves a specific journal using a unique journal number.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $journal_number Number of a Journal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Journals, HTTP status code, HTTP response headers (array of strings)
     */
    public function getJournalByNumberWithHttpInfo($xero_tenant_id, $journal_number)
    {
        $request = $this->getJournalByNumberRequest($xero_tenant_id, $journal_number);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Journals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Journals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Journals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Journals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getJournalByNumberAsync
     * Retrieves a specific journal using a unique journal number.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $journal_number Number of a Journal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getJournalByNumberAsync($xero_tenant_id, $journal_number)
    {
        return $this->getJournalByNumberAsyncWithHttpInfo($xero_tenant_id, $journal_number)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getJournalByNumberAsyncWithHttpInfo
     * Retrieves a specific journal using a unique journal number.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $journal_number Number of a Journal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getJournalByNumberAsyncWithHttpInfo($xero_tenant_id, $journal_number)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Journals';
        $request = $this->getJournalByNumberRequest($xero_tenant_id, $journal_number);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getJournalByNumber'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $journal_number Number of a Journal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getJournalByNumberRequest($xero_tenant_id, $journal_number)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getJournalByNumber'
            );
        }
        // verify the required parameter 'journal_number' is set
        if ($journal_number === null || (is_array($journal_number) && count($journal_number) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $journal_number when calling getJournalByNumber'
            );
        }
        $resourcePath = '/Journals/{JournalNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($journal_number !== null) {
            $resourcePath = str_replace(
                '{' . 'JournalNumber' . '}',
                AccountingObjectSerializer::toPathValue($journal_number),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getJournals
     * Retrieves journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  int $offset Offset by a specified journal number. e.g. journals with a JournalNumber greater than the offset will be returned (optional)
     * @param  bool $payments_only Filter to retrieve journals on a cash basis. Journals are returned on an accrual basis by default. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Journals
     */
    public function getJournals($xero_tenant_id, $if_modified_since = null, $offset = null, $payments_only = null)
    {
        list($response) = $this->getJournalsWithHttpInfo($xero_tenant_id, $if_modified_since, $offset, $payments_only);
        return $response;
    }
    /**
     * Operation getJournalsWithHttpInfo
     * Retrieves journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  int $offset Offset by a specified journal number. e.g. journals with a JournalNumber greater than the offset will be returned (optional)
     * @param  bool $payments_only Filter to retrieve journals on a cash basis. Journals are returned on an accrual basis by default. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Journals, HTTP status code, HTTP response headers (array of strings)
     */
    public function getJournalsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $offset = null, $payments_only = null)
    {
        $request = $this->getJournalsRequest($xero_tenant_id, $if_modified_since, $offset, $payments_only);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Journals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Journals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Journals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Journals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getJournalsAsync
     * Retrieves journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  int $offset Offset by a specified journal number. e.g. journals with a JournalNumber greater than the offset will be returned (optional)
     * @param  bool $payments_only Filter to retrieve journals on a cash basis. Journals are returned on an accrual basis by default. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getJournalsAsync($xero_tenant_id, $if_modified_since = null, $offset = null, $payments_only = null)
    {
        return $this->getJournalsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $offset, $payments_only)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getJournalsAsyncWithHttpInfo
     * Retrieves journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  int $offset Offset by a specified journal number. e.g. journals with a JournalNumber greater than the offset will be returned (optional)
     * @param  bool $payments_only Filter to retrieve journals on a cash basis. Journals are returned on an accrual basis by default. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getJournalsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $offset = null, $payments_only = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Journals';
        $request = $this->getJournalsRequest($xero_tenant_id, $if_modified_since, $offset, $payments_only);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getJournals'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  int $offset Offset by a specified journal number. e.g. journals with a JournalNumber greater than the offset will be returned (optional)
     * @param  bool $payments_only Filter to retrieve journals on a cash basis. Journals are returned on an accrual basis by default. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getJournalsRequest($xero_tenant_id, $if_modified_since = null, $offset = null, $payments_only = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getJournals'
            );
        }
        $resourcePath = '/Journals';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($offset !== null) {
            $queryParams['offset'] = AccountingObjectSerializer::toQueryValue($offset);
        }
        // query params
        if ($payments_only !== null) {
            $queryParams['paymentsOnly'] = $payments_only ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getLinkedTransaction
     * Retrieves a specific linked transaction (billable expenses) using a unique linked transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions
     */
    public function getLinkedTransaction($xero_tenant_id, $linked_transaction_id)
    {
        list($response) = $this->getLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction_id);
        return $response;
    }
    /**
     * Operation getLinkedTransactionWithHttpInfo
     * Retrieves a specific linked transaction (billable expenses) using a unique linked transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions, HTTP status code, HTTP response headers (array of strings)
     */
    public function getLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction_id)
    {
        $request = $this->getLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getLinkedTransactionAsync
     * Retrieves a specific linked transaction (billable expenses) using a unique linked transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getLinkedTransactionAsync($xero_tenant_id, $linked_transaction_id)
    {
        return $this->getLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getLinkedTransactionAsyncWithHttpInfo
     * Retrieves a specific linked transaction (billable expenses) using a unique linked transaction Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
        $request = $this->getLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getLinkedTransaction'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getLinkedTransaction'
            );
        }
        // verify the required parameter 'linked_transaction_id' is set
        if ($linked_transaction_id === null || (is_array($linked_transaction_id) && count($linked_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $linked_transaction_id when calling getLinkedTransaction'
            );
        }
        $resourcePath = '/LinkedTransactions/{LinkedTransactionID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($linked_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'LinkedTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($linked_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getLinkedTransactions
     * Retrieves linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $page Up to 100 linked transactions will be returned in a single API call. Use the page parameter to specify the page to be returned e.g. page&#x3D;1. (optional)
     * @param  string $linked_transaction_id The Xero identifier for an Linked Transaction (optional)
     * @param  string $source_transaction_id Filter by the SourceTransactionID. Get the linked transactions created from a particular ACCPAY invoice (optional)
     * @param  string $contact_id Filter by the ContactID. Get all the linked transactions that have been assigned to a particular customer. (optional)
     * @param  string $status Filter by the combination of ContactID and Status. Get  the linked transactions associated to a  customer and with a status (optional)
     * @param  string $target_transaction_id Filter by the TargetTransactionID. Get all the linked transactions allocated to a particular ACCREC invoice (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions
     */
    public function getLinkedTransactions($xero_tenant_id, $page = null, $linked_transaction_id = null, $source_transaction_id = null, $contact_id = null, $status = null, $target_transaction_id = null)
    {
        list($response) = $this->getLinkedTransactionsWithHttpInfo($xero_tenant_id, $page, $linked_transaction_id, $source_transaction_id, $contact_id, $status, $target_transaction_id);
        return $response;
    }
    /**
     * Operation getLinkedTransactionsWithHttpInfo
     * Retrieves linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $page Up to 100 linked transactions will be returned in a single API call. Use the page parameter to specify the page to be returned e.g. page&#x3D;1. (optional)
     * @param  string $linked_transaction_id The Xero identifier for an Linked Transaction (optional)
     * @param  string $source_transaction_id Filter by the SourceTransactionID. Get the linked transactions created from a particular ACCPAY invoice (optional)
     * @param  string $contact_id Filter by the ContactID. Get all the linked transactions that have been assigned to a particular customer. (optional)
     * @param  string $status Filter by the combination of ContactID and Status. Get  the linked transactions associated to a  customer and with a status (optional)
     * @param  string $target_transaction_id Filter by the TargetTransactionID. Get all the linked transactions allocated to a particular ACCREC invoice (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions, HTTP status code, HTTP response headers (array of strings)
     */
    public function getLinkedTransactionsWithHttpInfo($xero_tenant_id, $page = null, $linked_transaction_id = null, $source_transaction_id = null, $contact_id = null, $status = null, $target_transaction_id = null)
    {
        $request = $this->getLinkedTransactionsRequest($xero_tenant_id, $page, $linked_transaction_id, $source_transaction_id, $contact_id, $status, $target_transaction_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getLinkedTransactionsAsync
     * Retrieves linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $page Up to 100 linked transactions will be returned in a single API call. Use the page parameter to specify the page to be returned e.g. page&#x3D;1. (optional)
     * @param  string $linked_transaction_id The Xero identifier for an Linked Transaction (optional)
     * @param  string $source_transaction_id Filter by the SourceTransactionID. Get the linked transactions created from a particular ACCPAY invoice (optional)
     * @param  string $contact_id Filter by the ContactID. Get all the linked transactions that have been assigned to a particular customer. (optional)
     * @param  string $status Filter by the combination of ContactID and Status. Get  the linked transactions associated to a  customer and with a status (optional)
     * @param  string $target_transaction_id Filter by the TargetTransactionID. Get all the linked transactions allocated to a particular ACCREC invoice (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getLinkedTransactionsAsync($xero_tenant_id, $page = null, $linked_transaction_id = null, $source_transaction_id = null, $contact_id = null, $status = null, $target_transaction_id = null)
    {
        return $this->getLinkedTransactionsAsyncWithHttpInfo($xero_tenant_id, $page, $linked_transaction_id, $source_transaction_id, $contact_id, $status, $target_transaction_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getLinkedTransactionsAsyncWithHttpInfo
     * Retrieves linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $page Up to 100 linked transactions will be returned in a single API call. Use the page parameter to specify the page to be returned e.g. page&#x3D;1. (optional)
     * @param  string $linked_transaction_id The Xero identifier for an Linked Transaction (optional)
     * @param  string $source_transaction_id Filter by the SourceTransactionID. Get the linked transactions created from a particular ACCPAY invoice (optional)
     * @param  string $contact_id Filter by the ContactID. Get all the linked transactions that have been assigned to a particular customer. (optional)
     * @param  string $status Filter by the combination of ContactID and Status. Get  the linked transactions associated to a  customer and with a status (optional)
     * @param  string $target_transaction_id Filter by the TargetTransactionID. Get all the linked transactions allocated to a particular ACCREC invoice (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getLinkedTransactionsAsyncWithHttpInfo($xero_tenant_id, $page = null, $linked_transaction_id = null, $source_transaction_id = null, $contact_id = null, $status = null, $target_transaction_id = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
        $request = $this->getLinkedTransactionsRequest($xero_tenant_id, $page, $linked_transaction_id, $source_transaction_id, $contact_id, $status, $target_transaction_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getLinkedTransactions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  int $page Up to 100 linked transactions will be returned in a single API call. Use the page parameter to specify the page to be returned e.g. page&#x3D;1. (optional)
     * @param  string $linked_transaction_id The Xero identifier for an Linked Transaction (optional)
     * @param  string $source_transaction_id Filter by the SourceTransactionID. Get the linked transactions created from a particular ACCPAY invoice (optional)
     * @param  string $contact_id Filter by the ContactID. Get all the linked transactions that have been assigned to a particular customer. (optional)
     * @param  string $status Filter by the combination of ContactID and Status. Get  the linked transactions associated to a  customer and with a status (optional)
     * @param  string $target_transaction_id Filter by the TargetTransactionID. Get all the linked transactions allocated to a particular ACCREC invoice (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getLinkedTransactionsRequest($xero_tenant_id, $page = null, $linked_transaction_id = null, $source_transaction_id = null, $contact_id = null, $status = null, $target_transaction_id = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getLinkedTransactions'
            );
        }
        $resourcePath = '/LinkedTransactions';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($linked_transaction_id !== null) {
            $queryParams['LinkedTransactionID'] = AccountingObjectSerializer::toQueryValue($linked_transaction_id);
        }
        // query params
        if ($source_transaction_id !== null) {
            $queryParams['SourceTransactionID'] = AccountingObjectSerializer::toQueryValue($source_transaction_id);
        }
        // query params
        if ($contact_id !== null) {
            $queryParams['ContactID'] = AccountingObjectSerializer::toQueryValue($contact_id);
        }
        // query params
        if ($status !== null) {
            $queryParams['Status'] = AccountingObjectSerializer::toQueryValue($status);
        }
        // query params
        if ($target_transaction_id !== null) {
            $queryParams['TargetTransactionID'] = AccountingObjectSerializer::toQueryValue($target_transaction_id);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getManualJournal
     * Retrieves a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ManualJournals
     */
    public function getManualJournal($xero_tenant_id, $manual_journal_id)
    {
        list($response) = $this->getManualJournalWithHttpInfo($xero_tenant_id, $manual_journal_id);
        return $response;
    }
    /**
     * Operation getManualJournalWithHttpInfo
     * Retrieves a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ManualJournals, HTTP status code, HTTP response headers (array of strings)
     */
    public function getManualJournalWithHttpInfo($xero_tenant_id, $manual_journal_id)
    {
        $request = $this->getManualJournalRequest($xero_tenant_id, $manual_journal_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ManualJournals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getManualJournalAsync
     * Retrieves a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getManualJournalAsync($xero_tenant_id, $manual_journal_id)
    {
        return $this->getManualJournalAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getManualJournalAsyncWithHttpInfo
     * Retrieves a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getManualJournalAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
        $request = $this->getManualJournalRequest($xero_tenant_id, $manual_journal_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getManualJournal'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getManualJournalRequest($xero_tenant_id, $manual_journal_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getManualJournal'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling getManualJournal'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getManualJournalAttachmentByFileName
     * Retrieves a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getManualJournalAttachmentByFileName($xero_tenant_id, $manual_journal_id, $file_name, $content_type)
    {
        list($response) = $this->getManualJournalAttachmentByFileNameWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getManualJournalAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getManualJournalAttachmentByFileNameWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $content_type)
    {
        $request = $this->getManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getManualJournalAttachmentByFileNameAsync
     * Retrieves a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getManualJournalAttachmentByFileNameAsync($xero_tenant_id, $manual_journal_id, $file_name, $content_type)
    {
        return $this->getManualJournalAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getManualJournalAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getManualJournalAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getManualJournalAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling getManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getManualJournalAttachmentByFileName'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getManualJournalAttachmentById
     * Allows you to retrieve a specific attachment from a specific manual journal using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getManualJournalAttachmentById($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type)
    {
        list($response) = $this->getManualJournalAttachmentByIdWithHttpInfo($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getManualJournalAttachmentByIdWithHttpInfo
     * Allows you to retrieve a specific attachment from a specific manual journal using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getManualJournalAttachmentByIdWithHttpInfo($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type)
    {
        $request = $this->getManualJournalAttachmentByIdRequest($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getManualJournalAttachmentByIdAsync
     * Allows you to retrieve a specific attachment from a specific manual journal using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getManualJournalAttachmentByIdAsync($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type)
    {
        return $this->getManualJournalAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getManualJournalAttachmentByIdAsyncWithHttpInfo
     * Allows you to retrieve a specific attachment from a specific manual journal using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getManualJournalAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getManualJournalAttachmentByIdRequest($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getManualJournalAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getManualJournalAttachmentByIdRequest($xero_tenant_id, $manual_journal_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getManualJournalAttachmentById'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling getManualJournalAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getManualJournalAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getManualJournalAttachmentById'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getManualJournalAttachments
     * Retrieves attachment for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getManualJournalAttachments($xero_tenant_id, $manual_journal_id)
    {
        list($response) = $this->getManualJournalAttachmentsWithHttpInfo($xero_tenant_id, $manual_journal_id);
        return $response;
    }
    /**
     * Operation getManualJournalAttachmentsWithHttpInfo
     * Retrieves attachment for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getManualJournalAttachmentsWithHttpInfo($xero_tenant_id, $manual_journal_id)
    {
        $request = $this->getManualJournalAttachmentsRequest($xero_tenant_id, $manual_journal_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getManualJournalAttachmentsAsync
     * Retrieves attachment for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getManualJournalAttachmentsAsync($xero_tenant_id, $manual_journal_id)
    {
        return $this->getManualJournalAttachmentsAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getManualJournalAttachmentsAsyncWithHttpInfo
     * Retrieves attachment for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getManualJournalAttachmentsAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getManualJournalAttachmentsRequest($xero_tenant_id, $manual_journal_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getManualJournalAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getManualJournalAttachmentsRequest($xero_tenant_id, $manual_journal_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getManualJournalAttachments'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling getManualJournalAttachments'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getManualJournals
     * Retrieves manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 manual journals will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ManualJournals
     */
    public function getManualJournals($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        list($response) = $this->getManualJournalsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size);
        return $response;
    }
    /**
     * Operation getManualJournalsWithHttpInfo
     * Retrieves manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 manual journals will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ManualJournals, HTTP status code, HTTP response headers (array of strings)
     */
    public function getManualJournalsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        $request = $this->getManualJournalsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ManualJournals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getManualJournalsAsync
     * Retrieves manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 manual journals will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getManualJournalsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        return $this->getManualJournalsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getManualJournalsAsyncWithHttpInfo
     * Retrieves manual journals
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 manual journals will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getManualJournalsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
        $request = $this->getManualJournalsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getManualJournals'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 manual journals will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getManualJournalsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getManualJournals'
            );
        }
        $resourcePath = '/ManualJournals';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getManualJournalsHistory
     * Retrieves history for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getManualJournalsHistory($xero_tenant_id, $manual_journal_id)
    {
        list($response) = $this->getManualJournalsHistoryWithHttpInfo($xero_tenant_id, $manual_journal_id);
        return $response;
    }
    /**
     * Operation getManualJournalsHistoryWithHttpInfo
     * Retrieves history for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getManualJournalsHistoryWithHttpInfo($xero_tenant_id, $manual_journal_id)
    {
        $request = $this->getManualJournalsHistoryRequest($xero_tenant_id, $manual_journal_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getManualJournalsHistoryAsync
     * Retrieves history for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getManualJournalsHistoryAsync($xero_tenant_id, $manual_journal_id)
    {
        return $this->getManualJournalsHistoryAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getManualJournalsHistoryAsyncWithHttpInfo
     * Retrieves history for a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getManualJournalsHistoryAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getManualJournalsHistoryRequest($xero_tenant_id, $manual_journal_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getManualJournalsHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getManualJournalsHistoryRequest($xero_tenant_id, $manual_journal_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getManualJournalsHistory'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling getManualJournalsHistory'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOnlineInvoice
     * Retrieves a URL to an online invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\OnlineInvoices
     */
    public function getOnlineInvoice($xero_tenant_id, $invoice_id)
    {
        list($response) = $this->getOnlineInvoiceWithHttpInfo($xero_tenant_id, $invoice_id);
        return $response;
    }
    /**
     * Operation getOnlineInvoiceWithHttpInfo
     * Retrieves a URL to an online invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\OnlineInvoices, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOnlineInvoiceWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $request = $this->getOnlineInvoiceRequest($xero_tenant_id, $invoice_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\OnlineInvoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\OnlineInvoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\OnlineInvoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\OnlineInvoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getOnlineInvoiceAsync
     * Retrieves a URL to an online invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOnlineInvoiceAsync($xero_tenant_id, $invoice_id)
    {
        return $this->getOnlineInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getOnlineInvoiceAsyncWithHttpInfo
     * Retrieves a URL to an online invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getOnlineInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\OnlineInvoices';
        $request = $this->getOnlineInvoiceRequest($xero_tenant_id, $invoice_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOnlineInvoice'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getOnlineInvoiceRequest($xero_tenant_id, $invoice_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getOnlineInvoice'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling getOnlineInvoice'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/OnlineInvoice';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOrganisationActions
     * Retrieves a list of the key actions your app has permission to perform in the connected Xero organisation.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Actions
     */
    public function getOrganisationActions($xero_tenant_id)
    {
        list($response) = $this->getOrganisationActionsWithHttpInfo($xero_tenant_id);
        return $response;
    }
    /**
     * Operation getOrganisationActionsWithHttpInfo
     * Retrieves a list of the key actions your app has permission to perform in the connected Xero organisation.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Actions, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOrganisationActionsWithHttpInfo($xero_tenant_id)
    {
        $request = $this->getOrganisationActionsRequest($xero_tenant_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Actions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Actions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Actions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Actions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getOrganisationActionsAsync
     * Retrieves a list of the key actions your app has permission to perform in the connected Xero organisation.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrganisationActionsAsync($xero_tenant_id)
    {
        return $this->getOrganisationActionsAsyncWithHttpInfo($xero_tenant_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getOrganisationActionsAsyncWithHttpInfo
     * Retrieves a list of the key actions your app has permission to perform in the connected Xero organisation.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getOrganisationActionsAsyncWithHttpInfo($xero_tenant_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Actions';
        $request = $this->getOrganisationActionsRequest($xero_tenant_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOrganisationActions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getOrganisationActionsRequest($xero_tenant_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getOrganisationActions'
            );
        }
        $resourcePath = '/Organisation/Actions';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOrganisationCISSettings
     * Retrieves the CIS settings for the Xero organistaion.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $organisation_id The unique Xero identifier for an organisation (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\CISOrgSettings
     */
    public function getOrganisationCISSettings($xero_tenant_id, $organisation_id)
    {
        list($response) = $this->getOrganisationCISSettingsWithHttpInfo($xero_tenant_id, $organisation_id);
        return $response;
    }
    /**
     * Operation getOrganisationCISSettingsWithHttpInfo
     * Retrieves the CIS settings for the Xero organistaion.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $organisation_id The unique Xero identifier for an organisation (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\CISOrgSettings, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOrganisationCISSettingsWithHttpInfo($xero_tenant_id, $organisation_id)
    {
        $request = $this->getOrganisationCISSettingsRequest($xero_tenant_id, $organisation_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\CISOrgSettings' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\CISOrgSettings', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CISOrgSettings';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\CISOrgSettings',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getOrganisationCISSettingsAsync
     * Retrieves the CIS settings for the Xero organistaion.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $organisation_id The unique Xero identifier for an organisation (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrganisationCISSettingsAsync($xero_tenant_id, $organisation_id)
    {
        return $this->getOrganisationCISSettingsAsyncWithHttpInfo($xero_tenant_id, $organisation_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getOrganisationCISSettingsAsyncWithHttpInfo
     * Retrieves the CIS settings for the Xero organistaion.
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $organisation_id The unique Xero identifier for an organisation (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getOrganisationCISSettingsAsyncWithHttpInfo($xero_tenant_id, $organisation_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CISOrgSettings';
        $request = $this->getOrganisationCISSettingsRequest($xero_tenant_id, $organisation_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOrganisationCISSettings'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $organisation_id The unique Xero identifier for an organisation (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getOrganisationCISSettingsRequest($xero_tenant_id, $organisation_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getOrganisationCISSettings'
            );
        }
        // verify the required parameter 'organisation_id' is set
        if ($organisation_id === null || (is_array($organisation_id) && count($organisation_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $organisation_id when calling getOrganisationCISSettings'
            );
        }
        $resourcePath = '/Organisation/{OrganisationID}/CISSettings';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($organisation_id !== null) {
            $resourcePath = str_replace(
                '{' . 'OrganisationID' . '}',
                AccountingObjectSerializer::toPathValue($organisation_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOrganisations
     * Retrieves Xero organisation details
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Organisations
     */
    public function getOrganisations($xero_tenant_id)
    {
        list($response) = $this->getOrganisationsWithHttpInfo($xero_tenant_id);
        return $response;
    }
    /**
     * Operation getOrganisationsWithHttpInfo
     * Retrieves Xero organisation details
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Organisations, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOrganisationsWithHttpInfo($xero_tenant_id)
    {
        $request = $this->getOrganisationsRequest($xero_tenant_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Organisations' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Organisations', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Organisations';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Organisations',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getOrganisationsAsync
     * Retrieves Xero organisation details
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOrganisationsAsync($xero_tenant_id)
    {
        return $this->getOrganisationsAsyncWithHttpInfo($xero_tenant_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getOrganisationsAsyncWithHttpInfo
     * Retrieves Xero organisation details
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getOrganisationsAsyncWithHttpInfo($xero_tenant_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Organisations';
        $request = $this->getOrganisationsRequest($xero_tenant_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOrganisations'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getOrganisationsRequest($xero_tenant_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getOrganisations'
            );
        }
        $resourcePath = '/Organisation';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOverpayment
     * Retrieves a specific overpayment using a unique overpayment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Overpayments
     */
    public function getOverpayment($xero_tenant_id, $overpayment_id)
    {
        list($response) = $this->getOverpaymentWithHttpInfo($xero_tenant_id, $overpayment_id);
        return $response;
    }
    /**
     * Operation getOverpaymentWithHttpInfo
     * Retrieves a specific overpayment using a unique overpayment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Overpayments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOverpaymentWithHttpInfo($xero_tenant_id, $overpayment_id)
    {
        $request = $this->getOverpaymentRequest($xero_tenant_id, $overpayment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Overpayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Overpayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Overpayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Overpayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getOverpaymentAsync
     * Retrieves a specific overpayment using a unique overpayment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOverpaymentAsync($xero_tenant_id, $overpayment_id)
    {
        return $this->getOverpaymentAsyncWithHttpInfo($xero_tenant_id, $overpayment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getOverpaymentAsyncWithHttpInfo
     * Retrieves a specific overpayment using a unique overpayment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getOverpaymentAsyncWithHttpInfo($xero_tenant_id, $overpayment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Overpayments';
        $request = $this->getOverpaymentRequest($xero_tenant_id, $overpayment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOverpayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getOverpaymentRequest($xero_tenant_id, $overpayment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getOverpayment'
            );
        }
        // verify the required parameter 'overpayment_id' is set
        if ($overpayment_id === null || (is_array($overpayment_id) && count($overpayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $overpayment_id when calling getOverpayment'
            );
        }
        $resourcePath = '/Overpayments/{OverpaymentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($overpayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'OverpaymentID' . '}',
                AccountingObjectSerializer::toPathValue($overpayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOverpaymentHistory
     * Retrieves history records of a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getOverpaymentHistory($xero_tenant_id, $overpayment_id)
    {
        list($response) = $this->getOverpaymentHistoryWithHttpInfo($xero_tenant_id, $overpayment_id);
        return $response;
    }
    /**
     * Operation getOverpaymentHistoryWithHttpInfo
     * Retrieves history records of a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOverpaymentHistoryWithHttpInfo($xero_tenant_id, $overpayment_id)
    {
        $request = $this->getOverpaymentHistoryRequest($xero_tenant_id, $overpayment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getOverpaymentHistoryAsync
     * Retrieves history records of a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOverpaymentHistoryAsync($xero_tenant_id, $overpayment_id)
    {
        return $this->getOverpaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $overpayment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getOverpaymentHistoryAsyncWithHttpInfo
     * Retrieves history records of a specific overpayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getOverpaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $overpayment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getOverpaymentHistoryRequest($xero_tenant_id, $overpayment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOverpaymentHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $overpayment_id Unique identifier for a Overpayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getOverpaymentHistoryRequest($xero_tenant_id, $overpayment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getOverpaymentHistory'
            );
        }
        // verify the required parameter 'overpayment_id' is set
        if ($overpayment_id === null || (is_array($overpayment_id) && count($overpayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $overpayment_id when calling getOverpaymentHistory'
            );
        }
        $resourcePath = '/Overpayments/{OverpaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($overpayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'OverpaymentID' . '}',
                AccountingObjectSerializer::toPathValue($overpayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getOverpayments
     * Retrieves overpayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 overpayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Overpayments
     */
    public function getOverpayments($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        list($response) = $this->getOverpaymentsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $response;
    }
    /**
     * Operation getOverpaymentsWithHttpInfo
     * Retrieves overpayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 overpayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Overpayments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getOverpaymentsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $request = $this->getOverpaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Overpayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Overpayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Overpayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Overpayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getOverpaymentsAsync
     * Retrieves overpayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 overpayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getOverpaymentsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        return $this->getOverpaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getOverpaymentsAsyncWithHttpInfo
     * Retrieves overpayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 overpayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getOverpaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Overpayments';
        $request = $this->getOverpaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getOverpayments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 overpayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getOverpaymentsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getOverpayments'
            );
        }
        $resourcePath = '/Overpayments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPayment
     * Retrieves a specific payment for invoices and credit notes using a unique payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Payments
     */
    public function getPayment($xero_tenant_id, $payment_id)
    {
        list($response) = $this->getPaymentWithHttpInfo($xero_tenant_id, $payment_id);
        return $response;
    }
    /**
     * Operation getPaymentWithHttpInfo
     * Retrieves a specific payment for invoices and credit notes using a unique payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Payments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPaymentWithHttpInfo($xero_tenant_id, $payment_id)
    {
        $request = $this->getPaymentRequest($xero_tenant_id, $payment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Payments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Payments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Payments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPaymentAsync
     * Retrieves a specific payment for invoices and credit notes using a unique payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPaymentAsync($xero_tenant_id, $payment_id)
    {
        return $this->getPaymentAsyncWithHttpInfo($xero_tenant_id, $payment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPaymentAsyncWithHttpInfo
     * Retrieves a specific payment for invoices and credit notes using a unique payment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPaymentAsyncWithHttpInfo($xero_tenant_id, $payment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
        $request = $this->getPaymentRequest($xero_tenant_id, $payment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPaymentRequest($xero_tenant_id, $payment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPayment'
            );
        }
        // verify the required parameter 'payment_id' is set
        if ($payment_id === null || (is_array($payment_id) && count($payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment_id when calling getPayment'
            );
        }
        $resourcePath = '/Payments/{PaymentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PaymentID' . '}',
                AccountingObjectSerializer::toPathValue($payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPaymentHistory
     * Retrieves history records of a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getPaymentHistory($xero_tenant_id, $payment_id)
    {
        list($response) = $this->getPaymentHistoryWithHttpInfo($xero_tenant_id, $payment_id);
        return $response;
    }
    /**
     * Operation getPaymentHistoryWithHttpInfo
     * Retrieves history records of a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPaymentHistoryWithHttpInfo($xero_tenant_id, $payment_id)
    {
        $request = $this->getPaymentHistoryRequest($xero_tenant_id, $payment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPaymentHistoryAsync
     * Retrieves history records of a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPaymentHistoryAsync($xero_tenant_id, $payment_id)
    {
        return $this->getPaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $payment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPaymentHistoryAsyncWithHttpInfo
     * Retrieves history records of a specific payment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $payment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getPaymentHistoryRequest($xero_tenant_id, $payment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPaymentHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $payment_id Unique identifier for a Payment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPaymentHistoryRequest($xero_tenant_id, $payment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPaymentHistory'
            );
        }
        // verify the required parameter 'payment_id' is set
        if ($payment_id === null || (is_array($payment_id) && count($payment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $payment_id when calling getPaymentHistory'
            );
        }
        $resourcePath = '/Payments/{PaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($payment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PaymentID' . '}',
                AccountingObjectSerializer::toPathValue($payment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPaymentServices
     * Retrieves payment services
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PaymentServices
     */
    public function getPaymentServices($xero_tenant_id)
    {
        list($response) = $this->getPaymentServicesWithHttpInfo($xero_tenant_id);
        return $response;
    }
    /**
     * Operation getPaymentServicesWithHttpInfo
     * Retrieves payment services
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PaymentServices, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPaymentServicesWithHttpInfo($xero_tenant_id)
    {
        $request = $this->getPaymentServicesRequest($xero_tenant_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PaymentServices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPaymentServicesAsync
     * Retrieves payment services
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPaymentServicesAsync($xero_tenant_id)
    {
        return $this->getPaymentServicesAsyncWithHttpInfo($xero_tenant_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPaymentServicesAsyncWithHttpInfo
     * Retrieves payment services
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPaymentServicesAsyncWithHttpInfo($xero_tenant_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PaymentServices';
        $request = $this->getPaymentServicesRequest($xero_tenant_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPaymentServices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPaymentServicesRequest($xero_tenant_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPaymentServices'
            );
        }
        $resourcePath = '/PaymentServices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPayments
     * Retrieves payments for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 payments will be returned in a single API call (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Payments
     */
    public function getPayments($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        list($response) = $this->getPaymentsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size);
        return $response;
    }
    /**
     * Operation getPaymentsWithHttpInfo
     * Retrieves payments for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 payments will be returned in a single API call (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Payments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPaymentsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        $request = $this->getPaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Payments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Payments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Payments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPaymentsAsync
     * Retrieves payments for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 payments will be returned in a single API call (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPaymentsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        return $this->getPaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPaymentsAsyncWithHttpInfo
     * Retrieves payments for invoices and credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 payments will be returned in a single API call (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Payments';
        $request = $this->getPaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPayments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page Up to 100 payments will be returned in a single API call (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPaymentsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPayments'
            );
        }
        $resourcePath = '/Payments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPrepayment
     * Allows you to retrieve a specified prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Prepayments
     */
    public function getPrepayment($xero_tenant_id, $prepayment_id)
    {
        list($response) = $this->getPrepaymentWithHttpInfo($xero_tenant_id, $prepayment_id);
        return $response;
    }
    /**
     * Operation getPrepaymentWithHttpInfo
     * Allows you to retrieve a specified prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Prepayments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPrepaymentWithHttpInfo($xero_tenant_id, $prepayment_id)
    {
        $request = $this->getPrepaymentRequest($xero_tenant_id, $prepayment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Prepayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Prepayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Prepayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Prepayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPrepaymentAsync
     * Allows you to retrieve a specified prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPrepaymentAsync($xero_tenant_id, $prepayment_id)
    {
        return $this->getPrepaymentAsyncWithHttpInfo($xero_tenant_id, $prepayment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPrepaymentAsyncWithHttpInfo
     * Allows you to retrieve a specified prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPrepaymentAsyncWithHttpInfo($xero_tenant_id, $prepayment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Prepayments';
        $request = $this->getPrepaymentRequest($xero_tenant_id, $prepayment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPrepayment'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPrepaymentRequest($xero_tenant_id, $prepayment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPrepayment'
            );
        }
        // verify the required parameter 'prepayment_id' is set
        if ($prepayment_id === null || (is_array($prepayment_id) && count($prepayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $prepayment_id when calling getPrepayment'
            );
        }
        $resourcePath = '/Prepayments/{PrepaymentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($prepayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PrepaymentID' . '}',
                AccountingObjectSerializer::toPathValue($prepayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPrepaymentHistory
     * Retrieves history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getPrepaymentHistory($xero_tenant_id, $prepayment_id)
    {
        list($response) = $this->getPrepaymentHistoryWithHttpInfo($xero_tenant_id, $prepayment_id);
        return $response;
    }
    /**
     * Operation getPrepaymentHistoryWithHttpInfo
     * Retrieves history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPrepaymentHistoryWithHttpInfo($xero_tenant_id, $prepayment_id)
    {
        $request = $this->getPrepaymentHistoryRequest($xero_tenant_id, $prepayment_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPrepaymentHistoryAsync
     * Retrieves history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPrepaymentHistoryAsync($xero_tenant_id, $prepayment_id)
    {
        return $this->getPrepaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $prepayment_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPrepaymentHistoryAsyncWithHttpInfo
     * Retrieves history record for a specific prepayment
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPrepaymentHistoryAsyncWithHttpInfo($xero_tenant_id, $prepayment_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getPrepaymentHistoryRequest($xero_tenant_id, $prepayment_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPrepaymentHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $prepayment_id Unique identifier for a PrePayment (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPrepaymentHistoryRequest($xero_tenant_id, $prepayment_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPrepaymentHistory'
            );
        }
        // verify the required parameter 'prepayment_id' is set
        if ($prepayment_id === null || (is_array($prepayment_id) && count($prepayment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $prepayment_id when calling getPrepaymentHistory'
            );
        }
        $resourcePath = '/Prepayments/{PrepaymentID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($prepayment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PrepaymentID' . '}',
                AccountingObjectSerializer::toPathValue($prepayment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPrepayments
     * Retrieves prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 prepayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Prepayments
     */
    public function getPrepayments($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        list($response) = $this->getPrepaymentsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $response;
    }
    /**
     * Operation getPrepaymentsWithHttpInfo
     * Retrieves prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 prepayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Prepayments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPrepaymentsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $request = $this->getPrepaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Prepayments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Prepayments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Prepayments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Prepayments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPrepaymentsAsync
     * Retrieves prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 prepayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPrepaymentsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        return $this->getPrepaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPrepaymentsAsyncWithHttpInfo
     * Retrieves prepayments
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 prepayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPrepaymentsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Prepayments';
        $request = $this->getPrepaymentsRequest($xero_tenant_id, $if_modified_since, $where, $order, $page, $unitdp, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPrepayments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 prepayments will be returned in a single API call with line items shown for each overpayment (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPrepaymentsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $page = null, $unitdp = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPrepayments'
            );
        }
        $resourcePath = '/Prepayments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrder
     * Retrieves a specific purchase order using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders
     */
    public function getPurchaseOrder($xero_tenant_id, $purchase_order_id)
    {
        list($response) = $this->getPurchaseOrderWithHttpInfo($xero_tenant_id, $purchase_order_id);
        return $response;
    }
    /**
     * Operation getPurchaseOrderWithHttpInfo
     * Retrieves a specific purchase order using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrderWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $request = $this->getPurchaseOrderRequest($xero_tenant_id, $purchase_order_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrderAsync
     * Retrieves a specific purchase order using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrderAsync($xero_tenant_id, $purchase_order_id)
    {
        return $this->getPurchaseOrderAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrderAsyncWithHttpInfo
     * Retrieves a specific purchase order using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrderAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
        $request = $this->getPurchaseOrderRequest($xero_tenant_id, $purchase_order_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrder'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrderRequest($xero_tenant_id, $purchase_order_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrder'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling getPurchaseOrder'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrderAsPdf
     * Retrieves specific purchase order as PDF files using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getPurchaseOrderAsPdf($xero_tenant_id, $purchase_order_id)
    {
        list($response) = $this->getPurchaseOrderAsPdfWithHttpInfo($xero_tenant_id, $purchase_order_id);
        return $response;
    }
    /**
     * Operation getPurchaseOrderAsPdfWithHttpInfo
     * Retrieves specific purchase order as PDF files using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrderAsPdfWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $request = $this->getPurchaseOrderAsPdfRequest($xero_tenant_id, $purchase_order_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrderAsPdfAsync
     * Retrieves specific purchase order as PDF files using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrderAsPdfAsync($xero_tenant_id, $purchase_order_id)
    {
        return $this->getPurchaseOrderAsPdfAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrderAsPdfAsyncWithHttpInfo
     * Retrieves specific purchase order as PDF files using a unique purchase order Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrderAsPdfAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $returnType = '\SplFileObject';
        $request = $this->getPurchaseOrderAsPdfRequest($xero_tenant_id, $purchase_order_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrderAsPdf'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrderAsPdfRequest($xero_tenant_id, $purchase_order_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrderAsPdf'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling getPurchaseOrderAsPdf'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/pdf']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/pdf'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrderAttachmentByFileName
     * Retrieves a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getPurchaseOrderAttachmentByFileName($xero_tenant_id, $purchase_order_id, $file_name, $content_type)
    {
        list($response) = $this->getPurchaseOrderAttachmentByFileNameWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getPurchaseOrderAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrderAttachmentByFileNameWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $content_type)
    {
        $request = $this->getPurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrderAttachmentByFileNameAsync
     * Retrieves a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrderAttachmentByFileNameAsync($xero_tenant_id, $purchase_order_id, $file_name, $content_type)
    {
        return $this->getPurchaseOrderAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrderAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrderAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getPurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrderAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling getPurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getPurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getPurchaseOrderAttachmentByFileName'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrderAttachmentById
     * Retrieves specific attachment for a specific purchase order using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getPurchaseOrderAttachmentById($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type)
    {
        list($response) = $this->getPurchaseOrderAttachmentByIdWithHttpInfo($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getPurchaseOrderAttachmentByIdWithHttpInfo
     * Retrieves specific attachment for a specific purchase order using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrderAttachmentByIdWithHttpInfo($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type)
    {
        $request = $this->getPurchaseOrderAttachmentByIdRequest($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrderAttachmentByIdAsync
     * Retrieves specific attachment for a specific purchase order using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrderAttachmentByIdAsync($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type)
    {
        return $this->getPurchaseOrderAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrderAttachmentByIdAsyncWithHttpInfo
     * Retrieves specific attachment for a specific purchase order using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrderAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getPurchaseOrderAttachmentByIdRequest($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrderAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrderAttachmentByIdRequest($xero_tenant_id, $purchase_order_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrderAttachmentById'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling getPurchaseOrderAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getPurchaseOrderAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getPurchaseOrderAttachmentById'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrderAttachments
     * Retrieves attachments for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getPurchaseOrderAttachments($xero_tenant_id, $purchase_order_id)
    {
        list($response) = $this->getPurchaseOrderAttachmentsWithHttpInfo($xero_tenant_id, $purchase_order_id);
        return $response;
    }
    /**
     * Operation getPurchaseOrderAttachmentsWithHttpInfo
     * Retrieves attachments for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrderAttachmentsWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $request = $this->getPurchaseOrderAttachmentsRequest($xero_tenant_id, $purchase_order_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrderAttachmentsAsync
     * Retrieves attachments for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrderAttachmentsAsync($xero_tenant_id, $purchase_order_id)
    {
        return $this->getPurchaseOrderAttachmentsAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrderAttachmentsAsyncWithHttpInfo
     * Retrieves attachments for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrderAttachmentsAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getPurchaseOrderAttachmentsRequest($xero_tenant_id, $purchase_order_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrderAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrderAttachmentsRequest($xero_tenant_id, $purchase_order_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrderAttachments'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling getPurchaseOrderAttachments'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrderByNumber
     * Retrieves a specific purchase order using purchase order number
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_number Unique identifier for a PurchaseOrder (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders
     */
    public function getPurchaseOrderByNumber($xero_tenant_id, $purchase_order_number)
    {
        list($response) = $this->getPurchaseOrderByNumberWithHttpInfo($xero_tenant_id, $purchase_order_number);
        return $response;
    }
    /**
     * Operation getPurchaseOrderByNumberWithHttpInfo
     * Retrieves a specific purchase order using purchase order number
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_number Unique identifier for a PurchaseOrder (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrderByNumberWithHttpInfo($xero_tenant_id, $purchase_order_number)
    {
        $request = $this->getPurchaseOrderByNumberRequest($xero_tenant_id, $purchase_order_number);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrderByNumberAsync
     * Retrieves a specific purchase order using purchase order number
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_number Unique identifier for a PurchaseOrder (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrderByNumberAsync($xero_tenant_id, $purchase_order_number)
    {
        return $this->getPurchaseOrderByNumberAsyncWithHttpInfo($xero_tenant_id, $purchase_order_number)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrderByNumberAsyncWithHttpInfo
     * Retrieves a specific purchase order using purchase order number
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_number Unique identifier for a PurchaseOrder (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrderByNumberAsyncWithHttpInfo($xero_tenant_id, $purchase_order_number)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
        $request = $this->getPurchaseOrderByNumberRequest($xero_tenant_id, $purchase_order_number);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrderByNumber'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_number Unique identifier for a PurchaseOrder (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrderByNumberRequest($xero_tenant_id, $purchase_order_number)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrderByNumber'
            );
        }
        // verify the required parameter 'purchase_order_number' is set
        if ($purchase_order_number === null || (is_array($purchase_order_number) && count($purchase_order_number) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_number when calling getPurchaseOrderByNumber'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderNumber}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($purchase_order_number !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderNumber' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_number),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrderHistory
     * Retrieves history for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getPurchaseOrderHistory($xero_tenant_id, $purchase_order_id)
    {
        list($response) = $this->getPurchaseOrderHistoryWithHttpInfo($xero_tenant_id, $purchase_order_id);
        return $response;
    }
    /**
     * Operation getPurchaseOrderHistoryWithHttpInfo
     * Retrieves history for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrderHistoryWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $request = $this->getPurchaseOrderHistoryRequest($xero_tenant_id, $purchase_order_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrderHistoryAsync
     * Retrieves history for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrderHistoryAsync($xero_tenant_id, $purchase_order_id)
    {
        return $this->getPurchaseOrderHistoryAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrderHistoryAsyncWithHttpInfo
     * Retrieves history for a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrderHistoryAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getPurchaseOrderHistoryRequest($xero_tenant_id, $purchase_order_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrderHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrderHistoryRequest($xero_tenant_id, $purchase_order_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrderHistory'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling getPurchaseOrderHistory'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPurchaseOrders
     * Retrieves purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $status Filter by purchase order status (optional)
     * @param  string $date_from Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $date_to Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page To specify a page, append the page parameter to the URL e.g. ?page&#x3D;1. If there are 100 records in the response you will need to check if there is any more data by fetching the next page e.g ?page&#x3D;2 and continuing this process until no more results are returned. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders
     */
    public function getPurchaseOrders($xero_tenant_id, $if_modified_since = null, $status = null, $date_from = null, $date_to = null, $order = null, $page = null, $page_size = null)
    {
        list($response) = $this->getPurchaseOrdersWithHttpInfo($xero_tenant_id, $if_modified_since, $status, $date_from, $date_to, $order, $page, $page_size);
        return $response;
    }
    /**
     * Operation getPurchaseOrdersWithHttpInfo
     * Retrieves purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $status Filter by purchase order status (optional)
     * @param  string $date_from Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $date_to Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page To specify a page, append the page parameter to the URL e.g. ?page&#x3D;1. If there are 100 records in the response you will need to check if there is any more data by fetching the next page e.g ?page&#x3D;2 and continuing this process until no more results are returned. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPurchaseOrdersWithHttpInfo($xero_tenant_id, $if_modified_since = null, $status = null, $date_from = null, $date_to = null, $order = null, $page = null, $page_size = null)
    {
        $request = $this->getPurchaseOrdersRequest($xero_tenant_id, $if_modified_since, $status, $date_from, $date_to, $order, $page, $page_size);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getPurchaseOrdersAsync
     * Retrieves purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $status Filter by purchase order status (optional)
     * @param  string $date_from Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $date_to Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page To specify a page, append the page parameter to the URL e.g. ?page&#x3D;1. If there are 100 records in the response you will need to check if there is any more data by fetching the next page e.g ?page&#x3D;2 and continuing this process until no more results are returned. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getPurchaseOrdersAsync($xero_tenant_id, $if_modified_since = null, $status = null, $date_from = null, $date_to = null, $order = null, $page = null, $page_size = null)
    {
        return $this->getPurchaseOrdersAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $status, $date_from, $date_to, $order, $page, $page_size)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getPurchaseOrdersAsyncWithHttpInfo
     * Retrieves purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $status Filter by purchase order status (optional)
     * @param  string $date_from Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $date_to Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page To specify a page, append the page parameter to the URL e.g. ?page&#x3D;1. If there are 100 records in the response you will need to check if there is any more data by fetching the next page e.g ?page&#x3D;2 and continuing this process until no more results are returned. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getPurchaseOrdersAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $status = null, $date_from = null, $date_to = null, $order = null, $page = null, $page_size = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
        $request = $this->getPurchaseOrdersRequest($xero_tenant_id, $if_modified_since, $status, $date_from, $date_to, $order, $page, $page_size);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getPurchaseOrders'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $status Filter by purchase order status (optional)
     * @param  string $date_from Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $date_to Filter by purchase order date (e.g. GET https://.../PurchaseOrders?DateFrom&#x3D;2015-12-01&amp;DateTo&#x3D;2015-12-31 (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $page To specify a page, append the page parameter to the URL e.g. ?page&#x3D;1. If there are 100 records in the response you will need to check if there is any more data by fetching the next page e.g ?page&#x3D;2 and continuing this process until no more results are returned. (optional)
     * @param  int $page_size Number of records to retrieve per page (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getPurchaseOrdersRequest($xero_tenant_id, $if_modified_since = null, $status = null, $date_from = null, $date_to = null, $order = null, $page = null, $page_size = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getPurchaseOrders'
            );
        }
        $resourcePath = '/PurchaseOrders';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($status !== null) {
            $queryParams['Status'] = AccountingObjectSerializer::toQueryValue($status);
        }
        // query params
        if ($date_from !== null) {
            $queryParams['DateFrom'] = AccountingObjectSerializer::toQueryValue($date_from);
        }
        // query params
        if ($date_to !== null) {
            $queryParams['DateTo'] = AccountingObjectSerializer::toQueryValue($date_to);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($page_size !== null) {
            $queryParams['pageSize'] = AccountingObjectSerializer::toQueryValue($page_size);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getQuote
     * Retrieves a specific quote using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Quotes
     */
    public function getQuote($xero_tenant_id, $quote_id)
    {
        list($response) = $this->getQuoteWithHttpInfo($xero_tenant_id, $quote_id);
        return $response;
    }
    /**
     * Operation getQuoteWithHttpInfo
     * Retrieves a specific quote using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Quotes, HTTP status code, HTTP response headers (array of strings)
     */
    public function getQuoteWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $request = $this->getQuoteRequest($xero_tenant_id, $quote_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Quotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Quotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Quotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getQuoteAsync
     * Retrieves a specific quote using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getQuoteAsync($xero_tenant_id, $quote_id)
    {
        return $this->getQuoteAsyncWithHttpInfo($xero_tenant_id, $quote_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getQuoteAsyncWithHttpInfo
     * Retrieves a specific quote using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getQuoteAsyncWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
        $request = $this->getQuoteRequest($xero_tenant_id, $quote_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getQuote'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getQuoteRequest($xero_tenant_id, $quote_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getQuote'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling getQuote'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getQuoteAsPdf
     * Retrieves a specific quote as a PDF file using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getQuoteAsPdf($xero_tenant_id, $quote_id)
    {
        list($response) = $this->getQuoteAsPdfWithHttpInfo($xero_tenant_id, $quote_id);
        return $response;
    }
    /**
     * Operation getQuoteAsPdfWithHttpInfo
     * Retrieves a specific quote as a PDF file using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getQuoteAsPdfWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $request = $this->getQuoteAsPdfRequest($xero_tenant_id, $quote_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getQuoteAsPdfAsync
     * Retrieves a specific quote as a PDF file using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getQuoteAsPdfAsync($xero_tenant_id, $quote_id)
    {
        return $this->getQuoteAsPdfAsyncWithHttpInfo($xero_tenant_id, $quote_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getQuoteAsPdfAsyncWithHttpInfo
     * Retrieves a specific quote as a PDF file using a unique quote Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getQuoteAsPdfAsyncWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $returnType = '\SplFileObject';
        $request = $this->getQuoteAsPdfRequest($xero_tenant_id, $quote_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getQuoteAsPdf'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getQuoteAsPdfRequest($xero_tenant_id, $quote_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getQuoteAsPdf'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling getQuoteAsPdf'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/pdf']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/pdf'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getQuoteAttachmentByFileName
     * Retrieves a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getQuoteAttachmentByFileName($xero_tenant_id, $quote_id, $file_name, $content_type)
    {
        list($response) = $this->getQuoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getQuoteAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getQuoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $content_type)
    {
        $request = $this->getQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getQuoteAttachmentByFileNameAsync
     * Retrieves a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getQuoteAttachmentByFileNameAsync($xero_tenant_id, $quote_id, $file_name, $content_type)
    {
        return $this->getQuoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getQuoteAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getQuoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getQuoteAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling getQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getQuoteAttachmentByFileName'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getQuoteAttachmentById
     * Retrieves a specific attachment from a specific quote using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getQuoteAttachmentById($xero_tenant_id, $quote_id, $attachment_id, $content_type)
    {
        list($response) = $this->getQuoteAttachmentByIdWithHttpInfo($xero_tenant_id, $quote_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getQuoteAttachmentByIdWithHttpInfo
     * Retrieves a specific attachment from a specific quote using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getQuoteAttachmentByIdWithHttpInfo($xero_tenant_id, $quote_id, $attachment_id, $content_type)
    {
        $request = $this->getQuoteAttachmentByIdRequest($xero_tenant_id, $quote_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getQuoteAttachmentByIdAsync
     * Retrieves a specific attachment from a specific quote using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getQuoteAttachmentByIdAsync($xero_tenant_id, $quote_id, $attachment_id, $content_type)
    {
        return $this->getQuoteAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $quote_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getQuoteAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific quote using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getQuoteAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $quote_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getQuoteAttachmentByIdRequest($xero_tenant_id, $quote_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getQuoteAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getQuoteAttachmentByIdRequest($xero_tenant_id, $quote_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getQuoteAttachmentById'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling getQuoteAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getQuoteAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getQuoteAttachmentById'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getQuoteAttachments
     * Retrieves attachments for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getQuoteAttachments($xero_tenant_id, $quote_id)
    {
        list($response) = $this->getQuoteAttachmentsWithHttpInfo($xero_tenant_id, $quote_id);
        return $response;
    }
    /**
     * Operation getQuoteAttachmentsWithHttpInfo
     * Retrieves attachments for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getQuoteAttachmentsWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $request = $this->getQuoteAttachmentsRequest($xero_tenant_id, $quote_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getQuoteAttachmentsAsync
     * Retrieves attachments for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getQuoteAttachmentsAsync($xero_tenant_id, $quote_id)
    {
        return $this->getQuoteAttachmentsAsyncWithHttpInfo($xero_tenant_id, $quote_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getQuoteAttachmentsAsyncWithHttpInfo
     * Retrieves attachments for a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getQuoteAttachmentsAsyncWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getQuoteAttachmentsRequest($xero_tenant_id, $quote_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getQuoteAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getQuoteAttachmentsRequest($xero_tenant_id, $quote_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getQuoteAttachments'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling getQuoteAttachments'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getQuoteHistory
     * Retrieves history records of a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getQuoteHistory($xero_tenant_id, $quote_id)
    {
        list($response) = $this->getQuoteHistoryWithHttpInfo($xero_tenant_id, $quote_id);
        return $response;
    }
    /**
     * Operation getQuoteHistoryWithHttpInfo
     * Retrieves history records of a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getQuoteHistoryWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $request = $this->getQuoteHistoryRequest($xero_tenant_id, $quote_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getQuoteHistoryAsync
     * Retrieves history records of a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getQuoteHistoryAsync($xero_tenant_id, $quote_id)
    {
        return $this->getQuoteHistoryAsyncWithHttpInfo($xero_tenant_id, $quote_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getQuoteHistoryAsyncWithHttpInfo
     * Retrieves history records of a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getQuoteHistoryAsyncWithHttpInfo($xero_tenant_id, $quote_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getQuoteHistoryRequest($xero_tenant_id, $quote_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getQuoteHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getQuoteHistoryRequest($xero_tenant_id, $quote_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getQuoteHistory'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling getQuoteHistory'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getQuotes
     * Retrieves sales quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  \DateTime $date_from Filter for quotes after a particular date (optional)
     * @param  \DateTime $date_to Filter for quotes before a particular date (optional)
     * @param  \DateTime $expiry_date_from Filter for quotes expiring after a particular date (optional)
     * @param  \DateTime $expiry_date_to Filter for quotes before a particular date (optional)
     * @param  string $contact_id Filter for quotes belonging to a particular contact (optional)
     * @param  string $status Filter for quotes of a particular Status (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 Quotes will be returned in a single API call with line items shown for each quote (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string $quote_number Filter by quote number (e.g. GET https://.../Quotes?QuoteNumber&#x3D;QU-0001) (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Quotes
     */
    public function getQuotes($xero_tenant_id, $if_modified_since = null, $date_from = null, $date_to = null, $expiry_date_from = null, $expiry_date_to = null, $contact_id = null, $status = null, $page = null, $order = null, $quote_number = null)
    {
        list($response) = $this->getQuotesWithHttpInfo($xero_tenant_id, $if_modified_since, $date_from, $date_to, $expiry_date_from, $expiry_date_to, $contact_id, $status, $page, $order, $quote_number);
        return $response;
    }
    /**
     * Operation getQuotesWithHttpInfo
     * Retrieves sales quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  \DateTime $date_from Filter for quotes after a particular date (optional)
     * @param  \DateTime $date_to Filter for quotes before a particular date (optional)
     * @param  \DateTime $expiry_date_from Filter for quotes expiring after a particular date (optional)
     * @param  \DateTime $expiry_date_to Filter for quotes before a particular date (optional)
     * @param  string $contact_id Filter for quotes belonging to a particular contact (optional)
     * @param  string $status Filter for quotes of a particular Status (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 Quotes will be returned in a single API call with line items shown for each quote (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string $quote_number Filter by quote number (e.g. GET https://.../Quotes?QuoteNumber&#x3D;QU-0001) (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Quotes, HTTP status code, HTTP response headers (array of strings)
     */
    public function getQuotesWithHttpInfo($xero_tenant_id, $if_modified_since = null, $date_from = null, $date_to = null, $expiry_date_from = null, $expiry_date_to = null, $contact_id = null, $status = null, $page = null, $order = null, $quote_number = null)
    {
        $request = $this->getQuotesRequest($xero_tenant_id, $if_modified_since, $date_from, $date_to, $expiry_date_from, $expiry_date_to, $contact_id, $status, $page, $order, $quote_number);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Quotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Quotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Quotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getQuotesAsync
     * Retrieves sales quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  \DateTime $date_from Filter for quotes after a particular date (optional)
     * @param  \DateTime $date_to Filter for quotes before a particular date (optional)
     * @param  \DateTime $expiry_date_from Filter for quotes expiring after a particular date (optional)
     * @param  \DateTime $expiry_date_to Filter for quotes before a particular date (optional)
     * @param  string $contact_id Filter for quotes belonging to a particular contact (optional)
     * @param  string $status Filter for quotes of a particular Status (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 Quotes will be returned in a single API call with line items shown for each quote (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string $quote_number Filter by quote number (e.g. GET https://.../Quotes?QuoteNumber&#x3D;QU-0001) (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getQuotesAsync($xero_tenant_id, $if_modified_since = null, $date_from = null, $date_to = null, $expiry_date_from = null, $expiry_date_to = null, $contact_id = null, $status = null, $page = null, $order = null, $quote_number = null)
    {
        return $this->getQuotesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $date_from, $date_to, $expiry_date_from, $expiry_date_to, $contact_id, $status, $page, $order, $quote_number)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getQuotesAsyncWithHttpInfo
     * Retrieves sales quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  \DateTime $date_from Filter for quotes after a particular date (optional)
     * @param  \DateTime $date_to Filter for quotes before a particular date (optional)
     * @param  \DateTime $expiry_date_from Filter for quotes expiring after a particular date (optional)
     * @param  \DateTime $expiry_date_to Filter for quotes before a particular date (optional)
     * @param  string $contact_id Filter for quotes belonging to a particular contact (optional)
     * @param  string $status Filter for quotes of a particular Status (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 Quotes will be returned in a single API call with line items shown for each quote (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string $quote_number Filter by quote number (e.g. GET https://.../Quotes?QuoteNumber&#x3D;QU-0001) (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getQuotesAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $date_from = null, $date_to = null, $expiry_date_from = null, $expiry_date_to = null, $contact_id = null, $status = null, $page = null, $order = null, $quote_number = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
        $request = $this->getQuotesRequest($xero_tenant_id, $if_modified_since, $date_from, $date_to, $expiry_date_from, $expiry_date_to, $contact_id, $status, $page, $order, $quote_number);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getQuotes'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  \DateTime $date_from Filter for quotes after a particular date (optional)
     * @param  \DateTime $date_to Filter for quotes before a particular date (optional)
     * @param  \DateTime $expiry_date_from Filter for quotes expiring after a particular date (optional)
     * @param  \DateTime $expiry_date_to Filter for quotes before a particular date (optional)
     * @param  string $contact_id Filter for quotes belonging to a particular contact (optional)
     * @param  string $status Filter for quotes of a particular Status (optional)
     * @param  int $page e.g. page&#x3D;1 – Up to 100 Quotes will be returned in a single API call with line items shown for each quote (optional)
     * @param  string $order Order by an any element (optional)
     * @param  string $quote_number Filter by quote number (e.g. GET https://.../Quotes?QuoteNumber&#x3D;QU-0001) (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getQuotesRequest($xero_tenant_id, $if_modified_since = null, $date_from = null, $date_to = null, $expiry_date_from = null, $expiry_date_to = null, $contact_id = null, $status = null, $page = null, $order = null, $quote_number = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getQuotes'
            );
        }
        $resourcePath = '/Quotes';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($date_from !== null) {
            $queryParams['DateFrom'] = AccountingObjectSerializer::toQueryValue($date_from);
        }
        // query params
        if ($date_to !== null) {
            $queryParams['DateTo'] = AccountingObjectSerializer::toQueryValue($date_to);
        }
        // query params
        if ($expiry_date_from !== null) {
            $queryParams['ExpiryDateFrom'] = AccountingObjectSerializer::toQueryValue($expiry_date_from);
        }
        // query params
        if ($expiry_date_to !== null) {
            $queryParams['ExpiryDateTo'] = AccountingObjectSerializer::toQueryValue($expiry_date_to);
        }
        // query params
        if ($contact_id !== null) {
            $queryParams['ContactID'] = AccountingObjectSerializer::toQueryValue($contact_id);
        }
        // query params
        if ($status !== null) {
            $queryParams['Status'] = AccountingObjectSerializer::toQueryValue($status);
        }
        // query params
        if ($page !== null) {
            $queryParams['page'] = AccountingObjectSerializer::toQueryValue($page);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($quote_number !== null) {
            $queryParams['QuoteNumber'] = AccountingObjectSerializer::toQueryValue($quote_number);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReceipt
     * Retrieves a specific draft expense claim receipt by using a unique receipt Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Receipts
     */
    public function getReceipt($xero_tenant_id, $receipt_id, $unitdp = null)
    {
        list($response) = $this->getReceiptWithHttpInfo($xero_tenant_id, $receipt_id, $unitdp);
        return $response;
    }
    /**
     * Operation getReceiptWithHttpInfo
     * Retrieves a specific draft expense claim receipt by using a unique receipt Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Receipts, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptWithHttpInfo($xero_tenant_id, $receipt_id, $unitdp = null)
    {
        $request = $this->getReceiptRequest($xero_tenant_id, $receipt_id, $unitdp);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Receipts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Receipts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Receipts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReceiptAsync
     * Retrieves a specific draft expense claim receipt by using a unique receipt Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptAsync($xero_tenant_id, $receipt_id, $unitdp = null)
    {
        return $this->getReceiptAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $unitdp)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReceiptAsyncWithHttpInfo
     * Retrieves a specific draft expense claim receipt by using a unique receipt Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReceiptAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $unitdp = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
        $request = $this->getReceiptRequest($xero_tenant_id, $receipt_id, $unitdp);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReceipt'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReceiptRequest($xero_tenant_id, $receipt_id, $unitdp = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReceipt'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling getReceipt'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReceiptAttachmentByFileName
     * Retrieves a specific attachment from a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getReceiptAttachmentByFileName($xero_tenant_id, $receipt_id, $file_name, $content_type)
    {
        list($response) = $this->getReceiptAttachmentByFileNameWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getReceiptAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment from a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptAttachmentByFileNameWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $content_type)
    {
        $request = $this->getReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReceiptAttachmentByFileNameAsync
     * Retrieves a specific attachment from a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptAttachmentByFileNameAsync($xero_tenant_id, $receipt_id, $file_name, $content_type)
    {
        return $this->getReceiptAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReceiptAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReceiptAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReceiptAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling getReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getReceiptAttachmentByFileName'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReceiptAttachmentById
     * Retrieves a specific attachments from a specific expense claim receipts by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getReceiptAttachmentById($xero_tenant_id, $receipt_id, $attachment_id, $content_type)
    {
        list($response) = $this->getReceiptAttachmentByIdWithHttpInfo($xero_tenant_id, $receipt_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getReceiptAttachmentByIdWithHttpInfo
     * Retrieves a specific attachments from a specific expense claim receipts by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptAttachmentByIdWithHttpInfo($xero_tenant_id, $receipt_id, $attachment_id, $content_type)
    {
        $request = $this->getReceiptAttachmentByIdRequest($xero_tenant_id, $receipt_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReceiptAttachmentByIdAsync
     * Retrieves a specific attachments from a specific expense claim receipts by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptAttachmentByIdAsync($xero_tenant_id, $receipt_id, $attachment_id, $content_type)
    {
        return $this->getReceiptAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReceiptAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachments from a specific expense claim receipts by using a unique attachment Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReceiptAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getReceiptAttachmentByIdRequest($xero_tenant_id, $receipt_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReceiptAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReceiptAttachmentByIdRequest($xero_tenant_id, $receipt_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReceiptAttachmentById'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling getReceiptAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getReceiptAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getReceiptAttachmentById'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReceiptAttachments
     * Retrieves attachments for a specific expense claim receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getReceiptAttachments($xero_tenant_id, $receipt_id)
    {
        list($response) = $this->getReceiptAttachmentsWithHttpInfo($xero_tenant_id, $receipt_id);
        return $response;
    }
    /**
     * Operation getReceiptAttachmentsWithHttpInfo
     * Retrieves attachments for a specific expense claim receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptAttachmentsWithHttpInfo($xero_tenant_id, $receipt_id)
    {
        $request = $this->getReceiptAttachmentsRequest($xero_tenant_id, $receipt_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReceiptAttachmentsAsync
     * Retrieves attachments for a specific expense claim receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptAttachmentsAsync($xero_tenant_id, $receipt_id)
    {
        return $this->getReceiptAttachmentsAsyncWithHttpInfo($xero_tenant_id, $receipt_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReceiptAttachmentsAsyncWithHttpInfo
     * Retrieves attachments for a specific expense claim receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReceiptAttachmentsAsyncWithHttpInfo($xero_tenant_id, $receipt_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getReceiptAttachmentsRequest($xero_tenant_id, $receipt_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReceiptAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReceiptAttachmentsRequest($xero_tenant_id, $receipt_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReceiptAttachments'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling getReceiptAttachments'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReceiptHistory
     * Retrieves a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getReceiptHistory($xero_tenant_id, $receipt_id)
    {
        list($response) = $this->getReceiptHistoryWithHttpInfo($xero_tenant_id, $receipt_id);
        return $response;
    }
    /**
     * Operation getReceiptHistoryWithHttpInfo
     * Retrieves a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptHistoryWithHttpInfo($xero_tenant_id, $receipt_id)
    {
        $request = $this->getReceiptHistoryRequest($xero_tenant_id, $receipt_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReceiptHistoryAsync
     * Retrieves a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptHistoryAsync($xero_tenant_id, $receipt_id)
    {
        return $this->getReceiptHistoryAsyncWithHttpInfo($xero_tenant_id, $receipt_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReceiptHistoryAsyncWithHttpInfo
     * Retrieves a history record for a specific receipt
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReceiptHistoryAsyncWithHttpInfo($xero_tenant_id, $receipt_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getReceiptHistoryRequest($xero_tenant_id, $receipt_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReceiptHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReceiptHistoryRequest($xero_tenant_id, $receipt_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReceiptHistory'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling getReceiptHistory'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReceipts
     * Retrieves draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Receipts
     */
    public function getReceipts($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        list($response) = $this->getReceiptsWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $unitdp);
        return $response;
    }
    /**
     * Operation getReceiptsWithHttpInfo
     * Retrieves draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Receipts, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReceiptsWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        $request = $this->getReceiptsRequest($xero_tenant_id, $if_modified_since, $where, $order, $unitdp);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Receipts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Receipts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Receipts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReceiptsAsync
     * Retrieves draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReceiptsAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        return $this->getReceiptsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order, $unitdp)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReceiptsAsyncWithHttpInfo
     * Retrieves draft expense claim receipts for any user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReceiptsAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
        $request = $this->getReceiptsRequest($xero_tenant_id, $if_modified_since, $where, $order, $unitdp);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReceipts'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReceiptsRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null, $unitdp = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReceipts'
            );
        }
        $resourcePath = '/Receipts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getRepeatingInvoice
     * Retrieves a specific repeating invoice by using a unique repeating invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices
     */
    public function getRepeatingInvoice($xero_tenant_id, $repeating_invoice_id)
    {
        list($response) = $this->getRepeatingInvoiceWithHttpInfo($xero_tenant_id, $repeating_invoice_id);
        return $response;
    }
    /**
     * Operation getRepeatingInvoiceWithHttpInfo
     * Retrieves a specific repeating invoice by using a unique repeating invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices, HTTP status code, HTTP response headers (array of strings)
     */
    public function getRepeatingInvoiceWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
    {
        $request = $this->getRepeatingInvoiceRequest($xero_tenant_id, $repeating_invoice_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getRepeatingInvoiceAsync
     * Retrieves a specific repeating invoice by using a unique repeating invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRepeatingInvoiceAsync($xero_tenant_id, $repeating_invoice_id)
    {
        return $this->getRepeatingInvoiceAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getRepeatingInvoiceAsyncWithHttpInfo
     * Retrieves a specific repeating invoice by using a unique repeating invoice Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getRepeatingInvoiceAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
        $request = $this->getRepeatingInvoiceRequest($xero_tenant_id, $repeating_invoice_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getRepeatingInvoice'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getRepeatingInvoiceRequest($xero_tenant_id, $repeating_invoice_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getRepeatingInvoice'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling getRepeatingInvoice'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getRepeatingInvoiceAttachmentByFileName
     * Retrieves a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getRepeatingInvoiceAttachmentByFileName($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type)
    {
        list($response) = $this->getRepeatingInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type);
        return $response;
    }
    /**
     * Operation getRepeatingInvoiceAttachmentByFileNameWithHttpInfo
     * Retrieves a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getRepeatingInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type)
    {
        $request = $this->getRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getRepeatingInvoiceAttachmentByFileNameAsync
     * Retrieves a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRepeatingInvoiceAttachmentByFileNameAsync($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type)
    {
        return $this->getRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getRepeatingInvoiceAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling getRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling getRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getRepeatingInvoiceAttachmentByFileName'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getRepeatingInvoiceAttachmentById
     * Retrieves a specific attachment from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \SplFileObject
     */
    public function getRepeatingInvoiceAttachmentById($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type)
    {
        list($response) = $this->getRepeatingInvoiceAttachmentByIdWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type);
        return $response;
    }
    /**
     * Operation getRepeatingInvoiceAttachmentByIdWithHttpInfo
     * Retrieves a specific attachment from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \SplFileObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function getRepeatingInvoiceAttachmentByIdWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type)
    {
        $request = $this->getRepeatingInvoiceAttachmentByIdRequest($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\SplFileObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\SplFileObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\SplFileObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\SplFileObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getRepeatingInvoiceAttachmentByIdAsync
     * Retrieves a specific attachment from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRepeatingInvoiceAttachmentByIdAsync($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type)
    {
        return $this->getRepeatingInvoiceAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getRepeatingInvoiceAttachmentByIdAsyncWithHttpInfo
     * Retrieves a specific attachment from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getRepeatingInvoiceAttachmentByIdAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type)
    {
        $returnType = '\SplFileObject';
        $request = $this->getRepeatingInvoiceAttachmentByIdRequest($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getRepeatingInvoiceAttachmentById'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $attachment_id Unique identifier for Attachment object (required)
     * @param  string $content_type The mime type of the attachment file you are retrieving i.e image/jpg, application/pdf (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getRepeatingInvoiceAttachmentByIdRequest($xero_tenant_id, $repeating_invoice_id, $attachment_id, $content_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getRepeatingInvoiceAttachmentById'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling getRepeatingInvoiceAttachmentById'
            );
        }
        // verify the required parameter 'attachment_id' is set
        if ($attachment_id === null || (is_array($attachment_id) && count($attachment_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $attachment_id when calling getRepeatingInvoiceAttachmentById'
            );
        }
        // verify the required parameter 'content_type' is set
        if ($content_type === null || (is_array($content_type) && count($content_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $content_type when calling getRepeatingInvoiceAttachmentById'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}/Attachments/{AttachmentID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($content_type !== null) {
            $headerParams['contentType'] = AccountingObjectSerializer::toHeaderValue($content_type);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($attachment_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AttachmentID' . '}',
                AccountingObjectSerializer::toPathValue($attachment_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/octet-stream']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/octet-stream'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getRepeatingInvoiceAttachments
     * Retrieves attachments from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments
     */
    public function getRepeatingInvoiceAttachments($xero_tenant_id, $repeating_invoice_id)
    {
        list($response) = $this->getRepeatingInvoiceAttachmentsWithHttpInfo($xero_tenant_id, $repeating_invoice_id);
        return $response;
    }
    /**
     * Operation getRepeatingInvoiceAttachmentsWithHttpInfo
     * Retrieves attachments from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments, HTTP status code, HTTP response headers (array of strings)
     */
    public function getRepeatingInvoiceAttachmentsWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
    {
        $request = $this->getRepeatingInvoiceAttachmentsRequest($xero_tenant_id, $repeating_invoice_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getRepeatingInvoiceAttachmentsAsync
     * Retrieves attachments from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRepeatingInvoiceAttachmentsAsync($xero_tenant_id, $repeating_invoice_id)
    {
        return $this->getRepeatingInvoiceAttachmentsAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getRepeatingInvoiceAttachmentsAsyncWithHttpInfo
     * Retrieves attachments from a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getRepeatingInvoiceAttachmentsAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->getRepeatingInvoiceAttachmentsRequest($xero_tenant_id, $repeating_invoice_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getRepeatingInvoiceAttachments'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getRepeatingInvoiceAttachmentsRequest($xero_tenant_id, $repeating_invoice_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getRepeatingInvoiceAttachments'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling getRepeatingInvoiceAttachments'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}/Attachments';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getRepeatingInvoiceHistory
     * Retrieves history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords
     */
    public function getRepeatingInvoiceHistory($xero_tenant_id, $repeating_invoice_id)
    {
        list($response) = $this->getRepeatingInvoiceHistoryWithHttpInfo($xero_tenant_id, $repeating_invoice_id);
        return $response;
    }
    /**
     * Operation getRepeatingInvoiceHistoryWithHttpInfo
     * Retrieves history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\HistoryRecords, HTTP status code, HTTP response headers (array of strings)
     */
    public function getRepeatingInvoiceHistoryWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
    {
        $request = $this->getRepeatingInvoiceHistoryRequest($xero_tenant_id, $repeating_invoice_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getRepeatingInvoiceHistoryAsync
     * Retrieves history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRepeatingInvoiceHistoryAsync($xero_tenant_id, $repeating_invoice_id)
    {
        return $this->getRepeatingInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getRepeatingInvoiceHistoryAsyncWithHttpInfo
     * Retrieves history record for a specific repeating invoice
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getRepeatingInvoiceHistoryAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\HistoryRecords';
        $request = $this->getRepeatingInvoiceHistoryRequest($xero_tenant_id, $repeating_invoice_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getRepeatingInvoiceHistory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getRepeatingInvoiceHistoryRequest($xero_tenant_id, $repeating_invoice_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getRepeatingInvoiceHistory'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling getRepeatingInvoiceHistory'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}/History';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getRepeatingInvoices
     * Retrieves repeating invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices
     */
    public function getRepeatingInvoices($xero_tenant_id, $where = null, $order = null)
    {
        list($response) = $this->getRepeatingInvoicesWithHttpInfo($xero_tenant_id, $where, $order);
        return $response;
    }
    /**
     * Operation getRepeatingInvoicesWithHttpInfo
     * Retrieves repeating invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices, HTTP status code, HTTP response headers (array of strings)
     */
    public function getRepeatingInvoicesWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $request = $this->getRepeatingInvoicesRequest($xero_tenant_id, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getRepeatingInvoicesAsync
     * Retrieves repeating invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getRepeatingInvoicesAsync($xero_tenant_id, $where = null, $order = null)
    {
        return $this->getRepeatingInvoicesAsyncWithHttpInfo($xero_tenant_id, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getRepeatingInvoicesAsyncWithHttpInfo
     * Retrieves repeating invoices
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getRepeatingInvoicesAsyncWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
        $request = $this->getRepeatingInvoicesRequest($xero_tenant_id, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getRepeatingInvoices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getRepeatingInvoicesRequest($xero_tenant_id, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getRepeatingInvoices'
            );
        }
        $resourcePath = '/RepeatingInvoices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportAgedPayablesByContact
     * Retrieves report for aged payables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Payables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportAgedPayablesByContact($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        list($response) = $this->getReportAgedPayablesByContactWithHttpInfo($xero_tenant_id, $contact_id, $date, $from_date, $to_date);
        return $response;
    }
    /**
     * Operation getReportAgedPayablesByContactWithHttpInfo
     * Retrieves report for aged payables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Payables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportAgedPayablesByContactWithHttpInfo($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        $request = $this->getReportAgedPayablesByContactRequest($xero_tenant_id, $contact_id, $date, $from_date, $to_date);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportAgedPayablesByContactAsync
     * Retrieves report for aged payables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Payables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportAgedPayablesByContactAsync($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        return $this->getReportAgedPayablesByContactAsyncWithHttpInfo($xero_tenant_id, $contact_id, $date, $from_date, $to_date)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportAgedPayablesByContactAsyncWithHttpInfo
     * Retrieves report for aged payables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Payables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportAgedPayablesByContactAsyncWithHttpInfo($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportAgedPayablesByContactRequest($xero_tenant_id, $contact_id, $date, $from_date, $to_date);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportAgedPayablesByContact'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Payables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportAgedPayablesByContactRequest($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportAgedPayablesByContact'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getReportAgedPayablesByContact'
            );
        }
        $resourcePath = '/Reports/AgedPayablesByContact';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($contact_id !== null) {
            $queryParams['contactId'] = AccountingObjectSerializer::toQueryValue($contact_id);
        }
        // query params
        if ($date !== null) {
            $queryParams['date'] = AccountingObjectSerializer::toQueryValue($date);
        }
        // query params
        if ($from_date !== null) {
            $queryParams['fromDate'] = AccountingObjectSerializer::toQueryValue($from_date);
        }
        // query params
        if ($to_date !== null) {
            $queryParams['toDate'] = AccountingObjectSerializer::toQueryValue($to_date);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportAgedReceivablesByContact
     * Retrieves report for aged receivables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Receivables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportAgedReceivablesByContact($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        list($response) = $this->getReportAgedReceivablesByContactWithHttpInfo($xero_tenant_id, $contact_id, $date, $from_date, $to_date);
        return $response;
    }
    /**
     * Operation getReportAgedReceivablesByContactWithHttpInfo
     * Retrieves report for aged receivables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Receivables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportAgedReceivablesByContactWithHttpInfo($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        $request = $this->getReportAgedReceivablesByContactRequest($xero_tenant_id, $contact_id, $date, $from_date, $to_date);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportAgedReceivablesByContactAsync
     * Retrieves report for aged receivables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Receivables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportAgedReceivablesByContactAsync($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        return $this->getReportAgedReceivablesByContactAsyncWithHttpInfo($xero_tenant_id, $contact_id, $date, $from_date, $to_date)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportAgedReceivablesByContactAsyncWithHttpInfo
     * Retrieves report for aged receivables by contact
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Receivables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportAgedReceivablesByContactAsyncWithHttpInfo($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportAgedReceivablesByContactRequest($xero_tenant_id, $contact_id, $date, $from_date, $to_date);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportAgedReceivablesByContact'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \DateTime $date The date of the Aged Receivables By Contact report (optional)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportAgedReceivablesByContactRequest($xero_tenant_id, $contact_id, $date = null, $from_date = null, $to_date = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportAgedReceivablesByContact'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling getReportAgedReceivablesByContact'
            );
        }
        $resourcePath = '/Reports/AgedReceivablesByContact';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($contact_id !== null) {
            $queryParams['contactId'] = AccountingObjectSerializer::toQueryValue($contact_id);
        }
        // query params
        if ($date !== null) {
            $queryParams['date'] = AccountingObjectSerializer::toQueryValue($date);
        }
        // query params
        if ($from_date !== null) {
            $queryParams['fromDate'] = AccountingObjectSerializer::toQueryValue($from_date);
        }
        // query params
        if ($to_date !== null) {
            $queryParams['toDate'] = AccountingObjectSerializer::toQueryValue($to_date);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportBalanceSheet
     * Retrieves report for balancesheet
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date of the Balance Sheet report (optional)
     * @param  int $periods The number of periods for the Balance Sheet report (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_option_id1 The tracking option 1 for the Balance Sheet report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the Balance Sheet report (optional)
     * @param  bool $standard_layout The standard layout boolean for the Balance Sheet report (optional)
     * @param  bool $payments_only return a cash basis for the Balance Sheet report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportBalanceSheet($xero_tenant_id, $date = null, $periods = null, $timeframe = null, $tracking_option_id1 = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        list($response) = $this->getReportBalanceSheetWithHttpInfo($xero_tenant_id, $date, $periods, $timeframe, $tracking_option_id1, $tracking_option_id2, $standard_layout, $payments_only);
        return $response;
    }
    /**
     * Operation getReportBalanceSheetWithHttpInfo
     * Retrieves report for balancesheet
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date of the Balance Sheet report (optional)
     * @param  int $periods The number of periods for the Balance Sheet report (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_option_id1 The tracking option 1 for the Balance Sheet report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the Balance Sheet report (optional)
     * @param  bool $standard_layout The standard layout boolean for the Balance Sheet report (optional)
     * @param  bool $payments_only return a cash basis for the Balance Sheet report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportBalanceSheetWithHttpInfo($xero_tenant_id, $date = null, $periods = null, $timeframe = null, $tracking_option_id1 = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        $request = $this->getReportBalanceSheetRequest($xero_tenant_id, $date, $periods, $timeframe, $tracking_option_id1, $tracking_option_id2, $standard_layout, $payments_only);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportBalanceSheetAsync
     * Retrieves report for balancesheet
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date of the Balance Sheet report (optional)
     * @param  int $periods The number of periods for the Balance Sheet report (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_option_id1 The tracking option 1 for the Balance Sheet report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the Balance Sheet report (optional)
     * @param  bool $standard_layout The standard layout boolean for the Balance Sheet report (optional)
     * @param  bool $payments_only return a cash basis for the Balance Sheet report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportBalanceSheetAsync($xero_tenant_id, $date = null, $periods = null, $timeframe = null, $tracking_option_id1 = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        return $this->getReportBalanceSheetAsyncWithHttpInfo($xero_tenant_id, $date, $periods, $timeframe, $tracking_option_id1, $tracking_option_id2, $standard_layout, $payments_only)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportBalanceSheetAsyncWithHttpInfo
     * Retrieves report for balancesheet
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date of the Balance Sheet report (optional)
     * @param  int $periods The number of periods for the Balance Sheet report (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_option_id1 The tracking option 1 for the Balance Sheet report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the Balance Sheet report (optional)
     * @param  bool $standard_layout The standard layout boolean for the Balance Sheet report (optional)
     * @param  bool $payments_only return a cash basis for the Balance Sheet report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportBalanceSheetAsyncWithHttpInfo($xero_tenant_id, $date = null, $periods = null, $timeframe = null, $tracking_option_id1 = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportBalanceSheetRequest($xero_tenant_id, $date, $periods, $timeframe, $tracking_option_id1, $tracking_option_id2, $standard_layout, $payments_only);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportBalanceSheet'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date of the Balance Sheet report (optional)
     * @param  int $periods The number of periods for the Balance Sheet report (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_option_id1 The tracking option 1 for the Balance Sheet report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the Balance Sheet report (optional)
     * @param  bool $standard_layout The standard layout boolean for the Balance Sheet report (optional)
     * @param  bool $payments_only return a cash basis for the Balance Sheet report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportBalanceSheetRequest($xero_tenant_id, $date = null, $periods = null, $timeframe = null, $tracking_option_id1 = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportBalanceSheet'
            );
        }
        $resourcePath = '/Reports/BalanceSheet';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($date !== null) {
            $queryParams['date'] = AccountingObjectSerializer::toQueryValue($date);
        }
        // query params
        if ($periods !== null) {
            $queryParams['periods'] = AccountingObjectSerializer::toQueryValue($periods);
        }
        // query params
        if ($timeframe !== null) {
            $queryParams['timeframe'] = AccountingObjectSerializer::toQueryValue($timeframe);
        }
        // query params
        if ($tracking_option_id1 !== null) {
            $queryParams['trackingOptionID1'] = AccountingObjectSerializer::toQueryValue($tracking_option_id1);
        }
        // query params
        if ($tracking_option_id2 !== null) {
            $queryParams['trackingOptionID2'] = AccountingObjectSerializer::toQueryValue($tracking_option_id2);
        }
        // query params
        if ($standard_layout !== null) {
            $queryParams['standardLayout'] = $standard_layout ? 'true' : 'false';
        }
        // query params
        if ($payments_only !== null) {
            $queryParams['paymentsOnly'] = $payments_only ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportBankSummary
     * Retrieves report for bank summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportBankSummary($xero_tenant_id, $from_date = null, $to_date = null)
    {
        list($response) = $this->getReportBankSummaryWithHttpInfo($xero_tenant_id, $from_date, $to_date);
        return $response;
    }
    /**
     * Operation getReportBankSummaryWithHttpInfo
     * Retrieves report for bank summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportBankSummaryWithHttpInfo($xero_tenant_id, $from_date = null, $to_date = null)
    {
        $request = $this->getReportBankSummaryRequest($xero_tenant_id, $from_date, $to_date);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportBankSummaryAsync
     * Retrieves report for bank summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportBankSummaryAsync($xero_tenant_id, $from_date = null, $to_date = null)
    {
        return $this->getReportBankSummaryAsyncWithHttpInfo($xero_tenant_id, $from_date, $to_date)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportBankSummaryAsyncWithHttpInfo
     * Retrieves report for bank summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportBankSummaryAsyncWithHttpInfo($xero_tenant_id, $from_date = null, $to_date = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportBankSummaryRequest($xero_tenant_id, $from_date, $to_date);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportBankSummary'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportBankSummaryRequest($xero_tenant_id, $from_date = null, $to_date = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportBankSummary'
            );
        }
        $resourcePath = '/Reports/BankSummary';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($from_date !== null) {
            $queryParams['fromDate'] = AccountingObjectSerializer::toQueryValue($from_date);
        }
        // query params
        if ($to_date !== null) {
            $queryParams['toDate'] = AccountingObjectSerializer::toQueryValue($to_date);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportBudgetSummary
     * Retrieves report for budget summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  int $timeframe The period size to compare to (1&#x3D;month, 3&#x3D;quarter, 12&#x3D;year) (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportBudgetSummary($xero_tenant_id, $date = null, $periods = null, $timeframe = null)
    {
        list($response) = $this->getReportBudgetSummaryWithHttpInfo($xero_tenant_id, $date, $periods, $timeframe);
        return $response;
    }
    /**
     * Operation getReportBudgetSummaryWithHttpInfo
     * Retrieves report for budget summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  int $timeframe The period size to compare to (1&#x3D;month, 3&#x3D;quarter, 12&#x3D;year) (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportBudgetSummaryWithHttpInfo($xero_tenant_id, $date = null, $periods = null, $timeframe = null)
    {
        $request = $this->getReportBudgetSummaryRequest($xero_tenant_id, $date, $periods, $timeframe);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportBudgetSummaryAsync
     * Retrieves report for budget summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  int $timeframe The period size to compare to (1&#x3D;month, 3&#x3D;quarter, 12&#x3D;year) (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportBudgetSummaryAsync($xero_tenant_id, $date = null, $periods = null, $timeframe = null)
    {
        return $this->getReportBudgetSummaryAsyncWithHttpInfo($xero_tenant_id, $date, $periods, $timeframe)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportBudgetSummaryAsyncWithHttpInfo
     * Retrieves report for budget summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  int $timeframe The period size to compare to (1&#x3D;month, 3&#x3D;quarter, 12&#x3D;year) (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportBudgetSummaryAsyncWithHttpInfo($xero_tenant_id, $date = null, $periods = null, $timeframe = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportBudgetSummaryRequest($xero_tenant_id, $date, $periods, $timeframe);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportBudgetSummary'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  int $timeframe The period size to compare to (1&#x3D;month, 3&#x3D;quarter, 12&#x3D;year) (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportBudgetSummaryRequest($xero_tenant_id, $date = null, $periods = null, $timeframe = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportBudgetSummary'
            );
        }
        $resourcePath = '/Reports/BudgetSummary';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($date !== null) {
            $queryParams['date'] = AccountingObjectSerializer::toQueryValue($date);
        }
        // query params
        if ($periods !== null) {
            $queryParams['periods'] = AccountingObjectSerializer::toQueryValue($periods);
        }
        // query params
        if ($timeframe !== null) {
            $queryParams['timeframe'] = AccountingObjectSerializer::toQueryValue($timeframe);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportExecutiveSummary
     * Retrieves report for executive summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportExecutiveSummary($xero_tenant_id, $date = null)
    {
        list($response) = $this->getReportExecutiveSummaryWithHttpInfo($xero_tenant_id, $date);
        return $response;
    }
    /**
     * Operation getReportExecutiveSummaryWithHttpInfo
     * Retrieves report for executive summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportExecutiveSummaryWithHttpInfo($xero_tenant_id, $date = null)
    {
        $request = $this->getReportExecutiveSummaryRequest($xero_tenant_id, $date);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportExecutiveSummaryAsync
     * Retrieves report for executive summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportExecutiveSummaryAsync($xero_tenant_id, $date = null)
    {
        return $this->getReportExecutiveSummaryAsyncWithHttpInfo($xero_tenant_id, $date)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportExecutiveSummaryAsyncWithHttpInfo
     * Retrieves report for executive summary
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportExecutiveSummaryAsyncWithHttpInfo($xero_tenant_id, $date = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportExecutiveSummaryRequest($xero_tenant_id, $date);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportExecutiveSummary'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Bank Summary report e.g. 2018-03-31 (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportExecutiveSummaryRequest($xero_tenant_id, $date = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportExecutiveSummary'
            );
        }
        $resourcePath = '/Reports/ExecutiveSummary';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($date !== null) {
            $queryParams['date'] = AccountingObjectSerializer::toQueryValue($date);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportFromId
     * Retrieves a specific report using a unique ReportID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_id Unique identifier for a Report (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportFromId($xero_tenant_id, $report_id)
    {
        list($response) = $this->getReportFromIdWithHttpInfo($xero_tenant_id, $report_id);
        return $response;
    }
    /**
     * Operation getReportFromIdWithHttpInfo
     * Retrieves a specific report using a unique ReportID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_id Unique identifier for a Report (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportFromIdWithHttpInfo($xero_tenant_id, $report_id)
    {
        $request = $this->getReportFromIdRequest($xero_tenant_id, $report_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportFromIdAsync
     * Retrieves a specific report using a unique ReportID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_id Unique identifier for a Report (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportFromIdAsync($xero_tenant_id, $report_id)
    {
        return $this->getReportFromIdAsyncWithHttpInfo($xero_tenant_id, $report_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportFromIdAsyncWithHttpInfo
     * Retrieves a specific report using a unique ReportID
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_id Unique identifier for a Report (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportFromIdAsyncWithHttpInfo($xero_tenant_id, $report_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportFromIdRequest($xero_tenant_id, $report_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportFromId'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_id Unique identifier for a Report (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportFromIdRequest($xero_tenant_id, $report_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportFromId'
            );
        }
        // verify the required parameter 'report_id' is set
        if ($report_id === null || (is_array($report_id) && count($report_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $report_id when calling getReportFromId'
            );
        }
        $resourcePath = '/Reports/{ReportID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($report_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReportID' . '}',
                AccountingObjectSerializer::toPathValue($report_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportProfitAndLoss
     * Retrieves report for profit and loss
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_category_id The trackingCategory 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_category_id2 The trackingCategory 2 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id The tracking option 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the ProfitAndLoss report (optional)
     * @param  bool $standard_layout Return the standard layout for the ProfitAndLoss report (optional)
     * @param  bool $payments_only Return cash only basis for the ProfitAndLoss report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportProfitAndLoss($xero_tenant_id, $from_date = null, $to_date = null, $periods = null, $timeframe = null, $tracking_category_id = null, $tracking_category_id2 = null, $tracking_option_id = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        list($response) = $this->getReportProfitAndLossWithHttpInfo($xero_tenant_id, $from_date, $to_date, $periods, $timeframe, $tracking_category_id, $tracking_category_id2, $tracking_option_id, $tracking_option_id2, $standard_layout, $payments_only);
        return $response;
    }
    /**
     * Operation getReportProfitAndLossWithHttpInfo
     * Retrieves report for profit and loss
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_category_id The trackingCategory 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_category_id2 The trackingCategory 2 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id The tracking option 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the ProfitAndLoss report (optional)
     * @param  bool $standard_layout Return the standard layout for the ProfitAndLoss report (optional)
     * @param  bool $payments_only Return cash only basis for the ProfitAndLoss report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportProfitAndLossWithHttpInfo($xero_tenant_id, $from_date = null, $to_date = null, $periods = null, $timeframe = null, $tracking_category_id = null, $tracking_category_id2 = null, $tracking_option_id = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        $request = $this->getReportProfitAndLossRequest($xero_tenant_id, $from_date, $to_date, $periods, $timeframe, $tracking_category_id, $tracking_category_id2, $tracking_option_id, $tracking_option_id2, $standard_layout, $payments_only);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportProfitAndLossAsync
     * Retrieves report for profit and loss
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_category_id The trackingCategory 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_category_id2 The trackingCategory 2 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id The tracking option 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the ProfitAndLoss report (optional)
     * @param  bool $standard_layout Return the standard layout for the ProfitAndLoss report (optional)
     * @param  bool $payments_only Return cash only basis for the ProfitAndLoss report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportProfitAndLossAsync($xero_tenant_id, $from_date = null, $to_date = null, $periods = null, $timeframe = null, $tracking_category_id = null, $tracking_category_id2 = null, $tracking_option_id = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        return $this->getReportProfitAndLossAsyncWithHttpInfo($xero_tenant_id, $from_date, $to_date, $periods, $timeframe, $tracking_category_id, $tracking_category_id2, $tracking_option_id, $tracking_option_id2, $standard_layout, $payments_only)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportProfitAndLossAsyncWithHttpInfo
     * Retrieves report for profit and loss
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_category_id The trackingCategory 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_category_id2 The trackingCategory 2 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id The tracking option 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the ProfitAndLoss report (optional)
     * @param  bool $standard_layout Return the standard layout for the ProfitAndLoss report (optional)
     * @param  bool $payments_only Return cash only basis for the ProfitAndLoss report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportProfitAndLossAsyncWithHttpInfo($xero_tenant_id, $from_date = null, $to_date = null, $periods = null, $timeframe = null, $tracking_category_id = null, $tracking_category_id2 = null, $tracking_option_id = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportProfitAndLossRequest($xero_tenant_id, $from_date, $to_date, $periods, $timeframe, $tracking_category_id, $tracking_category_id2, $tracking_option_id, $tracking_option_id2, $standard_layout, $payments_only);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportProfitAndLoss'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $from_date filter by the from date of the report e.g. 2021-02-01 (optional)
     * @param  \DateTime $to_date filter by the to date of the report e.g. 2021-02-28 (optional)
     * @param  int $periods The number of periods to compare (integer between 1 and 12) (optional)
     * @param  string $timeframe The period size to compare to (MONTH, QUARTER, YEAR) (optional)
     * @param  string $tracking_category_id The trackingCategory 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_category_id2 The trackingCategory 2 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id The tracking option 1 for the ProfitAndLoss report (optional)
     * @param  string $tracking_option_id2 The tracking option 2 for the ProfitAndLoss report (optional)
     * @param  bool $standard_layout Return the standard layout for the ProfitAndLoss report (optional)
     * @param  bool $payments_only Return cash only basis for the ProfitAndLoss report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportProfitAndLossRequest($xero_tenant_id, $from_date = null, $to_date = null, $periods = null, $timeframe = null, $tracking_category_id = null, $tracking_category_id2 = null, $tracking_option_id = null, $tracking_option_id2 = null, $standard_layout = null, $payments_only = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportProfitAndLoss'
            );
        }
        $resourcePath = '/Reports/ProfitAndLoss';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($from_date !== null) {
            $queryParams['fromDate'] = AccountingObjectSerializer::toQueryValue($from_date);
        }
        // query params
        if ($to_date !== null) {
            $queryParams['toDate'] = AccountingObjectSerializer::toQueryValue($to_date);
        }
        // query params
        if ($periods !== null) {
            $queryParams['periods'] = AccountingObjectSerializer::toQueryValue($periods);
        }
        // query params
        if ($timeframe !== null) {
            $queryParams['timeframe'] = AccountingObjectSerializer::toQueryValue($timeframe);
        }
        // query params
        if ($tracking_category_id !== null) {
            $queryParams['trackingCategoryID'] = AccountingObjectSerializer::toQueryValue($tracking_category_id);
        }
        // query params
        if ($tracking_category_id2 !== null) {
            $queryParams['trackingCategoryID2'] = AccountingObjectSerializer::toQueryValue($tracking_category_id2);
        }
        // query params
        if ($tracking_option_id !== null) {
            $queryParams['trackingOptionID'] = AccountingObjectSerializer::toQueryValue($tracking_option_id);
        }
        // query params
        if ($tracking_option_id2 !== null) {
            $queryParams['trackingOptionID2'] = AccountingObjectSerializer::toQueryValue($tracking_option_id2);
        }
        // query params
        if ($standard_layout !== null) {
            $queryParams['standardLayout'] = $standard_layout ? 'true' : 'false';
        }
        // query params
        if ($payments_only !== null) {
            $queryParams['paymentsOnly'] = $payments_only ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportTenNinetyNine
     * Retrieve reports for 1099
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_year The year of the 1099 report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Reports
     */
    public function getReportTenNinetyNine($xero_tenant_id, $report_year = null)
    {
        list($response) = $this->getReportTenNinetyNineWithHttpInfo($xero_tenant_id, $report_year);
        return $response;
    }
    /**
     * Operation getReportTenNinetyNineWithHttpInfo
     * Retrieve reports for 1099
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_year The year of the 1099 report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Reports, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportTenNinetyNineWithHttpInfo($xero_tenant_id, $report_year = null)
    {
        $request = $this->getReportTenNinetyNineRequest($xero_tenant_id, $report_year);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Reports' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Reports', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Reports';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Reports',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportTenNinetyNineAsync
     * Retrieve reports for 1099
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_year The year of the 1099 report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportTenNinetyNineAsync($xero_tenant_id, $report_year = null)
    {
        return $this->getReportTenNinetyNineAsyncWithHttpInfo($xero_tenant_id, $report_year)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportTenNinetyNineAsyncWithHttpInfo
     * Retrieve reports for 1099
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_year The year of the 1099 report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportTenNinetyNineAsyncWithHttpInfo($xero_tenant_id, $report_year = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Reports';
        $request = $this->getReportTenNinetyNineRequest($xero_tenant_id, $report_year);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportTenNinetyNine'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $report_year The year of the 1099 report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportTenNinetyNineRequest($xero_tenant_id, $report_year = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportTenNinetyNine'
            );
        }
        $resourcePath = '/Reports/TenNinetyNine';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($report_year !== null) {
            $queryParams['reportYear'] = AccountingObjectSerializer::toQueryValue($report_year);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportTrialBalance
     * Retrieves report for trial balance
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Trial Balance report e.g. 2018-03-31 (optional)
     * @param  bool $payments_only Return cash only basis for the Trial Balance report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportTrialBalance($xero_tenant_id, $date = null, $payments_only = null)
    {
        list($response) = $this->getReportTrialBalanceWithHttpInfo($xero_tenant_id, $date, $payments_only);
        return $response;
    }
    /**
     * Operation getReportTrialBalanceWithHttpInfo
     * Retrieves report for trial balance
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Trial Balance report e.g. 2018-03-31 (optional)
     * @param  bool $payments_only Return cash only basis for the Trial Balance report (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportTrialBalanceWithHttpInfo($xero_tenant_id, $date = null, $payments_only = null)
    {
        $request = $this->getReportTrialBalanceRequest($xero_tenant_id, $date, $payments_only);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportTrialBalanceAsync
     * Retrieves report for trial balance
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Trial Balance report e.g. 2018-03-31 (optional)
     * @param  bool $payments_only Return cash only basis for the Trial Balance report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportTrialBalanceAsync($xero_tenant_id, $date = null, $payments_only = null)
    {
        return $this->getReportTrialBalanceAsyncWithHttpInfo($xero_tenant_id, $date, $payments_only)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportTrialBalanceAsyncWithHttpInfo
     * Retrieves report for trial balance
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Trial Balance report e.g. 2018-03-31 (optional)
     * @param  bool $payments_only Return cash only basis for the Trial Balance report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportTrialBalanceAsyncWithHttpInfo($xero_tenant_id, $date = null, $payments_only = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportTrialBalanceRequest($xero_tenant_id, $date, $payments_only);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportTrialBalance'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $date The date for the Trial Balance report e.g. 2018-03-31 (optional)
     * @param  bool $payments_only Return cash only basis for the Trial Balance report (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportTrialBalanceRequest($xero_tenant_id, $date = null, $payments_only = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportTrialBalance'
            );
        }
        $resourcePath = '/Reports/TrialBalance';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($date !== null) {
            $queryParams['date'] = AccountingObjectSerializer::toQueryValue($date);
        }
        // query params
        if ($payments_only !== null) {
            $queryParams['paymentsOnly'] = $payments_only ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getReportsList
     * Retrieves a list of the organistaions unique reports that require a uuid to fetch
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows
     */
    public function getReportsList($xero_tenant_id)
    {
        list($response) = $this->getReportsListWithHttpInfo($xero_tenant_id);
        return $response;
    }
    /**
     * Operation getReportsListWithHttpInfo
     * Retrieves a list of the organistaions unique reports that require a uuid to fetch
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ReportWithRows, HTTP status code, HTTP response headers (array of strings)
     */
    public function getReportsListWithHttpInfo($xero_tenant_id)
    {
        $request = $this->getReportsListRequest($xero_tenant_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getReportsListAsync
     * Retrieves a list of the organistaions unique reports that require a uuid to fetch
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getReportsListAsync($xero_tenant_id)
    {
        return $this->getReportsListAsyncWithHttpInfo($xero_tenant_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getReportsListAsyncWithHttpInfo
     * Retrieves a list of the organistaions unique reports that require a uuid to fetch
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getReportsListAsyncWithHttpInfo($xero_tenant_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ReportWithRows';
        $request = $this->getReportsListRequest($xero_tenant_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getReportsList'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getReportsListRequest($xero_tenant_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getReportsList'
            );
        }
        $resourcePath = '/Reports';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getTaxRateByTaxType
     * Retrieves a specific tax rate according to given TaxType code
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tax_type A valid TaxType code (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TaxRates
     */
    public function getTaxRateByTaxType($xero_tenant_id, $tax_type)
    {
        list($response) = $this->getTaxRateByTaxTypeWithHttpInfo($xero_tenant_id, $tax_type);
        return $response;
    }
    /**
     * Operation getTaxRateByTaxTypeWithHttpInfo
     * Retrieves a specific tax rate according to given TaxType code
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tax_type A valid TaxType code (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TaxRates, HTTP status code, HTTP response headers (array of strings)
     */
    public function getTaxRateByTaxTypeWithHttpInfo($xero_tenant_id, $tax_type)
    {
        $request = $this->getTaxRateByTaxTypeRequest($xero_tenant_id, $tax_type);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TaxRates' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TaxRates', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TaxRates',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getTaxRateByTaxTypeAsync
     * Retrieves a specific tax rate according to given TaxType code
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tax_type A valid TaxType code (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getTaxRateByTaxTypeAsync($xero_tenant_id, $tax_type)
    {
        return $this->getTaxRateByTaxTypeAsyncWithHttpInfo($xero_tenant_id, $tax_type)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getTaxRateByTaxTypeAsyncWithHttpInfo
     * Retrieves a specific tax rate according to given TaxType code
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tax_type A valid TaxType code (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getTaxRateByTaxTypeAsyncWithHttpInfo($xero_tenant_id, $tax_type)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
        $request = $this->getTaxRateByTaxTypeRequest($xero_tenant_id, $tax_type);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getTaxRateByTaxType'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tax_type A valid TaxType code (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getTaxRateByTaxTypeRequest($xero_tenant_id, $tax_type)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getTaxRateByTaxType'
            );
        }
        // verify the required parameter 'tax_type' is set
        if ($tax_type === null || (is_array($tax_type) && count($tax_type) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tax_type when calling getTaxRateByTaxType'
            );
        }
        $resourcePath = '/TaxRates/{TaxType}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($tax_type !== null) {
            $resourcePath = str_replace(
                '{' . 'TaxType' . '}',
                AccountingObjectSerializer::toPathValue($tax_type),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getTaxRates
     * Retrieves tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TaxRates
     */
    public function getTaxRates($xero_tenant_id, $where = null, $order = null)
    {
        list($response) = $this->getTaxRatesWithHttpInfo($xero_tenant_id, $where, $order);
        return $response;
    }
    /**
     * Operation getTaxRatesWithHttpInfo
     * Retrieves tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TaxRates, HTTP status code, HTTP response headers (array of strings)
     */
    public function getTaxRatesWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $request = $this->getTaxRatesRequest($xero_tenant_id, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TaxRates' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TaxRates', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TaxRates',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getTaxRatesAsync
     * Retrieves tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getTaxRatesAsync($xero_tenant_id, $where = null, $order = null)
    {
        return $this->getTaxRatesAsyncWithHttpInfo($xero_tenant_id, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getTaxRatesAsyncWithHttpInfo
     * Retrieves tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getTaxRatesAsyncWithHttpInfo($xero_tenant_id, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
        $request = $this->getTaxRatesRequest($xero_tenant_id, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getTaxRates'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getTaxRatesRequest($xero_tenant_id, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getTaxRates'
            );
        }
        $resourcePath = '/TaxRates';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getTrackingCategories
     * Retrieves tracking categories and options
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Categories and options with a status of ARCHIVED will be included in the response (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories
     */
    public function getTrackingCategories($xero_tenant_id, $where = null, $order = null, $include_archived = null)
    {
        list($response) = $this->getTrackingCategoriesWithHttpInfo($xero_tenant_id, $where, $order, $include_archived);
        return $response;
    }
    /**
     * Operation getTrackingCategoriesWithHttpInfo
     * Retrieves tracking categories and options
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Categories and options with a status of ARCHIVED will be included in the response (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories, HTTP status code, HTTP response headers (array of strings)
     */
    public function getTrackingCategoriesWithHttpInfo($xero_tenant_id, $where = null, $order = null, $include_archived = null)
    {
        $request = $this->getTrackingCategoriesRequest($xero_tenant_id, $where, $order, $include_archived);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getTrackingCategoriesAsync
     * Retrieves tracking categories and options
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Categories and options with a status of ARCHIVED will be included in the response (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getTrackingCategoriesAsync($xero_tenant_id, $where = null, $order = null, $include_archived = null)
    {
        return $this->getTrackingCategoriesAsyncWithHttpInfo($xero_tenant_id, $where, $order, $include_archived)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getTrackingCategoriesAsyncWithHttpInfo
     * Retrieves tracking categories and options
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Categories and options with a status of ARCHIVED will be included in the response (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getTrackingCategoriesAsyncWithHttpInfo($xero_tenant_id, $where = null, $order = null, $include_archived = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
        $request = $this->getTrackingCategoriesRequest($xero_tenant_id, $where, $order, $include_archived);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getTrackingCategories'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @param  bool $include_archived e.g. includeArchived&#x3D;true - Categories and options with a status of ARCHIVED will be included in the response (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getTrackingCategoriesRequest($xero_tenant_id, $where = null, $order = null, $include_archived = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getTrackingCategories'
            );
        }
        $resourcePath = '/TrackingCategories';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // query params
        if ($include_archived !== null) {
            $queryParams['includeArchived'] = $include_archived ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getTrackingCategory
     * Retrieves specific tracking categories and options using a unique tracking category Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories
     */
    public function getTrackingCategory($xero_tenant_id, $tracking_category_id)
    {
        list($response) = $this->getTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category_id);
        return $response;
    }
    /**
     * Operation getTrackingCategoryWithHttpInfo
     * Retrieves specific tracking categories and options using a unique tracking category Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories, HTTP status code, HTTP response headers (array of strings)
     */
    public function getTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category_id)
    {
        $request = $this->getTrackingCategoryRequest($xero_tenant_id, $tracking_category_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getTrackingCategoryAsync
     * Retrieves specific tracking categories and options using a unique tracking category Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getTrackingCategoryAsync($xero_tenant_id, $tracking_category_id)
    {
        return $this->getTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getTrackingCategoryAsyncWithHttpInfo
     * Retrieves specific tracking categories and options using a unique tracking category Id
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
        $request = $this->getTrackingCategoryRequest($xero_tenant_id, $tracking_category_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getTrackingCategory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getTrackingCategoryRequest($xero_tenant_id, $tracking_category_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getTrackingCategory'
            );
        }
        // verify the required parameter 'tracking_category_id' is set
        if ($tracking_category_id === null || (is_array($tracking_category_id) && count($tracking_category_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category_id when calling getTrackingCategory'
            );
        }
        $resourcePath = '/TrackingCategories/{TrackingCategoryID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($tracking_category_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingCategoryID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_category_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getUser
     * Retrieves a specific user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $user_id Unique identifier for a User (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Users
     */
    public function getUser($xero_tenant_id, $user_id)
    {
        list($response) = $this->getUserWithHttpInfo($xero_tenant_id, $user_id);
        return $response;
    }
    /**
     * Operation getUserWithHttpInfo
     * Retrieves a specific user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $user_id Unique identifier for a User (required)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Users, HTTP status code, HTTP response headers (array of strings)
     */
    public function getUserWithHttpInfo($xero_tenant_id, $user_id)
    {
        $request = $this->getUserRequest($xero_tenant_id, $user_id);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Users' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Users', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Users';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Users',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getUserAsync
     * Retrieves a specific user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $user_id Unique identifier for a User (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getUserAsync($xero_tenant_id, $user_id)
    {
        return $this->getUserAsyncWithHttpInfo($xero_tenant_id, $user_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getUserAsyncWithHttpInfo
     * Retrieves a specific user
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $user_id Unique identifier for a User (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getUserAsyncWithHttpInfo($xero_tenant_id, $user_id)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Users';
        $request = $this->getUserRequest($xero_tenant_id, $user_id);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getUser'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $user_id Unique identifier for a User (required)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getUserRequest($xero_tenant_id, $user_id)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getUser'
            );
        }
        // verify the required parameter 'user_id' is set
        if ($user_id === null || (is_array($user_id) && count($user_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $user_id when calling getUser'
            );
        }
        $resourcePath = '/Users/{UserID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // path params
        if ($user_id !== null) {
            $resourcePath = str_replace(
                '{' . 'UserID' . '}',
                AccountingObjectSerializer::toPathValue($user_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getUsers
     * Retrieves users
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Users
     */
    public function getUsers($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        list($response) = $this->getUsersWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order);
        return $response;
    }
    /**
     * Operation getUsersWithHttpInfo
     * Retrieves users
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Users, HTTP status code, HTTP response headers (array of strings)
     */
    public function getUsersWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $request = $this->getUsersRequest($xero_tenant_id, $if_modified_since, $where, $order);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Users' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Users', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Users';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Users',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation getUsersAsync
     * Retrieves users
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getUsersAsync($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        return $this->getUsersAsyncWithHttpInfo($xero_tenant_id, $if_modified_since, $where, $order)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation getUsersAsyncWithHttpInfo
     * Retrieves users
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function getUsersAsyncWithHttpInfo($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Users';
        $request = $this->getUsersRequest($xero_tenant_id, $if_modified_since, $where, $order);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getUsers'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \DateTime $if_modified_since Only records created or modified since this timestamp will be returned (optional)
     * @param  string $where Filter by an any element (optional)
     * @param  string $order Order by an any element (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function getUsersRequest($xero_tenant_id, $if_modified_since = null, $where = null, $order = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling getUsers'
            );
        }
        $resourcePath = '/Users';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($where !== null) {
            $queryParams['where'] = AccountingObjectSerializer::toQueryValue($where);
        }
        // query params
        if ($order !== null) {
            $queryParams['order'] = AccountingObjectSerializer::toQueryValue($order);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($if_modified_since !== null) {
            $headerParams['If-Modified-Since'] = AccountingObjectSerializer::toHeaderValue($if_modified_since);
        }
        // body params
        $_tempBody = null;
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation postSetup
     * Sets the chart of accounts, the conversion date and conversion balances
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Setup $setup Object including an accounts array, a conversion balances array and a conversion date object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ImportSummaryObject
     */
    public function postSetup($xero_tenant_id, $setup, $idempotency_key = null)
    {
        list($response) = $this->postSetupWithHttpInfo($xero_tenant_id, $setup, $idempotency_key);
        return $response;
    }
    /**
     * Operation postSetupWithHttpInfo
     * Sets the chart of accounts, the conversion date and conversion balances
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Setup $setup Object including an accounts array, a conversion balances array and a conversion date object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ImportSummaryObject, HTTP status code, HTTP response headers (array of strings)
     */
    public function postSetupWithHttpInfo($xero_tenant_id, $setup, $idempotency_key = null)
    {
        $request = $this->postSetupRequest($xero_tenant_id, $setup, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ImportSummaryObject' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ImportSummaryObject', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ImportSummaryObject';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ImportSummaryObject',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation postSetupAsync
     * Sets the chart of accounts, the conversion date and conversion balances
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Setup $setup Object including an accounts array, a conversion balances array and a conversion date object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function postSetupAsync($xero_tenant_id, $setup, $idempotency_key = null)
    {
        return $this->postSetupAsyncWithHttpInfo($xero_tenant_id, $setup, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation postSetupAsyncWithHttpInfo
     * Sets the chart of accounts, the conversion date and conversion balances
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Setup $setup Object including an accounts array, a conversion balances array and a conversion date object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function postSetupAsyncWithHttpInfo($xero_tenant_id, $setup, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ImportSummaryObject';
        $request = $this->postSetupRequest($xero_tenant_id, $setup, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'postSetup'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Setup $setup Object including an accounts array, a conversion balances array and a conversion date object in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function postSetupRequest($xero_tenant_id, $setup, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling postSetup'
            );
        }
        // verify the required parameter 'setup' is set
        if ($setup === null || (is_array($setup) && count($setup) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $setup when calling postSetup'
            );
        }
        $resourcePath = '/Setup';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($setup)) {
            $_tempBody = $setup;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateAccount
     * Updates a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Accounts $accounts Request of type Accounts array with one Account (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Accounts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateAccount($xero_tenant_id, $account_id, $accounts, $idempotency_key = null)
    {
        list($response) = $this->updateAccountWithHttpInfo($xero_tenant_id, $account_id, $accounts, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateAccountWithHttpInfo
     * Updates a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Accounts $accounts Request of type Accounts array with one Account (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Accounts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateAccountWithHttpInfo($xero_tenant_id, $account_id, $accounts, $idempotency_key = null)
    {
        $request = $this->updateAccountRequest($xero_tenant_id, $account_id, $accounts, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Accounts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Accounts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Accounts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateAccountAsync
     * Updates a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Accounts $accounts Request of type Accounts array with one Account (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateAccountAsync($xero_tenant_id, $account_id, $accounts, $idempotency_key = null)
    {
        return $this->updateAccountAsyncWithHttpInfo($xero_tenant_id, $account_id, $accounts, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateAccountAsyncWithHttpInfo
     * Updates a chart of accounts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Accounts $accounts Request of type Accounts array with one Account (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateAccountAsyncWithHttpInfo($xero_tenant_id, $account_id, $accounts, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Accounts';
        $request = $this->updateAccountRequest($xero_tenant_id, $account_id, $accounts, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateAccount'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Accounts $accounts Request of type Accounts array with one Account (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateAccountRequest($xero_tenant_id, $account_id, $accounts, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateAccount'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling updateAccount'
            );
        }
        // verify the required parameter 'accounts' is set
        if ($accounts === null || (is_array($accounts) && count($accounts) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $accounts when calling updateAccount'
            );
        }
        $resourcePath = '/Accounts/{AccountID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($accounts)) {
            $_tempBody = $accounts;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateAccountAttachmentByFileName
     * Updates attachment on a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateAccountAttachmentByFileName($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateAccountAttachmentByFileNameWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateAccountAttachmentByFileNameWithHttpInfo
     * Updates attachment on a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateAccountAttachmentByFileNameWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateAccountAttachmentByFileNameAsync
     * Updates attachment on a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateAccountAttachmentByFileNameAsync($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateAccountAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateAccountAttachmentByFileNameAsyncWithHttpInfo
     * Updates attachment on a specific account by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateAccountAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateAccountAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $account_id Unique identifier for Account object (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateAccountAttachmentByFileNameRequest($xero_tenant_id, $account_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'account_id' is set
        if ($account_id === null || (is_array($account_id) && count($account_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $account_id when calling updateAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateAccountAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateAccountAttachmentByFileName'
            );
        }
        $resourcePath = '/Accounts/{AccountID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($account_id !== null) {
            $resourcePath = str_replace(
                '{' . 'AccountID' . '}',
                AccountingObjectSerializer::toPathValue($account_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateBankTransaction
     * Updates a single spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions bank_transactions (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateBankTransaction($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateBankTransactionWithHttpInfo($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateBankTransactionWithHttpInfo
     * Updates a single spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateBankTransactionWithHttpInfo($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateBankTransactionRequest($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateBankTransactionAsync
     * Updates a single spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateBankTransactionAsync($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateBankTransactionAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateBankTransactionAsyncWithHttpInfo
     * Updates a single spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateBankTransactionAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
        $request = $this->updateBankTransactionRequest($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateBankTransaction'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateBankTransactionRequest($xero_tenant_id, $bank_transaction_id, $bank_transactions, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateBankTransaction'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling updateBankTransaction'
            );
        }
        // verify the required parameter 'bank_transactions' is set
        if ($bank_transactions === null || (is_array($bank_transactions) && count($bank_transactions) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transactions when calling updateBankTransaction'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($bank_transactions)) {
            $_tempBody = $bank_transactions;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateBankTransactionAttachmentByFileName
     * Updates a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateBankTransactionAttachmentByFileName($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateBankTransactionAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateBankTransactionAttachmentByFileNameWithHttpInfo
     * Updates a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateBankTransactionAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateBankTransactionAttachmentByFileNameAsync
     * Updates a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateBankTransactionAttachmentByFileNameAsync($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateBankTransactionAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateBankTransactionAttachmentByFileNameAsyncWithHttpInfo
     * Updates a specific attachment from a specific bank transaction by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateBankTransactionAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateBankTransactionAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transaction_id Xero generated unique identifier for a bank transaction (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateBankTransactionAttachmentByFileNameRequest($xero_tenant_id, $bank_transaction_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'bank_transaction_id' is set
        if ($bank_transaction_id === null || (is_array($bank_transaction_id) && count($bank_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transaction_id when calling updateBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateBankTransactionAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateBankTransactionAttachmentByFileName'
            );
        }
        $resourcePath = '/BankTransactions/{BankTransactionID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($bank_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transaction_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateBankTransferAttachmentByFileName
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateBankTransferAttachmentByFileName($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateBankTransferAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateBankTransferAttachmentByFileNameWithHttpInfo
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateBankTransferAttachmentByFileNameWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateBankTransferAttachmentByFileNameAsync
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateBankTransferAttachmentByFileNameAsync($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateBankTransferAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateBankTransferAttachmentByFileNameAsyncWithHttpInfo
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateBankTransferAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateBankTransferAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $bank_transfer_id Xero generated unique identifier for a bank transfer (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateBankTransferAttachmentByFileNameRequest($xero_tenant_id, $bank_transfer_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'bank_transfer_id' is set
        if ($bank_transfer_id === null || (is_array($bank_transfer_id) && count($bank_transfer_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transfer_id when calling updateBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateBankTransferAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateBankTransferAttachmentByFileName'
            );
        }
        $resourcePath = '/BankTransfers/{BankTransferID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($bank_transfer_id !== null) {
            $resourcePath = str_replace(
                '{' . 'BankTransferID' . '}',
                AccountingObjectSerializer::toPathValue($bank_transfer_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateContact
     * Updates a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts an array of Contacts containing single Contact object with properties to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateContact($xero_tenant_id, $contact_id, $contacts, $idempotency_key = null)
    {
        list($response) = $this->updateContactWithHttpInfo($xero_tenant_id, $contact_id, $contacts, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateContactWithHttpInfo
     * Updates a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts an array of Contacts containing single Contact object with properties to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateContactWithHttpInfo($xero_tenant_id, $contact_id, $contacts, $idempotency_key = null)
    {
        $request = $this->updateContactRequest($xero_tenant_id, $contact_id, $contacts, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Contacts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Contacts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Contacts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateContactAsync
     * Updates a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts an array of Contacts containing single Contact object with properties to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateContactAsync($xero_tenant_id, $contact_id, $contacts, $idempotency_key = null)
    {
        return $this->updateContactAsyncWithHttpInfo($xero_tenant_id, $contact_id, $contacts, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateContactAsyncWithHttpInfo
     * Updates a specific contact in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts an array of Contacts containing single Contact object with properties to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateContactAsyncWithHttpInfo($xero_tenant_id, $contact_id, $contacts, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
        $request = $this->updateContactRequest($xero_tenant_id, $contact_id, $contacts, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateContact'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts an array of Contacts containing single Contact object with properties to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateContactRequest($xero_tenant_id, $contact_id, $contacts, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateContact'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling updateContact'
            );
        }
        // verify the required parameter 'contacts' is set
        if ($contacts === null || (is_array($contacts) && count($contacts) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contacts when calling updateContact'
            );
        }
        $resourcePath = '/Contacts/{ContactID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($contacts)) {
            $_tempBody = $contacts;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateContactAttachmentByFileName
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateContactAttachmentByFileName($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateContactAttachmentByFileNameWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateContactAttachmentByFileNameWithHttpInfo
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateContactAttachmentByFileNameWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateContactAttachmentByFileNameAsync
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateContactAttachmentByFileNameAsync($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateContactAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateContactAttachmentByFileNameAsyncWithHttpInfo
     * 
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateContactAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateContactAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_id Unique identifier for a Contact (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateContactAttachmentByFileNameRequest($xero_tenant_id, $contact_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'contact_id' is set
        if ($contact_id === null || (is_array($contact_id) && count($contact_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_id when calling updateContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateContactAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateContactAttachmentByFileName'
            );
        }
        $resourcePath = '/Contacts/{ContactID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($contact_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactID' . '}',
                AccountingObjectSerializer::toPathValue($contact_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateContactGroup
     * Updates a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups an array of Contact groups with Name of specific group to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ContactGroups|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateContactGroup($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key = null)
    {
        list($response) = $this->updateContactGroupWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateContactGroupWithHttpInfo
     * Updates a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups an array of Contact groups with Name of specific group to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ContactGroups|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateContactGroupWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key = null)
    {
        $request = $this->updateContactGroupRequest($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ContactGroups' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateContactGroupAsync
     * Updates a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups an array of Contact groups with Name of specific group to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateContactGroupAsync($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key = null)
    {
        return $this->updateContactGroupAsyncWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateContactGroupAsyncWithHttpInfo
     * Updates a specific contact group
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups an array of Contact groups with Name of specific group to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateContactGroupAsyncWithHttpInfo($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ContactGroups';
        $request = $this->updateContactGroupRequest($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateContactGroup'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $contact_group_id Unique identifier for a Contact Group (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ContactGroups $contact_groups an array of Contact groups with Name of specific group to update (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateContactGroupRequest($xero_tenant_id, $contact_group_id, $contact_groups, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateContactGroup'
            );
        }
        // verify the required parameter 'contact_group_id' is set
        if ($contact_group_id === null || (is_array($contact_group_id) && count($contact_group_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_group_id when calling updateContactGroup'
            );
        }
        // verify the required parameter 'contact_groups' is set
        if ($contact_groups === null || (is_array($contact_groups) && count($contact_groups) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contact_groups when calling updateContactGroup'
            );
        }
        $resourcePath = '/ContactGroups/{ContactGroupID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($contact_group_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ContactGroupID' . '}',
                AccountingObjectSerializer::toPathValue($contact_group_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($contact_groups)) {
            $_tempBody = $contact_groups;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateCreditNote
     * Updates a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes containing credit note details to update (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\CreditNotes|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateCreditNote($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateCreditNoteWithHttpInfo($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateCreditNoteWithHttpInfo
     * Updates a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes containing credit note details to update (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\CreditNotes|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateCreditNoteWithHttpInfo($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateCreditNoteRequest($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\CreditNotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateCreditNoteAsync
     * Updates a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes containing credit note details to update (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateCreditNoteAsync($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateCreditNoteAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateCreditNoteAsyncWithHttpInfo
     * Updates a specific credit note
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes containing credit note details to update (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateCreditNoteAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
        $request = $this->updateCreditNoteRequest($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateCreditNote'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes containing credit note details to update (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateCreditNoteRequest($xero_tenant_id, $credit_note_id, $credit_notes, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateCreditNote'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling updateCreditNote'
            );
        }
        // verify the required parameter 'credit_notes' is set
        if ($credit_notes === null || (is_array($credit_notes) && count($credit_notes) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_notes when calling updateCreditNote'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($credit_notes)) {
            $_tempBody = $credit_notes;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateCreditNoteAttachmentByFileName
     * Updates attachments on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateCreditNoteAttachmentByFileName($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateCreditNoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateCreditNoteAttachmentByFileNameWithHttpInfo
     * Updates attachments on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateCreditNoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateCreditNoteAttachmentByFileNameAsync
     * Updates attachments on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateCreditNoteAttachmentByFileNameAsync($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateCreditNoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateCreditNoteAttachmentByFileNameAsyncWithHttpInfo
     * Updates attachments on a specific credit note by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateCreditNoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateCreditNoteAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $credit_note_id Unique identifier for a Credit Note (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateCreditNoteAttachmentByFileNameRequest($xero_tenant_id, $credit_note_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'credit_note_id' is set
        if ($credit_note_id === null || (is_array($credit_note_id) && count($credit_note_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_note_id when calling updateCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateCreditNoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateCreditNoteAttachmentByFileName'
            );
        }
        $resourcePath = '/CreditNotes/{CreditNoteID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($credit_note_id !== null) {
            $resourcePath = str_replace(
                '{' . 'CreditNoteID' . '}',
                AccountingObjectSerializer::toPathValue($credit_note_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateExpenseClaim
     * Updates a specific expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims expense_claims (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateExpenseClaim($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key = null)
    {
        list($response) = $this->updateExpenseClaimWithHttpInfo($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateExpenseClaimWithHttpInfo
     * Updates a specific expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateExpenseClaimWithHttpInfo($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key = null)
    {
        $request = $this->updateExpenseClaimRequest($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateExpenseClaimAsync
     * Updates a specific expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateExpenseClaimAsync($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key = null)
    {
        return $this->updateExpenseClaimAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateExpenseClaimAsyncWithHttpInfo
     * Updates a specific expense claims
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateExpenseClaimAsyncWithHttpInfo($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims';
        $request = $this->updateExpenseClaimRequest($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateExpenseClaim'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $expense_claim_id Unique identifier for a ExpenseClaim (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ExpenseClaims $expense_claims (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateExpenseClaimRequest($xero_tenant_id, $expense_claim_id, $expense_claims, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateExpenseClaim'
            );
        }
        // verify the required parameter 'expense_claim_id' is set
        if ($expense_claim_id === null || (is_array($expense_claim_id) && count($expense_claim_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $expense_claim_id when calling updateExpenseClaim'
            );
        }
        // verify the required parameter 'expense_claims' is set
        if ($expense_claims === null || (is_array($expense_claims) && count($expense_claims) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $expense_claims when calling updateExpenseClaim'
            );
        }
        $resourcePath = '/ExpenseClaims/{ExpenseClaimID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($expense_claim_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ExpenseClaimID' . '}',
                AccountingObjectSerializer::toPathValue($expense_claim_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($expense_claims)) {
            $_tempBody = $expense_claims;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateInvoice
     * Updates a specific sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices invoices (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Invoices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateInvoice($xero_tenant_id, $invoice_id, $invoices, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateInvoiceWithHttpInfo($xero_tenant_id, $invoice_id, $invoices, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateInvoiceWithHttpInfo
     * Updates a specific sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Invoices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateInvoiceWithHttpInfo($xero_tenant_id, $invoice_id, $invoices, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateInvoiceRequest($xero_tenant_id, $invoice_id, $invoices, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Invoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Invoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Invoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateInvoiceAsync
     * Updates a specific sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateInvoiceAsync($xero_tenant_id, $invoice_id, $invoices, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $invoices, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateInvoiceAsyncWithHttpInfo
     * Updates a specific sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateInvoiceAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $invoices, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
        $request = $this->updateInvoiceRequest($xero_tenant_id, $invoice_id, $invoices, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateInvoice'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateInvoiceRequest($xero_tenant_id, $invoice_id, $invoices, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateInvoice'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling updateInvoice'
            );
        }
        // verify the required parameter 'invoices' is set
        if ($invoices === null || (is_array($invoices) && count($invoices) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoices when calling updateInvoice'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($invoices)) {
            $_tempBody = $invoices;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateInvoiceAttachmentByFileName
     * Updates an attachment from a specific invoices or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateInvoiceAttachmentByFileName($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateInvoiceAttachmentByFileNameWithHttpInfo
     * Updates an attachment from a specific invoices or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateInvoiceAttachmentByFileNameAsync
     * Updates an attachment from a specific invoices or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateInvoiceAttachmentByFileNameAsync($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateInvoiceAttachmentByFileNameAsyncWithHttpInfo
     * Updates an attachment from a specific invoices or purchase bill by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateInvoiceAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $invoice_id Unique identifier for an Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateInvoiceAttachmentByFileNameRequest($xero_tenant_id, $invoice_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'invoice_id' is set
        if ($invoice_id === null || (is_array($invoice_id) && count($invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoice_id when calling updateInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateInvoiceAttachmentByFileName'
            );
        }
        $resourcePath = '/Invoices/{InvoiceID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'InvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateItem
     * Updates a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items items (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Items|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateItem($xero_tenant_id, $item_id, $items, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateItemWithHttpInfo($xero_tenant_id, $item_id, $items, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateItemWithHttpInfo
     * Updates a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Items|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateItemWithHttpInfo($xero_tenant_id, $item_id, $items, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateItemRequest($xero_tenant_id, $item_id, $items, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Items' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Items', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Items',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateItemAsync
     * Updates a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateItemAsync($xero_tenant_id, $item_id, $items, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateItemAsyncWithHttpInfo($xero_tenant_id, $item_id, $items, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateItemAsyncWithHttpInfo
     * Updates a specific item
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateItemAsyncWithHttpInfo($xero_tenant_id, $item_id, $items, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
        $request = $this->updateItemRequest($xero_tenant_id, $item_id, $items, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateItem'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $item_id Unique identifier for an Item (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateItemRequest($xero_tenant_id, $item_id, $items, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateItem'
            );
        }
        // verify the required parameter 'item_id' is set
        if ($item_id === null || (is_array($item_id) && count($item_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $item_id when calling updateItem'
            );
        }
        // verify the required parameter 'items' is set
        if ($items === null || (is_array($items) && count($items) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $items when calling updateItem'
            );
        }
        $resourcePath = '/Items/{ItemID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($item_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ItemID' . '}',
                AccountingObjectSerializer::toPathValue($item_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($items)) {
            $_tempBody = $items;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateLinkedTransaction
     * Updates a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions $linked_transactions linked_transactions (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateLinkedTransaction($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key = null)
    {
        list($response) = $this->updateLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateLinkedTransactionWithHttpInfo
     * Updates a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions $linked_transactions (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateLinkedTransactionWithHttpInfo($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key = null)
    {
        $request = $this->updateLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateLinkedTransactionAsync
     * Updates a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions $linked_transactions (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateLinkedTransactionAsync($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key = null)
    {
        return $this->updateLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateLinkedTransactionAsyncWithHttpInfo
     * Updates a specific linked transactions (billable expenses)
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions $linked_transactions (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateLinkedTransactionAsyncWithHttpInfo($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions';
        $request = $this->updateLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateLinkedTransaction'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $linked_transaction_id Unique identifier for a LinkedTransaction (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\LinkedTransactions $linked_transactions (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateLinkedTransactionRequest($xero_tenant_id, $linked_transaction_id, $linked_transactions, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateLinkedTransaction'
            );
        }
        // verify the required parameter 'linked_transaction_id' is set
        if ($linked_transaction_id === null || (is_array($linked_transaction_id) && count($linked_transaction_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $linked_transaction_id when calling updateLinkedTransaction'
            );
        }
        // verify the required parameter 'linked_transactions' is set
        if ($linked_transactions === null || (is_array($linked_transactions) && count($linked_transactions) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $linked_transactions when calling updateLinkedTransaction'
            );
        }
        $resourcePath = '/LinkedTransactions/{LinkedTransactionID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($linked_transaction_id !== null) {
            $resourcePath = str_replace(
                '{' . 'LinkedTransactionID' . '}',
                AccountingObjectSerializer::toPathValue($linked_transaction_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($linked_transactions)) {
            $_tempBody = $linked_transactions;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateManualJournal
     * Updates a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals manual_journals (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ManualJournals|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateManualJournal($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key = null)
    {
        list($response) = $this->updateManualJournalWithHttpInfo($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateManualJournalWithHttpInfo
     * Updates a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ManualJournals|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateManualJournalWithHttpInfo($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key = null)
    {
        $request = $this->updateManualJournalRequest($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ManualJournals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateManualJournalAsync
     * Updates a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateManualJournalAsync($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key = null)
    {
        return $this->updateManualJournalAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateManualJournalAsyncWithHttpInfo
     * Updates a specific manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateManualJournalAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
        $request = $this->updateManualJournalRequest($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateManualJournal'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateManualJournalRequest($xero_tenant_id, $manual_journal_id, $manual_journals, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateManualJournal'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling updateManualJournal'
            );
        }
        // verify the required parameter 'manual_journals' is set
        if ($manual_journals === null || (is_array($manual_journals) && count($manual_journals) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journals when calling updateManualJournal'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($manual_journals)) {
            $_tempBody = $manual_journals;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateManualJournalAttachmentByFileName
     * Updates a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateManualJournalAttachmentByFileName($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateManualJournalAttachmentByFileNameWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateManualJournalAttachmentByFileNameWithHttpInfo
     * Updates a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateManualJournalAttachmentByFileNameWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateManualJournalAttachmentByFileNameAsync
     * Updates a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateManualJournalAttachmentByFileNameAsync($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateManualJournalAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateManualJournalAttachmentByFileNameAsyncWithHttpInfo
     * Updates a specific attachment from a specific manual journal by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateManualJournalAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateManualJournalAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $manual_journal_id Unique identifier for a ManualJournal (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateManualJournalAttachmentByFileNameRequest($xero_tenant_id, $manual_journal_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'manual_journal_id' is set
        if ($manual_journal_id === null || (is_array($manual_journal_id) && count($manual_journal_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journal_id when calling updateManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateManualJournalAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateManualJournalAttachmentByFileName'
            );
        }
        $resourcePath = '/ManualJournals/{ManualJournalID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($manual_journal_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ManualJournalID' . '}',
                AccountingObjectSerializer::toPathValue($manual_journal_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateBankTransactions
     * Updates or creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions bank_transactions (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\BankTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateBankTransactions($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateBankTransactionsWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateBankTransactionsWithHttpInfo
     * Updates or creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\BankTransactions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateBankTransactionsWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateOrCreateBankTransactionsRequest($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\BankTransactions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateBankTransactionsAsync
     * Updates or creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateBankTransactionsAsync($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateOrCreateBankTransactionsAsyncWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateBankTransactionsAsyncWithHttpInfo
     * Updates or creates one or more spent or received money transaction
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateBankTransactionsAsyncWithHttpInfo($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\BankTransactions';
        $request = $this->updateOrCreateBankTransactionsRequest($xero_tenant_id, $bank_transactions, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateBankTransactions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\BankTransactions $bank_transactions (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateBankTransactionsRequest($xero_tenant_id, $bank_transactions, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateBankTransactions'
            );
        }
        // verify the required parameter 'bank_transactions' is set
        if ($bank_transactions === null || (is_array($bank_transactions) && count($bank_transactions) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bank_transactions when calling updateOrCreateBankTransactions'
            );
        }
        $resourcePath = '/BankTransactions';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($bank_transactions)) {
            $_tempBody = $bank_transactions;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateContacts
     * Updates or creates one or more contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts contacts (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateContacts($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateContactsWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateContactsWithHttpInfo
     * Updates or creates one or more contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Contacts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateContactsWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->updateOrCreateContactsRequest($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Contacts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Contacts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Contacts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateContactsAsync
     * Updates or creates one or more contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateContactsAsync($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->updateOrCreateContactsAsyncWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateContactsAsyncWithHttpInfo
     * Updates or creates one or more contacts in a Xero organisation
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateContactsAsyncWithHttpInfo($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Contacts';
        $request = $this->updateOrCreateContactsRequest($xero_tenant_id, $contacts, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateContacts'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Contacts $contacts (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateContactsRequest($xero_tenant_id, $contacts, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateContacts'
            );
        }
        // verify the required parameter 'contacts' is set
        if ($contacts === null || (is_array($contacts) && count($contacts) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $contacts when calling updateOrCreateContacts'
            );
        }
        $resourcePath = '/Contacts';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($contacts)) {
            $_tempBody = $contacts;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateCreditNotes
     * Updates or creates one or more credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes with a single CreditNote object. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\CreditNotes|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateCreditNotes($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateCreditNotesWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateCreditNotesWithHttpInfo
     * Updates or creates one or more credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes with a single CreditNote object. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\CreditNotes|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateCreditNotesWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateOrCreateCreditNotesRequest($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\CreditNotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateCreditNotesAsync
     * Updates or creates one or more credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes with a single CreditNote object. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateCreditNotesAsync($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateOrCreateCreditNotesAsyncWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateCreditNotesAsyncWithHttpInfo
     * Updates or creates one or more credit notes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes with a single CreditNote object. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateCreditNotesAsyncWithHttpInfo($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\CreditNotes';
        $request = $this->updateOrCreateCreditNotesRequest($xero_tenant_id, $credit_notes, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateCreditNotes'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\CreditNotes $credit_notes an array of Credit Notes with a single CreditNote object. (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateCreditNotesRequest($xero_tenant_id, $credit_notes, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateCreditNotes'
            );
        }
        // verify the required parameter 'credit_notes' is set
        if ($credit_notes === null || (is_array($credit_notes) && count($credit_notes) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $credit_notes when calling updateOrCreateCreditNotes'
            );
        }
        $resourcePath = '/CreditNotes';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($credit_notes)) {
            $_tempBody = $credit_notes;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateEmployees
     * Creates a single new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Employees|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateEmployees($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateEmployeesWithHttpInfo($xero_tenant_id, $employees, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateEmployeesWithHttpInfo
     * Creates a single new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Employees|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateEmployeesWithHttpInfo($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->updateOrCreateEmployeesRequest($xero_tenant_id, $employees, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Employees' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Employees', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Employees',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateEmployeesAsync
     * Creates a single new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateEmployeesAsync($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->updateOrCreateEmployeesAsyncWithHttpInfo($xero_tenant_id, $employees, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateEmployeesAsyncWithHttpInfo
     * Creates a single new employees used in Xero payrun
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateEmployeesAsyncWithHttpInfo($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Employees';
        $request = $this->updateOrCreateEmployeesRequest($xero_tenant_id, $employees, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateEmployees'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Employees $employees Employees with array of Employee object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateEmployeesRequest($xero_tenant_id, $employees, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateEmployees'
            );
        }
        // verify the required parameter 'employees' is set
        if ($employees === null || (is_array($employees) && count($employees) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $employees when calling updateOrCreateEmployees'
            );
        }
        $resourcePath = '/Employees';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($employees)) {
            $_tempBody = $employees;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateInvoices
     * Updates or creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices invoices (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Invoices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateInvoices($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateInvoicesWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateInvoicesWithHttpInfo
     * Updates or creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Invoices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateInvoicesWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateOrCreateInvoicesRequest($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Invoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Invoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Invoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateInvoicesAsync
     * Updates or creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateInvoicesAsync($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateOrCreateInvoicesAsyncWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateInvoicesAsyncWithHttpInfo
     * Updates or creates one or more sales invoices or purchase bills
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateInvoicesAsyncWithHttpInfo($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Invoices';
        $request = $this->updateOrCreateInvoicesRequest($xero_tenant_id, $invoices, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateInvoices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Invoices $invoices (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateInvoicesRequest($xero_tenant_id, $invoices, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateInvoices'
            );
        }
        // verify the required parameter 'invoices' is set
        if ($invoices === null || (is_array($invoices) && count($invoices) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $invoices when calling updateOrCreateInvoices'
            );
        }
        $resourcePath = '/Invoices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($invoices)) {
            $_tempBody = $invoices;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateItems
     * Updates or creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items items (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Items|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateItems($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateItemsWithHttpInfo($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateItemsWithHttpInfo
     * Updates or creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Items|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateItemsWithHttpInfo($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateOrCreateItemsRequest($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Items' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Items', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Items',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateItemsAsync
     * Updates or creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateItemsAsync($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateOrCreateItemsAsyncWithHttpInfo($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateItemsAsyncWithHttpInfo
     * Updates or creates one or more items
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateItemsAsyncWithHttpInfo($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Items';
        $request = $this->updateOrCreateItemsRequest($xero_tenant_id, $items, $summarize_errors, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateItems'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Items $items (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateItemsRequest($xero_tenant_id, $items, $summarize_errors = false, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateItems'
            );
        }
        // verify the required parameter 'items' is set
        if ($items === null || (is_array($items) && count($items) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $items when calling updateOrCreateItems'
            );
        }
        $resourcePath = '/Items';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($items)) {
            $_tempBody = $items;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateManualJournals
     * Updates or creates a single manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\ManualJournals|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateManualJournals($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateManualJournalsWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateManualJournalsWithHttpInfo
     * Updates or creates a single manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\ManualJournals|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateManualJournalsWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->updateOrCreateManualJournalsRequest($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\ManualJournals' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateManualJournalsAsync
     * Updates or creates a single manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateManualJournalsAsync($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->updateOrCreateManualJournalsAsyncWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateManualJournalsAsyncWithHttpInfo
     * Updates or creates a single manual journal
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateManualJournalsAsyncWithHttpInfo($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\ManualJournals';
        $request = $this->updateOrCreateManualJournalsRequest($xero_tenant_id, $manual_journals, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateManualJournals'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\ManualJournals $manual_journals ManualJournals array with ManualJournal object in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateManualJournalsRequest($xero_tenant_id, $manual_journals, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateManualJournals'
            );
        }
        // verify the required parameter 'manual_journals' is set
        if ($manual_journals === null || (is_array($manual_journals) && count($manual_journals) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $manual_journals when calling updateOrCreateManualJournals'
            );
        }
        $resourcePath = '/ManualJournals';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($manual_journals)) {
            $_tempBody = $manual_journals;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreatePurchaseOrders
     * Updates or creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders purchase_orders (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreatePurchaseOrders($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreatePurchaseOrdersWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreatePurchaseOrdersWithHttpInfo
     * Updates or creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreatePurchaseOrdersWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->updateOrCreatePurchaseOrdersRequest($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreatePurchaseOrdersAsync
     * Updates or creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreatePurchaseOrdersAsync($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->updateOrCreatePurchaseOrdersAsyncWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreatePurchaseOrdersAsyncWithHttpInfo
     * Updates or creates one or more purchase orders
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreatePurchaseOrdersAsyncWithHttpInfo($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
        $request = $this->updateOrCreatePurchaseOrdersRequest($xero_tenant_id, $purchase_orders, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreatePurchaseOrders'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreatePurchaseOrdersRequest($xero_tenant_id, $purchase_orders, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreatePurchaseOrders'
            );
        }
        // verify the required parameter 'purchase_orders' is set
        if ($purchase_orders === null || (is_array($purchase_orders) && count($purchase_orders) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_orders when calling updateOrCreatePurchaseOrders'
            );
        }
        $resourcePath = '/PurchaseOrders';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($purchase_orders)) {
            $_tempBody = $purchase_orders;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateQuotes
     * Updates or creates one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes quotes (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Quotes|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateQuotes($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateQuotesWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateQuotesWithHttpInfo
     * Updates or creates one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Quotes|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateQuotesWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->updateOrCreateQuotesRequest($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Quotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Quotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Quotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateQuotesAsync
     * Updates or creates one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateQuotesAsync($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->updateOrCreateQuotesAsyncWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateQuotesAsyncWithHttpInfo
     * Updates or creates one or more quotes
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateQuotesAsyncWithHttpInfo($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
        $request = $this->updateOrCreateQuotesRequest($xero_tenant_id, $quotes, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateQuotes'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateQuotesRequest($xero_tenant_id, $quotes, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateQuotes'
            );
        }
        // verify the required parameter 'quotes' is set
        if ($quotes === null || (is_array($quotes) && count($quotes) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quotes when calling updateOrCreateQuotes'
            );
        }
        $resourcePath = '/Quotes';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($quotes)) {
            $_tempBody = $quotes;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateOrCreateRepeatingInvoices
     * Creates or deletes one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateOrCreateRepeatingInvoices($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        list($response) = $this->updateOrCreateRepeatingInvoicesWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateOrCreateRepeatingInvoicesWithHttpInfo
     * Creates or deletes one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateOrCreateRepeatingInvoicesWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        $request = $this->updateOrCreateRepeatingInvoicesRequest($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateOrCreateRepeatingInvoicesAsync
     * Creates or deletes one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateOrCreateRepeatingInvoicesAsync($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        return $this->updateOrCreateRepeatingInvoicesAsyncWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateOrCreateRepeatingInvoicesAsyncWithHttpInfo
     * Creates or deletes one or more repeating invoice templates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateOrCreateRepeatingInvoicesAsyncWithHttpInfo($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
        $request = $this->updateOrCreateRepeatingInvoicesRequest($xero_tenant_id, $repeating_invoices, $summarize_errors, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateOrCreateRepeatingInvoices'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices RepeatingInvoices with an array of repeating invoice objects in body of request (required)
     * @param  bool $summarize_errors If false return 200 OK and mix of successfully created objects and any with validation errors (optional, default to false)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateOrCreateRepeatingInvoicesRequest($xero_tenant_id, $repeating_invoices, $summarize_errors = false, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateOrCreateRepeatingInvoices'
            );
        }
        // verify the required parameter 'repeating_invoices' is set
        if ($repeating_invoices === null || (is_array($repeating_invoices) && count($repeating_invoices) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoices when calling updateOrCreateRepeatingInvoices'
            );
        }
        $resourcePath = '/RepeatingInvoices';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($summarize_errors !== null) {
            $queryParams['summarizeErrors'] = $summarize_errors ? 'true' : 'false';
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($repeating_invoices)) {
            $_tempBody = $repeating_invoices;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updatePurchaseOrder
     * Updates a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders purchase_orders (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updatePurchaseOrder($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key = null)
    {
        list($response) = $this->updatePurchaseOrderWithHttpInfo($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key);
        return $response;
    }
    /**
     * Operation updatePurchaseOrderWithHttpInfo
     * Updates a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updatePurchaseOrderWithHttpInfo($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key = null)
    {
        $request = $this->updatePurchaseOrderRequest($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updatePurchaseOrderAsync
     * Updates a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updatePurchaseOrderAsync($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key = null)
    {
        return $this->updatePurchaseOrderAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updatePurchaseOrderAsyncWithHttpInfo
     * Updates a specific purchase order
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updatePurchaseOrderAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders';
        $request = $this->updatePurchaseOrderRequest($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updatePurchaseOrder'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\PurchaseOrders $purchase_orders (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updatePurchaseOrderRequest($xero_tenant_id, $purchase_order_id, $purchase_orders, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updatePurchaseOrder'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling updatePurchaseOrder'
            );
        }
        // verify the required parameter 'purchase_orders' is set
        if ($purchase_orders === null || (is_array($purchase_orders) && count($purchase_orders) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_orders when calling updatePurchaseOrder'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($purchase_orders)) {
            $_tempBody = $purchase_orders;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updatePurchaseOrderAttachmentByFileName
     * Updates a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updatePurchaseOrderAttachmentByFileName($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updatePurchaseOrderAttachmentByFileNameWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updatePurchaseOrderAttachmentByFileNameWithHttpInfo
     * Updates a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updatePurchaseOrderAttachmentByFileNameWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updatePurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updatePurchaseOrderAttachmentByFileNameAsync
     * Updates a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updatePurchaseOrderAttachmentByFileNameAsync($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updatePurchaseOrderAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updatePurchaseOrderAttachmentByFileNameAsyncWithHttpInfo
     * Updates a specific attachment for a specific purchase order by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updatePurchaseOrderAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updatePurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updatePurchaseOrderAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $purchase_order_id Unique identifier for an Purchase Order (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updatePurchaseOrderAttachmentByFileNameRequest($xero_tenant_id, $purchase_order_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updatePurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'purchase_order_id' is set
        if ($purchase_order_id === null || (is_array($purchase_order_id) && count($purchase_order_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $purchase_order_id when calling updatePurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updatePurchaseOrderAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updatePurchaseOrderAttachmentByFileName'
            );
        }
        $resourcePath = '/PurchaseOrders/{PurchaseOrderID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($purchase_order_id !== null) {
            $resourcePath = str_replace(
                '{' . 'PurchaseOrderID' . '}',
                AccountingObjectSerializer::toPathValue($purchase_order_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateQuote
     * Updates a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes quotes (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Quotes|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateQuote($xero_tenant_id, $quote_id, $quotes, $idempotency_key = null)
    {
        list($response) = $this->updateQuoteWithHttpInfo($xero_tenant_id, $quote_id, $quotes, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateQuoteWithHttpInfo
     * Updates a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Quotes|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateQuoteWithHttpInfo($xero_tenant_id, $quote_id, $quotes, $idempotency_key = null)
    {
        $request = $this->updateQuoteRequest($xero_tenant_id, $quote_id, $quotes, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Quotes' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Quotes', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Quotes',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateQuoteAsync
     * Updates a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateQuoteAsync($xero_tenant_id, $quote_id, $quotes, $idempotency_key = null)
    {
        return $this->updateQuoteAsyncWithHttpInfo($xero_tenant_id, $quote_id, $quotes, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateQuoteAsyncWithHttpInfo
     * Updates a specific quote
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateQuoteAsyncWithHttpInfo($xero_tenant_id, $quote_id, $quotes, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Quotes';
        $request = $this->updateQuoteRequest($xero_tenant_id, $quote_id, $quotes, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateQuote'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Quotes $quotes (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateQuoteRequest($xero_tenant_id, $quote_id, $quotes, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateQuote'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling updateQuote'
            );
        }
        // verify the required parameter 'quotes' is set
        if ($quotes === null || (is_array($quotes) && count($quotes) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quotes when calling updateQuote'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($quotes)) {
            $_tempBody = $quotes;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateQuoteAttachmentByFileName
     * Updates a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateQuoteAttachmentByFileName($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateQuoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateQuoteAttachmentByFileNameWithHttpInfo
     * Updates a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateQuoteAttachmentByFileNameWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateQuoteAttachmentByFileNameAsync
     * Updates a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateQuoteAttachmentByFileNameAsync($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateQuoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateQuoteAttachmentByFileNameAsyncWithHttpInfo
     * Updates a specific attachment from a specific quote by filename
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateQuoteAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateQuoteAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $quote_id Unique identifier for an Quote (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateQuoteAttachmentByFileNameRequest($xero_tenant_id, $quote_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'quote_id' is set
        if ($quote_id === null || (is_array($quote_id) && count($quote_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $quote_id when calling updateQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateQuoteAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateQuoteAttachmentByFileName'
            );
        }
        $resourcePath = '/Quotes/{QuoteID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($quote_id !== null) {
            $resourcePath = str_replace(
                '{' . 'QuoteID' . '}',
                AccountingObjectSerializer::toPathValue($quote_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateReceipt
     * Updates a specific draft expense claim receipts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts receipts (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Receipts|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateReceipt($xero_tenant_id, $receipt_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        list($response) = $this->updateReceiptWithHttpInfo($xero_tenant_id, $receipt_id, $receipts, $unitdp, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateReceiptWithHttpInfo
     * Updates a specific draft expense claim receipts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Receipts|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateReceiptWithHttpInfo($xero_tenant_id, $receipt_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        $request = $this->updateReceiptRequest($xero_tenant_id, $receipt_id, $receipts, $unitdp, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Receipts' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Receipts', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Receipts',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateReceiptAsync
     * Updates a specific draft expense claim receipts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateReceiptAsync($xero_tenant_id, $receipt_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        return $this->updateReceiptAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $receipts, $unitdp, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateReceiptAsyncWithHttpInfo
     * Updates a specific draft expense claim receipts
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateReceiptAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Receipts';
        $request = $this->updateReceiptRequest($xero_tenant_id, $receipt_id, $receipts, $unitdp, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateReceipt'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\Receipts $receipts (required)
     * @param  int $unitdp e.g. unitdp&#x3D;4 – (Unit Decimal Places) You can opt in to use four decimal places for unit amounts (optional)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateReceiptRequest($xero_tenant_id, $receipt_id, $receipts, $unitdp = null, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateReceipt'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling updateReceipt'
            );
        }
        // verify the required parameter 'receipts' is set
        if ($receipts === null || (is_array($receipts) && count($receipts) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipts when calling updateReceipt'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // query params
        if ($unitdp !== null) {
            $queryParams['unitdp'] = AccountingObjectSerializer::toQueryValue($unitdp);
        }
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($receipts)) {
            $_tempBody = $receipts;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateReceiptAttachmentByFileName
     * Updates a specific attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateReceiptAttachmentByFileName($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateReceiptAttachmentByFileNameWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateReceiptAttachmentByFileNameWithHttpInfo
     * Updates a specific attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateReceiptAttachmentByFileNameWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateReceiptAttachmentByFileNameAsync
     * Updates a specific attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateReceiptAttachmentByFileNameAsync($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateReceiptAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateReceiptAttachmentByFileNameAsyncWithHttpInfo
     * Updates a specific attachment on a specific expense claim receipts by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateReceiptAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateReceiptAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $receipt_id Unique identifier for a Receipt (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateReceiptAttachmentByFileNameRequest($xero_tenant_id, $receipt_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'receipt_id' is set
        if ($receipt_id === null || (is_array($receipt_id) && count($receipt_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $receipt_id when calling updateReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateReceiptAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateReceiptAttachmentByFileName'
            );
        }
        $resourcePath = '/Receipts/{ReceiptID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($receipt_id !== null) {
            $resourcePath = str_replace(
                '{' . 'ReceiptID' . '}',
                AccountingObjectSerializer::toPathValue($receipt_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateRepeatingInvoice
     * Deletes a specific repeating invoice template
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices repeating_invoices (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateRepeatingInvoice($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key = null)
    {
        list($response) = $this->updateRepeatingInvoiceWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateRepeatingInvoiceWithHttpInfo
     * Deletes a specific repeating invoice template
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateRepeatingInvoiceWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key = null)
    {
        $request = $this->updateRepeatingInvoiceRequest($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateRepeatingInvoiceAsync
     * Deletes a specific repeating invoice template
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateRepeatingInvoiceAsync($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key = null)
    {
        return $this->updateRepeatingInvoiceAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateRepeatingInvoiceAsyncWithHttpInfo
     * Deletes a specific repeating invoice template
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateRepeatingInvoiceAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices';
        $request = $this->updateRepeatingInvoiceRequest($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateRepeatingInvoice'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\RepeatingInvoices $repeating_invoices (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateRepeatingInvoiceRequest($xero_tenant_id, $repeating_invoice_id, $repeating_invoices, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateRepeatingInvoice'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling updateRepeatingInvoice'
            );
        }
        // verify the required parameter 'repeating_invoices' is set
        if ($repeating_invoices === null || (is_array($repeating_invoices) && count($repeating_invoices) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoices when calling updateRepeatingInvoice'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($repeating_invoices)) {
            $_tempBody = $repeating_invoices;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateRepeatingInvoiceAttachmentByFileName
     * Updates a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateRepeatingInvoiceAttachmentByFileName($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        list($response) = $this->updateRepeatingInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateRepeatingInvoiceAttachmentByFileNameWithHttpInfo
     * Updates a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\Attachments|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateRepeatingInvoiceAttachmentByFileNameWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        $request = $this->updateRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Attachments' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Attachments', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Attachments',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateRepeatingInvoiceAttachmentByFileNameAsync
     * Updates a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateRepeatingInvoiceAttachmentByFileNameAsync($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        return $this->updateRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo
     * Updates a specific attachment from a specific repeating invoices by file name
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateRepeatingInvoiceAttachmentByFileNameAsyncWithHttpInfo($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\Attachments';
        $request = $this->updateRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateRepeatingInvoiceAttachmentByFileName'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $repeating_invoice_id Unique identifier for a Repeating Invoice (required)
     * @param  string $file_name Name of the attachment (required)
     * @param  string $body Byte array of file in body of request (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateRepeatingInvoiceAttachmentByFileNameRequest($xero_tenant_id, $repeating_invoice_id, $file_name, $body, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'repeating_invoice_id' is set
        if ($repeating_invoice_id === null || (is_array($repeating_invoice_id) && count($repeating_invoice_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repeating_invoice_id when calling updateRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'file_name' is set
        if ($file_name === null || (is_array($file_name) && count($file_name) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $file_name when calling updateRepeatingInvoiceAttachmentByFileName'
            );
        }
        // verify the required parameter 'body' is set
        if ($body === null || (is_array($body) && count($body) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $body when calling updateRepeatingInvoiceAttachmentByFileName'
            );
        }
        $resourcePath = '/RepeatingInvoices/{RepeatingInvoiceID}/Attachments/{FileName}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($repeating_invoice_id !== null) {
            $resourcePath = str_replace(
                '{' . 'RepeatingInvoiceID' . '}',
                AccountingObjectSerializer::toPathValue($repeating_invoice_id),
                $resourcePath
            );
        }
        // path params
        if ($file_name !== null) {
            $resourcePath = str_replace(
                '{' . 'FileName' . '}',
                AccountingObjectSerializer::toPathValue($file_name),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/octet-stream']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateTaxRate
     * Updates tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates tax_rates (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TaxRates|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateTaxRate($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        list($response) = $this->updateTaxRateWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateTaxRateWithHttpInfo
     * Updates tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TaxRates|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateTaxRateWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        $request = $this->updateTaxRateRequest($xero_tenant_id, $tax_rates, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TaxRates' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TaxRates', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TaxRates',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateTaxRateAsync
     * Updates tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateTaxRateAsync($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        return $this->updateTaxRateAsyncWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateTaxRateAsyncWithHttpInfo
     * Updates tax rates
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateTaxRateAsyncWithHttpInfo($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TaxRates';
        $request = $this->updateTaxRateRequest($xero_tenant_id, $tax_rates, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateTaxRate'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TaxRates $tax_rates (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateTaxRateRequest($xero_tenant_id, $tax_rates, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateTaxRate'
            );
        }
        // verify the required parameter 'tax_rates' is set
        if ($tax_rates === null || (is_array($tax_rates) && count($tax_rates) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tax_rates when calling updateTaxRate'
            );
        }
        $resourcePath = '/TaxRates';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // body params
        $_tempBody = null;
        if (isset($tax_rates)) {
            $_tempBody = $tax_rates;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateTrackingCategory
     * Updates a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category tracking_category (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateTrackingCategory($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key = null)
    {
        list($response) = $this->updateTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateTrackingCategoryWithHttpInfo
     * Updates a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingCategories|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateTrackingCategoryWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key = null)
    {
        $request = $this->updateTrackingCategoryRequest($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateTrackingCategoryAsync
     * Updates a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateTrackingCategoryAsync($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key = null)
    {
        return $this->updateTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateTrackingCategoryAsyncWithHttpInfo
     * Updates a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateTrackingCategoryAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingCategories';
        $request = $this->updateTrackingCategoryRequest($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateTrackingCategory'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingCategory $tracking_category (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateTrackingCategoryRequest($xero_tenant_id, $tracking_category_id, $tracking_category, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateTrackingCategory'
            );
        }
        // verify the required parameter 'tracking_category_id' is set
        if ($tracking_category_id === null || (is_array($tracking_category_id) && count($tracking_category_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category_id when calling updateTrackingCategory'
            );
        }
        // verify the required parameter 'tracking_category' is set
        if ($tracking_category === null || (is_array($tracking_category) && count($tracking_category) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category when calling updateTrackingCategory'
            );
        }
        $resourcePath = '/TrackingCategories/{TrackingCategoryID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($tracking_category_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingCategoryID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_category_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($tracking_category)) {
            $_tempBody = $tracking_category;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateTrackingOptions
     * Updates a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option tracking_option (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \XeroAPI\XeroPHP\Models\Accounting\TrackingOptions|\XeroAPI\XeroPHP\Models\Accounting\Error
     */
    public function updateTrackingOptions($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key = null)
    {
        list($response) = $this->updateTrackingOptionsWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key);
        return $response;
    }
    /**
     * Operation updateTrackingOptionsWithHttpInfo
     * Updates a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \XeroAPI\XeroPHP\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \XeroAPI\XeroPHP\Models\Accounting\TrackingOptions|\XeroAPI\XeroPHP\Models\Accounting\Error, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateTrackingOptionsWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key = null)
    {
        $request = $this->updateTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key);
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }
            $statusCode = $response->getStatusCode();
            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }
            $responseBody = $response->getBody();
            switch($statusCode) {
                case 200:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                case 400:
                    if ('\XeroAPI\XeroPHP\Models\Accounting\Error' === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::deserialize($content, '\XeroAPI\XeroPHP\Models\Accounting\Error', []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
            }
            $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions';
            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
            }
            return [
                AccountingObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = AccountingObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\XeroAPI\XeroPHP\Models\Accounting\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }
    /**
     * Operation updateTrackingOptionsAsync
     * Updates a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateTrackingOptionsAsync($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key = null)
    {
        return $this->updateTrackingOptionsAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }
    /**
     * Operation updateTrackingOptionsAsyncWithHttpInfo
     * Updates a specific option for a specific tracking category
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface */
    public function updateTrackingOptionsAsyncWithHttpInfo($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key = null)
    {
        $returnType = '\XeroAPI\XeroPHP\Models\Accounting\TrackingOptions';
        $request = $this->updateTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key);
        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                    }
                    return [
                        AccountingObjectSerializer::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(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateTrackingOptions'
     * @param  string $xero_tenant_id Xero identifier for Tenant (required)
     * @param  string $tracking_category_id Unique identifier for a TrackingCategory (required)
     * @param  string $tracking_option_id Unique identifier for a Tracking Option (required)
     * @param  \XeroAPI\XeroPHP\Models\Accounting\TrackingOption $tracking_option (required)
     * @param  string $idempotency_key This allows you to safely retry requests without the risk of duplicate processing. 128 character max. (optional)
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request  */
    protected function updateTrackingOptionsRequest($xero_tenant_id, $tracking_category_id, $tracking_option_id, $tracking_option, $idempotency_key = null)
    {
        // verify the required parameter 'xero_tenant_id' is set
        if ($xero_tenant_id === null || (is_array($xero_tenant_id) && count($xero_tenant_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $xero_tenant_id when calling updateTrackingOptions'
            );
        }
        // verify the required parameter 'tracking_category_id' is set
        if ($tracking_category_id === null || (is_array($tracking_category_id) && count($tracking_category_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_category_id when calling updateTrackingOptions'
            );
        }
        // verify the required parameter 'tracking_option_id' is set
        if ($tracking_option_id === null || (is_array($tracking_option_id) && count($tracking_option_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_option_id when calling updateTrackingOptions'
            );
        }
        // verify the required parameter 'tracking_option' is set
        if ($tracking_option === null || (is_array($tracking_option) && count($tracking_option) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $tracking_option when calling updateTrackingOptions'
            );
        }
        $resourcePath = '/TrackingCategories/{TrackingCategoryID}/Options/{TrackingOptionID}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;
        // header params
        if ($xero_tenant_id !== null) {
            $headerParams['xero-tenant-id'] = AccountingObjectSerializer::toHeaderValue($xero_tenant_id);
        }
        // header params
        if ($idempotency_key !== null) {
            $headerParams['Idempotency-Key'] = AccountingObjectSerializer::toHeaderValue($idempotency_key);
        }
        // path params
        if ($tracking_category_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingCategoryID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_category_id),
                $resourcePath
            );
        }
        // path params
        if ($tracking_option_id !== null) {
            $resourcePath = str_replace(
                '{' . 'TrackingOptionID' . '}',
                AccountingObjectSerializer::toPathValue($tracking_option_id),
                $resourcePath
            );
        }
        // body params
        $_tempBody = null;
        if (isset($tracking_option)) {
            $_tempBody = $tracking_option;
        }
        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }
        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            if ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode(AccountingObjectSerializer::sanitizeForSerialization($_tempBody));
            } else {
                $httpBody = $_tempBody;
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [
                    [
                        'Content-type' => 'multipart/form-data',
                    ]
                ];
                
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }
        // this endpoint requires OAuth (access token)
        if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }
        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }
        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );
        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHostAccounting() . $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;
    }
}
