<?php
/**
 * AbsenceApi
 * PHP version 8.1
 *
 * @category Class
 * @package  StevenBuehner\ChurchTools
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * ChurchTools REST API
 *
 * The ChurchTools REST API is the best entry point for developers to access ChurchTools. <br><br> **Authentication:** You need to be authorized to use some endpoints. Those endpoints are marked by a gray lock symbol. If you view the documentation, while you are logged into ChurchTools, all requests are already authorized. If you want to authorized a request, you need to provide a `Login Token` as `Authorization` header in the format `Authorization: Login<token>` or send a valid cookie. You can use the green \"Authorize\" dialog to enter those details and see how a request would look like in detail. <br><br> **Missing Endpoints:** Not all features are yet available by our new REST API. This documentation will grow in the future. We are working hard to add new endpoints with every ChurchTools version. The documentation will always show only those endpoints you can use with your ChurchTools installation.
 *
 * The version of the OpenAPI document: 0.1.0
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.21.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 StevenBuehner\ChurchTools\Api;

use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Client;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\ClientInterface;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Exception\ConnectException;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Exception\RequestException;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\MultipartStream;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\Request;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\RequestOptions;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\Psr\Http\Message\RequestInterface;
use StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\Psr\Http\Message\ResponseInterface;
use StevenBuehner\ChurchTools\ApiException;
use StevenBuehner\ChurchTools\Configuration;
use StevenBuehner\ChurchTools\FormDataProcessor;
use StevenBuehner\ChurchTools\HeaderSelector;
use StevenBuehner\ChurchTools\ObjectSerializer;

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

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

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

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

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'deletePersonsAbsence' => [
            'application/json',
        ],
        'getGroupsAbsences' => [
            'application/json',
        ],
        'getPersonsAbsence' => [
            'application/json',
        ],
        'getPersonsAbsences' => [
            'application/json',
        ],
        'postPersonsAbsences' => [
            'application/json',
        ],
        'putPersonsAbsence' => [
            'application/json',
        ],
    ];

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     * @param int             $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        ?ClientInterface $client = null,
        ?Configuration $config = null,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: Configuration::getDefaultConfiguration();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex($hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index
     *
     * @return int Host index
     */
    public function getHostIndex()
    {
        return $this->hostIndex;
    }

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

    /**
     * Operation deletePersonsAbsence
     *
     * Delete absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deletePersonsAbsence'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return void
     */
    public function deletePersonsAbsence($person_id, $id, string $contentType = self::contentTypes['deletePersonsAbsence'][0])
    {
        $this->deletePersonsAbsenceWithHttpInfo($person_id, $id, $contentType);
    }

    /**
     * Operation deletePersonsAbsenceWithHttpInfo
     *
     * Delete absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deletePersonsAbsence'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of null, HTTP status code, HTTP response headers (array of strings)
     */
    public function deletePersonsAbsenceWithHttpInfo($person_id, $id, string $contentType = self::contentTypes['deletePersonsAbsence'][0])
    {
        $request = $this->deletePersonsAbsenceRequest($person_id, $id, $contentType);

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

            $statusCode = $response->getStatusCode();


            return [null, $statusCode, $response->getHeaders()];
        } catch (ApiException $e) {
            switch ($e->getCode()) {
            }
        

            throw $e;
        }
    }

    /**
     * Operation deletePersonsAbsenceAsync
     *
     * Delete absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deletePersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function deletePersonsAbsenceAsync($person_id, $id, string $contentType = self::contentTypes['deletePersonsAbsence'][0])
    {
        return $this->deletePersonsAbsenceAsyncWithHttpInfo($person_id, $id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation deletePersonsAbsenceAsyncWithHttpInfo
     *
     * Delete absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deletePersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function deletePersonsAbsenceAsyncWithHttpInfo($person_id, $id, string $contentType = self::contentTypes['deletePersonsAbsence'][0])
    {
        $returnType = '';
        $request = $this->deletePersonsAbsenceRequest($person_id, $id, $contentType);

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

    /**
     * Create request for operation 'deletePersonsAbsence'
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['deletePersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\Request
     */
    public function deletePersonsAbsenceRequest($person_id, $id, string $contentType = self::contentTypes['deletePersonsAbsence'][0])
    {

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

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


        $resourcePath = '/persons/{personId}/absences/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

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

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

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }

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

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

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

    /**
     * Operation getGroupsAbsences
     *
     * Fetch all absences for persons in a group
     *
     * @param  int $group_id ID of group (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getGroupsAbsences'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response
     */
    public function getGroupsAbsences($group_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getGroupsAbsences'][0])
    {
        list($response) = $this->getGroupsAbsencesWithHttpInfo($group_id, $from_date, $to_date, $contentType);
        return $response;
    }

    /**
     * Operation getGroupsAbsencesWithHttpInfo
     *
     * Fetch all absences for persons in a group
     *
     * @param  int $group_id ID of group (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getGroupsAbsences'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function getGroupsAbsencesWithHttpInfo($group_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getGroupsAbsences'][0])
    {
        $request = $this->getGroupsAbsencesRequest($group_id, $from_date, $to_date, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response',
                        $request,
                        $response,
                    );
            }

            

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

            return $this->handleResponseWithDataType(
                '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getGroupsAbsencesAsync
     *
     * Fetch all absences for persons in a group
     *
     * @param  int $group_id ID of group (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getGroupsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function getGroupsAbsencesAsync($group_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getGroupsAbsences'][0])
    {
        return $this->getGroupsAbsencesAsyncWithHttpInfo($group_id, $from_date, $to_date, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getGroupsAbsencesAsyncWithHttpInfo
     *
     * Fetch all absences for persons in a group
     *
     * @param  int $group_id ID of group (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getGroupsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function getGroupsAbsencesAsyncWithHttpInfo($group_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getGroupsAbsences'][0])
    {
        $returnType = '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response';
        $request = $this->getGroupsAbsencesRequest($group_id, $from_date, $to_date, $contentType);

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

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

    /**
     * Create request for operation 'getGroupsAbsences'
     *
     * @param  int $group_id ID of group (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getGroupsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\Request
     */
    public function getGroupsAbsencesRequest($group_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getGroupsAbsences'][0])
    {

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




        $resourcePath = '/groups/{groupId}/absences';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


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


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

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

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

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }

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

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

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

    /**
     * Operation getPersonsAbsence
     *
     * Fetch one absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response
     */
    public function getPersonsAbsence($person_id, $id, string $contentType = self::contentTypes['getPersonsAbsence'][0])
    {
        list($response) = $this->getPersonsAbsenceWithHttpInfo($person_id, $id, $contentType);
        return $response;
    }

    /**
     * Operation getPersonsAbsenceWithHttpInfo
     *
     * Fetch one absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPersonsAbsenceWithHttpInfo($person_id, $id, string $contentType = self::contentTypes['getPersonsAbsence'][0])
    {
        $request = $this->getPersonsAbsenceRequest($person_id, $id, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response',
                        $request,
                        $response,
                    );
            }

            

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

            return $this->handleResponseWithDataType(
                '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getPersonsAbsenceAsync
     *
     * Fetch one absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function getPersonsAbsenceAsync($person_id, $id, string $contentType = self::contentTypes['getPersonsAbsence'][0])
    {
        return $this->getPersonsAbsenceAsyncWithHttpInfo($person_id, $id, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getPersonsAbsenceAsyncWithHttpInfo
     *
     * Fetch one absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function getPersonsAbsenceAsyncWithHttpInfo($person_id, $id, string $contentType = self::contentTypes['getPersonsAbsence'][0])
    {
        $returnType = '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response';
        $request = $this->getPersonsAbsenceRequest($person_id, $id, $contentType);

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

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

    /**
     * Create request for operation 'getPersonsAbsence'
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\Request
     */
    public function getPersonsAbsenceRequest($person_id, $id, string $contentType = self::contentTypes['getPersonsAbsence'][0])
    {

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

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


        $resourcePath = '/persons/{personId}/absences/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

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

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

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }

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

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

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

    /**
     * Operation getPersonsAbsences
     *
     * Fetch all absences for a person
     *
     * @param  int $person_id ID of person (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response
     */
    public function getPersonsAbsences($person_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getPersonsAbsences'][0])
    {
        list($response) = $this->getPersonsAbsencesWithHttpInfo($person_id, $from_date, $to_date, $contentType);
        return $response;
    }

    /**
     * Operation getPersonsAbsencesWithHttpInfo
     *
     * Fetch all absences for a person
     *
     * @param  int $person_id ID of person (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function getPersonsAbsencesWithHttpInfo($person_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getPersonsAbsences'][0])
    {
        $request = $this->getPersonsAbsencesRequest($person_id, $from_date, $to_date, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response',
                        $request,
                        $response,
                    );
            }

            

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

            return $this->handleResponseWithDataType(
                '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation getPersonsAbsencesAsync
     *
     * Fetch all absences for a person
     *
     * @param  int $person_id ID of person (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function getPersonsAbsencesAsync($person_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getPersonsAbsences'][0])
    {
        return $this->getPersonsAbsencesAsyncWithHttpInfo($person_id, $from_date, $to_date, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getPersonsAbsencesAsyncWithHttpInfo
     *
     * Fetch all absences for a person
     *
     * @param  int $person_id ID of person (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function getPersonsAbsencesAsyncWithHttpInfo($person_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getPersonsAbsences'][0])
    {
        $returnType = '\StevenBuehner\ChurchTools\Model\GetGroupsAbsences200Response';
        $request = $this->getPersonsAbsencesRequest($person_id, $from_date, $to_date, $contentType);

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

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

    /**
     * Create request for operation 'getPersonsAbsences'
     *
     * @param  int $person_id ID of person (required)
     * @param  \DateTime|null $from_date Return absences starting from this date. (optional)
     * @param  \DateTime|null $to_date Return absences till this date. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['getPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\Request
     */
    public function getPersonsAbsencesRequest($person_id, $from_date = null, $to_date = null, string $contentType = self::contentTypes['getPersonsAbsences'][0])
    {

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




        $resourcePath = '/persons/{personId}/absences';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


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


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

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

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

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }

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

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

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

    /**
     * Operation postPersonsAbsences
     *
     * Create new absence for person
     *
     * @param  int $person_id ID of person (required)
     * @param  \StevenBuehner\ChurchTools\Model\PostPersonsAbsencesRequest|null $post_persons_absences_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['postPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response
     */
    public function postPersonsAbsences($person_id, $post_persons_absences_request = null, string $contentType = self::contentTypes['postPersonsAbsences'][0])
    {
        list($response) = $this->postPersonsAbsencesWithHttpInfo($person_id, $post_persons_absences_request, $contentType);
        return $response;
    }

    /**
     * Operation postPersonsAbsencesWithHttpInfo
     *
     * Create new absence for person
     *
     * @param  int $person_id ID of person (required)
     * @param  \StevenBuehner\ChurchTools\Model\PostPersonsAbsencesRequest|null $post_persons_absences_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['postPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function postPersonsAbsencesWithHttpInfo($person_id, $post_persons_absences_request = null, string $contentType = self::contentTypes['postPersonsAbsences'][0])
    {
        $request = $this->postPersonsAbsencesRequest($person_id, $post_persons_absences_request, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 201:
                    return $this->handleResponseWithDataType(
                        '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response',
                        $request,
                        $response,
                    );
            }

            

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

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

            throw $e;
        }
    }

    /**
     * Operation postPersonsAbsencesAsync
     *
     * Create new absence for person
     *
     * @param  int $person_id ID of person (required)
     * @param  \StevenBuehner\ChurchTools\Model\PostPersonsAbsencesRequest|null $post_persons_absences_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['postPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function postPersonsAbsencesAsync($person_id, $post_persons_absences_request = null, string $contentType = self::contentTypes['postPersonsAbsences'][0])
    {
        return $this->postPersonsAbsencesAsyncWithHttpInfo($person_id, $post_persons_absences_request, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation postPersonsAbsencesAsyncWithHttpInfo
     *
     * Create new absence for person
     *
     * @param  int $person_id ID of person (required)
     * @param  \StevenBuehner\ChurchTools\Model\PostPersonsAbsencesRequest|null $post_persons_absences_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['postPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function postPersonsAbsencesAsyncWithHttpInfo($person_id, $post_persons_absences_request = null, string $contentType = self::contentTypes['postPersonsAbsences'][0])
    {
        $returnType = '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response';
        $request = $this->postPersonsAbsencesRequest($person_id, $post_persons_absences_request, $contentType);

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

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

    /**
     * Create request for operation 'postPersonsAbsences'
     *
     * @param  int $person_id ID of person (required)
     * @param  \StevenBuehner\ChurchTools\Model\PostPersonsAbsencesRequest|null $post_persons_absences_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['postPersonsAbsences'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\Request
     */
    public function postPersonsAbsencesRequest($person_id, $post_persons_absences_request = null, string $contentType = self::contentTypes['postPersonsAbsences'][0])
    {

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



        $resourcePath = '/persons/{personId}/absences';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

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

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

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }

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

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

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

    /**
     * Operation putPersonsAbsence
     *
     * Update absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  \StevenBuehner\ChurchTools\Model\PutPersonsAbsenceRequest|null $put_persons_absence_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['putPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response
     */
    public function putPersonsAbsence($person_id, $id, $put_persons_absence_request = null, string $contentType = self::contentTypes['putPersonsAbsence'][0])
    {
        list($response) = $this->putPersonsAbsenceWithHttpInfo($person_id, $id, $put_persons_absence_request, $contentType);
        return $response;
    }

    /**
     * Operation putPersonsAbsenceWithHttpInfo
     *
     * Update absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  \StevenBuehner\ChurchTools\Model\PutPersonsAbsenceRequest|null $put_persons_absence_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['putPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \StevenBuehner\ChurchTools\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response, HTTP status code, HTTP response headers (array of strings)
     */
    public function putPersonsAbsenceWithHttpInfo($person_id, $id, $put_persons_absence_request = null, string $contentType = self::contentTypes['putPersonsAbsence'][0])
    {
        $request = $this->putPersonsAbsenceRequest($person_id, $id, $put_persons_absence_request, $contentType);

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

            $statusCode = $response->getStatusCode();


            switch($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response',
                        $request,
                        $response,
                    );
            }

            

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

            return $this->handleResponseWithDataType(
                '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation putPersonsAbsenceAsync
     *
     * Update absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  \StevenBuehner\ChurchTools\Model\PutPersonsAbsenceRequest|null $put_persons_absence_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['putPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function putPersonsAbsenceAsync($person_id, $id, $put_persons_absence_request = null, string $contentType = self::contentTypes['putPersonsAbsence'][0])
    {
        return $this->putPersonsAbsenceAsyncWithHttpInfo($person_id, $id, $put_persons_absence_request, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation putPersonsAbsenceAsyncWithHttpInfo
     *
     * Update absence
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  \StevenBuehner\ChurchTools\Model\PutPersonsAbsenceRequest|null $put_persons_absence_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['putPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Promise\PromiseInterface
     */
    public function putPersonsAbsenceAsyncWithHttpInfo($person_id, $id, $put_persons_absence_request = null, string $contentType = self::contentTypes['putPersonsAbsence'][0])
    {
        $returnType = '\StevenBuehner\ChurchTools\Model\PostPersonsAbsences201Response';
        $request = $this->putPersonsAbsenceRequest($person_id, $id, $put_persons_absence_request, $contentType);

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

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

    /**
     * Create request for operation 'putPersonsAbsence'
     *
     * @param  int $person_id ID of person (required)
     * @param  int $id ID of Entity (required)
     * @param  \StevenBuehner\ChurchTools\Model\PutPersonsAbsenceRequest|null $put_persons_absence_request Absences can be all-day or with a specific time. Either &#x60;startDate&#x60;, &#x60;endDate&#x60;  or &#x60;startTime&#x60;, &#x60;endTime&#x60; MUST be present. If &#x60;*Time&#x60; is given, the &#x60;*Date&#x60; value will be ignored. (optional)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['putPersonsAbsence'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \StevenBuehner\sbChurchtoolsGrouphomepage\Vendor\GuzzleHttp\Psr7\Request
     */
    public function putPersonsAbsenceRequest($person_id, $id, $put_persons_absence_request = null, string $contentType = self::contentTypes['putPersonsAbsence'][0])
    {

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

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



        $resourcePath = '/persons/{personId}/absences/{id}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



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


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

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

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

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }

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

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

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

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

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

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

        return $options;
    }

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

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

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

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