# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.bad_request_error import BadRequestError
from ..errors.internal_server_error import InternalServerError
from ..errors.service_unavailable_error import ServiceUnavailableError
from ..errors.unauthorized_error import UnauthorizedError
from ..types.boarding_link_api_response import BoardingLinkApiResponse
from ..types.orgid import Orgid
from ..types.payabli_api_response import PayabliApiResponse
from ..types.payabli_api_response_template_id import PayabliApiResponseTemplateId
from ..types.template_code import TemplateCode
from ..types.template_content import TemplateContent
from ..types.template_name import TemplateName
from ..types.template_query_record import TemplateQueryRecord
from ..types.template_query_response import TemplateQueryResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawTemplatesClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def add_template(
        self,
        org_id_: int,
        *,
        org_id: typing.Optional[Orgid] = OMIT,
        pricing_id: typing.Optional[int] = OMIT,
        template_code: typing.Optional[TemplateCode] = OMIT,
        template_content: typing.Optional[TemplateContent] = OMIT,
        template_description: typing.Optional[str] = OMIT,
        template_name: typing.Optional[TemplateName] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayabliApiResponseTemplateId]:
        """
        Creates a boarding template in an organization.

        Parameters
        ----------
        org_id_ : int
            The numeric identifier for organization, assigned by Payabli.

        org_id : typing.Optional[Orgid]
            The ID of the organization the template belongs to.

        pricing_id : typing.Optional[int]

        template_code : typing.Optional[TemplateCode]

        template_content : typing.Optional[TemplateContent]

        template_description : typing.Optional[str]
            A description for the template.

        template_name : typing.Optional[TemplateName]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayabliApiResponseTemplateId]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"Templates/{jsonable_encoder(org_id_)}",
            method="POST",
            json={
                "orgId": org_id,
                "pricingId": pricing_id,
                "templateCode": template_code,
                "templateContent": convert_and_respect_annotation_metadata(
                    object_=template_content, annotation=TemplateContent, direction="write"
                ),
                "templateDescription": template_description,
                "templateName": template_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayabliApiResponseTemplateId,
                    parse_obj_as(
                        type_=PayabliApiResponseTemplateId,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_template(
        self, template_id: float, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[PayabliApiResponseTemplateId]:
        """
        Deletes a template by ID.

        Parameters
        ----------
        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayabliApiResponseTemplateId]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"Templates/{jsonable_encoder(template_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayabliApiResponseTemplateId,
                    parse_obj_as(
                        type_=PayabliApiResponseTemplateId,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def getlink_template(
        self, ignore_empty: bool, template_id: float, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[BoardingLinkApiResponse]:
        """
        Generates a boarding link from a boarding template.

        Parameters
        ----------
        ignore_empty : bool
            Ignore read-only and empty fields Default is `false`. If `ignoreEmpty` = `false` and any field is empty, then the request returns a failure response. If `ignoreEmpty` = `true`, the request returns the boarding link name regardless of whether fields are empty.

        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[BoardingLinkApiResponse]
            Success.
        """
        _response = self._client_wrapper.httpx_client.request(
            f"Templates/getlink/{jsonable_encoder(template_id)}/{jsonable_encoder(ignore_empty)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BoardingLinkApiResponse,
                    parse_obj_as(
                        type_=BoardingLinkApiResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_template(
        self, template_id: float, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[TemplateQueryRecord]:
        """
        Retrieves a boarding template's details by ID.

        Parameters
        ----------
        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[TemplateQueryRecord]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"Templates/get/{jsonable_encoder(template_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TemplateQueryRecord,
                    parse_obj_as(
                        type_=TemplateQueryRecord,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_templates(
        self,
        org_id: int,
        *,
        from_record: typing.Optional[int] = None,
        limit_record: typing.Optional[int] = None,
        parameters: typing.Optional[typing.Dict[str, typing.Optional[str]]] = None,
        sort_by: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[TemplateQueryResponse]:
        """
        Retrieves a list of boarding templates for an organization. Use filters to limit results. You can't make a request that includes filters from the API console in the documentation. The response won't be filtered. Instead, copy the request, remove `parameters=` and run the request in a different client.

        Parameters
        ----------
        org_id : int
            The numeric identifier for organization, assigned by Payabli.

        from_record : typing.Optional[int]
            The number of records to skip before starting to collect the result set.

        limit_record : typing.Optional[int]
            Max number of records to return for the query. Use `0` or negative value to return all records.

        parameters : typing.Optional[typing.Dict[str, typing.Optional[str]]]

            Collection of field names, conditions, and values used to filter the query.

            <Info>
              **You must remove `parameters=` from the request before you send it, otherwise Payabli will ignore the filters.**

              Because of a technical limitation, you can't make a request that includes filters from the API console on this page. The response won't be filtered. Instead, copy the request, remove `parameters=` and run the request in a different client.

              For example:

              --url https://api-sandbox.payabli.com/api/Query/transactions/org/236?parameters=totalAmount(gt)=1000&limitRecord=20

              should become:

              --url https://api-sandbox.payabli.com/api/Query/transactions/org/236?totalAmount(gt)=1000&limitRecord=20
            </Info>


            See [Filters and Conditions Reference](/developers/developer-guides/pay-ops-reporting-engine-overview#filters-and-conditions-reference) for help.

            List of field names accepted:
            - `createdAt` (gt, ge, lt, le, eq, ne)
            - `title` (ct, nct)
            - `description` (ct, nct)
            - `code` (ct, nct)
            - `orgParentname` (ct, nct)

            List of comparison accepted - enclosed between parentheses:
            - eq or empty => equal
            - gt => greater than
            - ge => greater or equal
            - lt => less than
            - le => less or equal
            - ne => not equal
            - ct => contains
            - nct => not contains
            - in => inside array
            - nin => not inside array

            List of parameters accepted:
            - limitRecord : max number of records for query (default="20", "0" or negative value for all)
            - fromRecord : initial record in query

            Example: title(ct)=hoa return all records with title containing "hoa"

        sort_by : typing.Optional[str]
            The field name to use for sorting results. Use `desc(field_name)` to sort descending by `field_name`, and use `asc(field_name)` to sort ascending by `field_name`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[TemplateQueryResponse]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"Query/templates/{jsonable_encoder(org_id)}",
            method="GET",
            params={
                "fromRecord": from_record,
                "limitRecord": limit_record,
                "parameters": parameters,
                "sortBy": sort_by,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TemplateQueryResponse,
                    parse_obj_as(
                        type_=TemplateQueryResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_template(
        self,
        template_id: float,
        *,
        org_id: typing.Optional[Orgid] = OMIT,
        pricing_id: typing.Optional[int] = OMIT,
        template_code: typing.Optional[TemplateCode] = OMIT,
        template_content: typing.Optional[TemplateContent] = OMIT,
        template_description: typing.Optional[str] = OMIT,
        template_name: typing.Optional[TemplateName] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[PayabliApiResponseTemplateId]:
        """
        Updates a boarding template by ID.

        Parameters
        ----------
        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        org_id : typing.Optional[Orgid]
            The ID of the organization the template belongs to.

        pricing_id : typing.Optional[int]

        template_code : typing.Optional[TemplateCode]

        template_content : typing.Optional[TemplateContent]

        template_description : typing.Optional[str]
            A description for the template.

        template_name : typing.Optional[TemplateName]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[PayabliApiResponseTemplateId]
            Success
        """
        _response = self._client_wrapper.httpx_client.request(
            f"Templates/{jsonable_encoder(template_id)}",
            method="PUT",
            json={
                "orgId": org_id,
                "pricingId": pricing_id,
                "templateCode": template_code,
                "templateContent": convert_and_respect_annotation_metadata(
                    object_=template_content, annotation=TemplateContent, direction="write"
                ),
                "templateDescription": template_description,
                "templateName": template_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayabliApiResponseTemplateId,
                    parse_obj_as(
                        type_=PayabliApiResponseTemplateId,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawTemplatesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def add_template(
        self,
        org_id_: int,
        *,
        org_id: typing.Optional[Orgid] = OMIT,
        pricing_id: typing.Optional[int] = OMIT,
        template_code: typing.Optional[TemplateCode] = OMIT,
        template_content: typing.Optional[TemplateContent] = OMIT,
        template_description: typing.Optional[str] = OMIT,
        template_name: typing.Optional[TemplateName] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayabliApiResponseTemplateId]:
        """
        Creates a boarding template in an organization.

        Parameters
        ----------
        org_id_ : int
            The numeric identifier for organization, assigned by Payabli.

        org_id : typing.Optional[Orgid]
            The ID of the organization the template belongs to.

        pricing_id : typing.Optional[int]

        template_code : typing.Optional[TemplateCode]

        template_content : typing.Optional[TemplateContent]

        template_description : typing.Optional[str]
            A description for the template.

        template_name : typing.Optional[TemplateName]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayabliApiResponseTemplateId]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"Templates/{jsonable_encoder(org_id_)}",
            method="POST",
            json={
                "orgId": org_id,
                "pricingId": pricing_id,
                "templateCode": template_code,
                "templateContent": convert_and_respect_annotation_metadata(
                    object_=template_content, annotation=TemplateContent, direction="write"
                ),
                "templateDescription": template_description,
                "templateName": template_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayabliApiResponseTemplateId,
                    parse_obj_as(
                        type_=PayabliApiResponseTemplateId,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_template(
        self, template_id: float, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[PayabliApiResponseTemplateId]:
        """
        Deletes a template by ID.

        Parameters
        ----------
        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayabliApiResponseTemplateId]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"Templates/{jsonable_encoder(template_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayabliApiResponseTemplateId,
                    parse_obj_as(
                        type_=PayabliApiResponseTemplateId,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def getlink_template(
        self, ignore_empty: bool, template_id: float, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[BoardingLinkApiResponse]:
        """
        Generates a boarding link from a boarding template.

        Parameters
        ----------
        ignore_empty : bool
            Ignore read-only and empty fields Default is `false`. If `ignoreEmpty` = `false` and any field is empty, then the request returns a failure response. If `ignoreEmpty` = `true`, the request returns the boarding link name regardless of whether fields are empty.

        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[BoardingLinkApiResponse]
            Success.
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"Templates/getlink/{jsonable_encoder(template_id)}/{jsonable_encoder(ignore_empty)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    BoardingLinkApiResponse,
                    parse_obj_as(
                        type_=BoardingLinkApiResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_template(
        self, template_id: float, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[TemplateQueryRecord]:
        """
        Retrieves a boarding template's details by ID.

        Parameters
        ----------
        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[TemplateQueryRecord]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"Templates/get/{jsonable_encoder(template_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TemplateQueryRecord,
                    parse_obj_as(
                        type_=TemplateQueryRecord,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_templates(
        self,
        org_id: int,
        *,
        from_record: typing.Optional[int] = None,
        limit_record: typing.Optional[int] = None,
        parameters: typing.Optional[typing.Dict[str, typing.Optional[str]]] = None,
        sort_by: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[TemplateQueryResponse]:
        """
        Retrieves a list of boarding templates for an organization. Use filters to limit results. You can't make a request that includes filters from the API console in the documentation. The response won't be filtered. Instead, copy the request, remove `parameters=` and run the request in a different client.

        Parameters
        ----------
        org_id : int
            The numeric identifier for organization, assigned by Payabli.

        from_record : typing.Optional[int]
            The number of records to skip before starting to collect the result set.

        limit_record : typing.Optional[int]
            Max number of records to return for the query. Use `0` or negative value to return all records.

        parameters : typing.Optional[typing.Dict[str, typing.Optional[str]]]

            Collection of field names, conditions, and values used to filter the query.

            <Info>
              **You must remove `parameters=` from the request before you send it, otherwise Payabli will ignore the filters.**

              Because of a technical limitation, you can't make a request that includes filters from the API console on this page. The response won't be filtered. Instead, copy the request, remove `parameters=` and run the request in a different client.

              For example:

              --url https://api-sandbox.payabli.com/api/Query/transactions/org/236?parameters=totalAmount(gt)=1000&limitRecord=20

              should become:

              --url https://api-sandbox.payabli.com/api/Query/transactions/org/236?totalAmount(gt)=1000&limitRecord=20
            </Info>


            See [Filters and Conditions Reference](/developers/developer-guides/pay-ops-reporting-engine-overview#filters-and-conditions-reference) for help.

            List of field names accepted:
            - `createdAt` (gt, ge, lt, le, eq, ne)
            - `title` (ct, nct)
            - `description` (ct, nct)
            - `code` (ct, nct)
            - `orgParentname` (ct, nct)

            List of comparison accepted - enclosed between parentheses:
            - eq or empty => equal
            - gt => greater than
            - ge => greater or equal
            - lt => less than
            - le => less or equal
            - ne => not equal
            - ct => contains
            - nct => not contains
            - in => inside array
            - nin => not inside array

            List of parameters accepted:
            - limitRecord : max number of records for query (default="20", "0" or negative value for all)
            - fromRecord : initial record in query

            Example: title(ct)=hoa return all records with title containing "hoa"

        sort_by : typing.Optional[str]
            The field name to use for sorting results. Use `desc(field_name)` to sort descending by `field_name`, and use `asc(field_name)` to sort ascending by `field_name`.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[TemplateQueryResponse]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"Query/templates/{jsonable_encoder(org_id)}",
            method="GET",
            params={
                "fromRecord": from_record,
                "limitRecord": limit_record,
                "parameters": parameters,
                "sortBy": sort_by,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    TemplateQueryResponse,
                    parse_obj_as(
                        type_=TemplateQueryResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_template(
        self,
        template_id: float,
        *,
        org_id: typing.Optional[Orgid] = OMIT,
        pricing_id: typing.Optional[int] = OMIT,
        template_code: typing.Optional[TemplateCode] = OMIT,
        template_content: typing.Optional[TemplateContent] = OMIT,
        template_description: typing.Optional[str] = OMIT,
        template_name: typing.Optional[TemplateName] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[PayabliApiResponseTemplateId]:
        """
        Updates a boarding template by ID.

        Parameters
        ----------
        template_id : float
            The boarding template ID. Can be found at the end of the boarding template URL in PartnerHub. Example: `https://partner-sandbox.payabli.com/myorganization/boarding/edittemplate/80`. Here, the template ID is `80`.

        org_id : typing.Optional[Orgid]
            The ID of the organization the template belongs to.

        pricing_id : typing.Optional[int]

        template_code : typing.Optional[TemplateCode]

        template_content : typing.Optional[TemplateContent]

        template_description : typing.Optional[str]
            A description for the template.

        template_name : typing.Optional[TemplateName]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[PayabliApiResponseTemplateId]
            Success
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"Templates/{jsonable_encoder(template_id)}",
            method="PUT",
            json={
                "orgId": org_id,
                "pricingId": pricing_id,
                "templateCode": template_code,
                "templateContent": convert_and_respect_annotation_metadata(
                    object_=template_content, annotation=TemplateContent, direction="write"
                ),
                "templateDescription": template_description,
                "templateName": template_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    PayabliApiResponseTemplateId,
                    parse_obj_as(
                        type_=PayabliApiResponseTemplateId,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Optional[typing.Any],
                        parse_obj_as(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        PayabliApiResponse,
                        parse_obj_as(
                            type_=PayabliApiResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
