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

import datetime as dt
import typing

from .....core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .....core.request_options import RequestOptions
from ....commons.types.facility_type_code import FacilityTypeCode
from ....commons.types.network_type import NetworkType
from ....commons.types.page_token import PageToken
from ....commons.types.payer_plan_group_id import PayerPlanGroupId
from ....commons.types.procedure_modifier import ProcedureModifier
from ....commons.types.rate_id import RateId
from ....commons.types.service_line_id import ServiceLineId
from ....commons.types.state import State
from ....organization_providers.resources.v_2.types.license_type import LicenseType
from ....organization_providers.resources.v_2.types.organization_provider_id import OrganizationProviderId
from ....payers.resources.v_3.types.payer_uuid import PayerUuid
from .raw_client import AsyncRawV3Client, RawV3Client
from .types.dimension_name import DimensionName
from .types.dimensions_page import DimensionsPage
from .types.match_result import MatchResult
from .types.match_test_result import MatchTestResult
from .types.optional_dimensions import OptionalDimensions
from .types.payer_threshold import PayerThreshold
from .types.payer_thresholds_page import PayerThresholdsPage
from .types.rate import Rate
from .types.rate_upload import RateUpload
from .types.rates_page import RatesPage

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


class V3Client:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawV3Client(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawV3Client:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawV3Client
        """
        return self._raw_client

    def get_match(
        self, service_line_id: ServiceLineId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[MatchResult]:
        """
        Gets the rate that matches a service line.  No result means no rate exists matching the service line's dimensions.

        Parameters
        ----------
        service_line_id : ServiceLineId

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

        Returns
        -------
        typing.Optional[MatchResult]

        Examples
        --------
        import uuid

        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.get_match(
            service_line_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = self._raw_client.get_match(service_line_id, request_options=request_options)
        return _response.data

    def test_match(
        self,
        service_line_id: ServiceLineId,
        rate_id: RateId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MatchTestResult:
        """
        Tests a service line against a rate to see if it matches.

        Parameters
        ----------
        service_line_id : ServiceLineId

        rate_id : RateId

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

        Returns
        -------
        MatchTestResult

        Examples
        --------
        import uuid

        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.test_match(
            service_line_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            rate_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = self._raw_client.test_match(service_line_id, rate_id, request_options=request_options)
        return _response.data

    def get_multi(
        self,
        *,
        page_token: typing.Optional[PageToken] = None,
        limit: typing.Optional[int] = None,
        active_date: typing.Optional[dt.date] = None,
        payer_uuid: typing.Optional[PayerUuid] = None,
        organization_billing_provider_id: typing.Optional[OrganizationProviderId] = None,
        states: typing.Optional[typing.Union[State, typing.Sequence[State]]] = None,
        zip_codes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        license_types: typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]] = None,
        facility_type_codes: typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]] = None,
        network_types: typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]] = None,
        payer_plan_group_ids: typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]] = None,
        cpt_code: typing.Optional[str] = None,
        modifiers: typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RatesPage:
        """
        Gets a list of dimensions with their rates. The rates returned will always be the most recent versions of those rates.

        Parameters
        ----------
        page_token : typing.Optional[PageToken]

        limit : typing.Optional[int]
            Max number of dimensions returned. Defaults to 100. Max is 100.

        active_date : typing.Optional[dt.date]

        payer_uuid : typing.Optional[PayerUuid]

        organization_billing_provider_id : typing.Optional[OrganizationProviderId]

        states : typing.Optional[typing.Union[State, typing.Sequence[State]]]

        zip_codes : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        license_types : typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]]

        facility_type_codes : typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]]

        network_types : typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]]

        payer_plan_group_ids : typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]]

        cpt_code : typing.Optional[str]

        modifiers : typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]]

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

        Returns
        -------
        RatesPage

        Examples
        --------
        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.get_multi()
        """
        _response = self._raw_client.get_multi(
            page_token=page_token,
            limit=limit,
            active_date=active_date,
            payer_uuid=payer_uuid,
            organization_billing_provider_id=organization_billing_provider_id,
            states=states,
            zip_codes=zip_codes,
            license_types=license_types,
            facility_type_codes=facility_type_codes,
            network_types=network_types,
            payer_plan_group_ids=payer_plan_group_ids,
            cpt_code=cpt_code,
            modifiers=modifiers,
            request_options=request_options,
        )
        return _response.data

    def get_unique_values_for_dimension(
        self,
        *,
        pivot_dimension: DimensionName,
        page_token: typing.Optional[PageToken] = None,
        limit: typing.Optional[int] = None,
        payer_uuid: typing.Optional[PayerUuid] = None,
        organization_billing_provider_id: typing.Optional[OrganizationProviderId] = None,
        states: typing.Optional[typing.Union[State, typing.Sequence[State]]] = None,
        zip_codes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        license_types: typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]] = None,
        facility_type_codes: typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]] = None,
        network_types: typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]] = None,
        payer_plan_group_ids: typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]] = None,
        cpt_code: typing.Optional[str] = None,
        modifiers: typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> DimensionsPage:
        """
        Gets unique values for a dimension based on other selection criteria. The response is a list of dimensions with your criteria and the unique values populated. This API is useful for driving pivots on dimension values.

        Parameters
        ----------
        pivot_dimension : DimensionName
            The name of the dimension to fetch unique values for.

        page_token : typing.Optional[PageToken]

        limit : typing.Optional[int]
            Max number of values returned. Defaults to 1000. Max is 1000.

        payer_uuid : typing.Optional[PayerUuid]

        organization_billing_provider_id : typing.Optional[OrganizationProviderId]

        states : typing.Optional[typing.Union[State, typing.Sequence[State]]]

        zip_codes : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        license_types : typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]]

        facility_type_codes : typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]]

        network_types : typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]]

        payer_plan_group_ids : typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]]

        cpt_code : typing.Optional[str]

        modifiers : typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]]

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

        Returns
        -------
        DimensionsPage

        Examples
        --------
        from candid import CandidApiClient
        from candid.resources.fee_schedules.resources.v_3 import DimensionName

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.get_unique_values_for_dimension(
            pivot_dimension=DimensionName.PAYER_UUID,
        )
        """
        _response = self._raw_client.get_unique_values_for_dimension(
            pivot_dimension=pivot_dimension,
            page_token=page_token,
            limit=limit,
            payer_uuid=payer_uuid,
            organization_billing_provider_id=organization_billing_provider_id,
            states=states,
            zip_codes=zip_codes,
            license_types=license_types,
            facility_type_codes=facility_type_codes,
            network_types=network_types,
            payer_plan_group_ids=payer_plan_group_ids,
            cpt_code=cpt_code,
            modifiers=modifiers,
            request_options=request_options,
        )
        return _response.data

    def get_rate_history(
        self, rate_id: RateId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Rate]:
        """
        Gets every version of a rate.

        Parameters
        ----------
        rate_id : RateId

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

        Returns
        -------
        typing.List[Rate]

        Examples
        --------
        import uuid

        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.get_rate_history(
            rate_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = self._raw_client.get_rate_history(rate_id, request_options=request_options)
        return _response.data

    def upload_fee_schedule(
        self,
        *,
        dry_run: bool,
        rates: typing.Sequence[RateUpload],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[Rate]:
        """
        Uploads a new fee schedule.

        Each rate may either be totally new as qualified by it's dimensions or a new version for an existing rate.

        If adding a new version to an existing rate, the rate must be posted with the next version number (previous version + 1) or a EntityConflictError will
        be returned.

        Use the dry run flag to discover already existing rates and to run validations.  If validations for any rate fail, no rates will
        be saved to the system.

        Parameters
        ----------
        dry_run : bool

        rates : typing.Sequence[RateUpload]

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

        Returns
        -------
        typing.List[Rate]

        Examples
        --------
        import datetime
        import uuid

        from candid import CandidApiClient
        from candid.resources.commons import (
            FacilityTypeCode,
            NetworkType,
            ProcedureModifier,
            State,
        )
        from candid.resources.fee_schedules.resources.v_3 import (
            Dimensions,
            RateEntry,
            RateUpload_NewRate,
        )
        from candid.resources.organization_providers.resources.v_2 import LicenseType

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.upload_fee_schedule(
            dry_run=True,
            rates=[
                RateUpload_NewRate(
                    dimensions=Dimensions(
                        payer_uuid=uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        ),
                        organization_billing_provider_id=uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        ),
                        states=[State.AA],
                        zip_codes={"zip_codes"},
                        license_types=[LicenseType.MD],
                        facility_type_codes=[FacilityTypeCode.PHARMACY],
                        network_types=[NetworkType.PPO],
                        payer_plan_group_ids=[
                            uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            )
                        ],
                        cpt_code="cpt_code",
                        modifiers=[ProcedureModifier.AV],
                    ),
                    entries=[
                        RateEntry(
                            start_date=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            rate_cents=1,
                            is_deactivated=True,
                        ),
                        RateEntry(
                            start_date=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            rate_cents=1,
                            is_deactivated=True,
                        ),
                    ],
                ),
                RateUpload_NewRate(
                    dimensions=Dimensions(
                        payer_uuid=uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        ),
                        organization_billing_provider_id=uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        ),
                        states=[State.AA],
                        zip_codes={"zip_codes"},
                        license_types=[LicenseType.MD],
                        facility_type_codes=[FacilityTypeCode.PHARMACY],
                        network_types=[NetworkType.PPO],
                        payer_plan_group_ids=[
                            uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            )
                        ],
                        cpt_code="cpt_code",
                        modifiers=[ProcedureModifier.AV],
                    ),
                    entries=[
                        RateEntry(
                            start_date=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            rate_cents=1,
                            is_deactivated=True,
                        ),
                        RateEntry(
                            start_date=datetime.date.fromisoformat(
                                "2023-01-15",
                            ),
                            rate_cents=1,
                            is_deactivated=True,
                        ),
                    ],
                ),
            ],
        )
        """
        _response = self._raw_client.upload_fee_schedule(dry_run=dry_run, rates=rates, request_options=request_options)
        return _response.data

    def delete_rate(
        self, rate_id: RateId, version: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Soft deletes a rate from the system.  Only the most recent version of a rate can be deleted.

        Parameters
        ----------
        rate_id : RateId

        version : int

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

        Returns
        -------
        None

        Examples
        --------
        import uuid

        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.delete_rate(
            rate_id=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            version=1,
        )
        """
        _response = self._raw_client.delete_rate(rate_id, version, request_options=request_options)
        return _response.data

    def get_payer_thresholds_default(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> PayerThreshold:
        """
        Gets the default payer threshold

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

        Returns
        -------
        PayerThreshold

        Examples
        --------
        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.get_payer_thresholds_default()
        """
        _response = self._raw_client.get_payer_thresholds_default(request_options=request_options)
        return _response.data

    def get_payer_thresholds(
        self,
        *,
        payer_uuids: typing.Union[PayerUuid, typing.Sequence[PayerUuid]],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PayerThresholdsPage:
        """
        Gets a list of payers and thresholds by their uuids

        Parameters
        ----------
        payer_uuids : typing.Union[PayerUuid, typing.Sequence[PayerUuid]]

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

        Returns
        -------
        PayerThresholdsPage

        Examples
        --------
        import uuid

        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.get_payer_thresholds(
            payer_uuids=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
        )
        """
        _response = self._raw_client.get_payer_thresholds(payer_uuids=payer_uuids, request_options=request_options)
        return _response.data

    def set_payer_threshold(
        self, payer_uuid: PayerUuid, *, request: PayerThreshold, request_options: typing.Optional[RequestOptions] = None
    ) -> PayerThreshold:
        """
        Sets the threshold information for a payer

        Parameters
        ----------
        payer_uuid : PayerUuid

        request : PayerThreshold

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

        Returns
        -------
        PayerThreshold

        Examples
        --------
        import uuid

        from candid import CandidApiClient
        from candid.resources.fee_schedules.resources.v_3 import PayerThreshold

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.set_payer_threshold(
            payer_uuid=uuid.UUID(
                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
            ),
            request=PayerThreshold(
                disable_paid_incorrectly=True,
            ),
        )
        """
        _response = self._raw_client.set_payer_threshold(payer_uuid, request=request, request_options=request_options)
        return _response.data

    def hard_delete_rates(
        self, *, request: OptionalDimensions, request_options: typing.Optional[RequestOptions] = None
    ) -> int:
        """
        Hard deletes rates from the system that match the provided dimensions.  This is a destructive operation and cannot be undone.  If an empty dimensions object is provided, all rates will be hard deleted.  The maximum number of rates this API will delete at a time is 10000.  Returns the number of rates deleted and if that number is the maximum, the caller should call this API again to continue deleting rates.

        Parameters
        ----------
        request : OptionalDimensions

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

        Returns
        -------
        int

        Examples
        --------
        import uuid

        from candid import CandidApiClient
        from candid.resources.commons import (
            FacilityTypeCode,
            NetworkType,
            ProcedureModifier,
            State,
        )
        from candid.resources.fee_schedules.resources.v_3 import OptionalDimensions
        from candid.resources.organization_providers.resources.v_2 import LicenseType

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.hard_delete_rates(
            request=OptionalDimensions(
                states=[State.AA],
                zip_codes={"zip_codes"},
                license_types=[LicenseType.MD],
                facility_type_codes=[FacilityTypeCode.PHARMACY],
                network_types=[NetworkType.PPO],
                payer_plan_group_ids=[
                    uuid.UUID(
                        "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                    )
                ],
                modifiers=[ProcedureModifier.AV],
            ),
        )
        """
        _response = self._raw_client.hard_delete_rates(request=request, request_options=request_options)
        return _response.data

    def hard_delete_rates_by_ids(
        self, *, rate_ids: typing.Sequence[RateId], request_options: typing.Optional[RequestOptions] = None
    ) -> int:
        """
        Hard deletes specific rates from the system by their IDs. This is a destructive operation and cannot be undone. Limited to 100 rate IDs maximum per request. For bulk deletion of more than 100 rates, use the hard_delete_rates endpoint with dimension filters. Returns the number of rates deleted.

        Parameters
        ----------
        rate_ids : typing.Sequence[RateId]

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

        Returns
        -------
        int

        Examples
        --------
        import uuid

        from candid import CandidApiClient

        client = CandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.fee_schedules.v_3.hard_delete_rates_by_ids(
            rate_ids=[
                uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
                uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
            ],
        )
        """
        _response = self._raw_client.hard_delete_rates_by_ids(rate_ids=rate_ids, request_options=request_options)
        return _response.data


class AsyncV3Client:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawV3Client(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawV3Client:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawV3Client
        """
        return self._raw_client

    async def get_match(
        self, service_line_id: ServiceLineId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Optional[MatchResult]:
        """
        Gets the rate that matches a service line.  No result means no rate exists matching the service line's dimensions.

        Parameters
        ----------
        service_line_id : ServiceLineId

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

        Returns
        -------
        typing.Optional[MatchResult]

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.get_match(
                service_line_id=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_match(service_line_id, request_options=request_options)
        return _response.data

    async def test_match(
        self,
        service_line_id: ServiceLineId,
        rate_id: RateId,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> MatchTestResult:
        """
        Tests a service line against a rate to see if it matches.

        Parameters
        ----------
        service_line_id : ServiceLineId

        rate_id : RateId

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

        Returns
        -------
        MatchTestResult

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.test_match(
                service_line_id=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
                rate_id=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.test_match(service_line_id, rate_id, request_options=request_options)
        return _response.data

    async def get_multi(
        self,
        *,
        page_token: typing.Optional[PageToken] = None,
        limit: typing.Optional[int] = None,
        active_date: typing.Optional[dt.date] = None,
        payer_uuid: typing.Optional[PayerUuid] = None,
        organization_billing_provider_id: typing.Optional[OrganizationProviderId] = None,
        states: typing.Optional[typing.Union[State, typing.Sequence[State]]] = None,
        zip_codes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        license_types: typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]] = None,
        facility_type_codes: typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]] = None,
        network_types: typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]] = None,
        payer_plan_group_ids: typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]] = None,
        cpt_code: typing.Optional[str] = None,
        modifiers: typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RatesPage:
        """
        Gets a list of dimensions with their rates. The rates returned will always be the most recent versions of those rates.

        Parameters
        ----------
        page_token : typing.Optional[PageToken]

        limit : typing.Optional[int]
            Max number of dimensions returned. Defaults to 100. Max is 100.

        active_date : typing.Optional[dt.date]

        payer_uuid : typing.Optional[PayerUuid]

        organization_billing_provider_id : typing.Optional[OrganizationProviderId]

        states : typing.Optional[typing.Union[State, typing.Sequence[State]]]

        zip_codes : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        license_types : typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]]

        facility_type_codes : typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]]

        network_types : typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]]

        payer_plan_group_ids : typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]]

        cpt_code : typing.Optional[str]

        modifiers : typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]]

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

        Returns
        -------
        RatesPage

        Examples
        --------
        import asyncio

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.get_multi()


        asyncio.run(main())
        """
        _response = await self._raw_client.get_multi(
            page_token=page_token,
            limit=limit,
            active_date=active_date,
            payer_uuid=payer_uuid,
            organization_billing_provider_id=organization_billing_provider_id,
            states=states,
            zip_codes=zip_codes,
            license_types=license_types,
            facility_type_codes=facility_type_codes,
            network_types=network_types,
            payer_plan_group_ids=payer_plan_group_ids,
            cpt_code=cpt_code,
            modifiers=modifiers,
            request_options=request_options,
        )
        return _response.data

    async def get_unique_values_for_dimension(
        self,
        *,
        pivot_dimension: DimensionName,
        page_token: typing.Optional[PageToken] = None,
        limit: typing.Optional[int] = None,
        payer_uuid: typing.Optional[PayerUuid] = None,
        organization_billing_provider_id: typing.Optional[OrganizationProviderId] = None,
        states: typing.Optional[typing.Union[State, typing.Sequence[State]]] = None,
        zip_codes: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        license_types: typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]] = None,
        facility_type_codes: typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]] = None,
        network_types: typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]] = None,
        payer_plan_group_ids: typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]] = None,
        cpt_code: typing.Optional[str] = None,
        modifiers: typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> DimensionsPage:
        """
        Gets unique values for a dimension based on other selection criteria. The response is a list of dimensions with your criteria and the unique values populated. This API is useful for driving pivots on dimension values.

        Parameters
        ----------
        pivot_dimension : DimensionName
            The name of the dimension to fetch unique values for.

        page_token : typing.Optional[PageToken]

        limit : typing.Optional[int]
            Max number of values returned. Defaults to 1000. Max is 1000.

        payer_uuid : typing.Optional[PayerUuid]

        organization_billing_provider_id : typing.Optional[OrganizationProviderId]

        states : typing.Optional[typing.Union[State, typing.Sequence[State]]]

        zip_codes : typing.Optional[typing.Union[str, typing.Sequence[str]]]

        license_types : typing.Optional[typing.Union[LicenseType, typing.Sequence[LicenseType]]]

        facility_type_codes : typing.Optional[typing.Union[FacilityTypeCode, typing.Sequence[FacilityTypeCode]]]

        network_types : typing.Optional[typing.Union[NetworkType, typing.Sequence[NetworkType]]]

        payer_plan_group_ids : typing.Optional[typing.Union[PayerPlanGroupId, typing.Sequence[PayerPlanGroupId]]]

        cpt_code : typing.Optional[str]

        modifiers : typing.Optional[typing.Union[ProcedureModifier, typing.Sequence[ProcedureModifier]]]

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

        Returns
        -------
        DimensionsPage

        Examples
        --------
        import asyncio

        from candid import AsyncCandidApiClient
        from candid.resources.fee_schedules.resources.v_3 import DimensionName

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.get_unique_values_for_dimension(
                pivot_dimension=DimensionName.PAYER_UUID,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_unique_values_for_dimension(
            pivot_dimension=pivot_dimension,
            page_token=page_token,
            limit=limit,
            payer_uuid=payer_uuid,
            organization_billing_provider_id=organization_billing_provider_id,
            states=states,
            zip_codes=zip_codes,
            license_types=license_types,
            facility_type_codes=facility_type_codes,
            network_types=network_types,
            payer_plan_group_ids=payer_plan_group_ids,
            cpt_code=cpt_code,
            modifiers=modifiers,
            request_options=request_options,
        )
        return _response.data

    async def get_rate_history(
        self, rate_id: RateId, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.List[Rate]:
        """
        Gets every version of a rate.

        Parameters
        ----------
        rate_id : RateId

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

        Returns
        -------
        typing.List[Rate]

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.get_rate_history(
                rate_id=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_rate_history(rate_id, request_options=request_options)
        return _response.data

    async def upload_fee_schedule(
        self,
        *,
        dry_run: bool,
        rates: typing.Sequence[RateUpload],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[Rate]:
        """
        Uploads a new fee schedule.

        Each rate may either be totally new as qualified by it's dimensions or a new version for an existing rate.

        If adding a new version to an existing rate, the rate must be posted with the next version number (previous version + 1) or a EntityConflictError will
        be returned.

        Use the dry run flag to discover already existing rates and to run validations.  If validations for any rate fail, no rates will
        be saved to the system.

        Parameters
        ----------
        dry_run : bool

        rates : typing.Sequence[RateUpload]

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

        Returns
        -------
        typing.List[Rate]

        Examples
        --------
        import asyncio
        import datetime
        import uuid

        from candid import AsyncCandidApiClient
        from candid.resources.commons import (
            FacilityTypeCode,
            NetworkType,
            ProcedureModifier,
            State,
        )
        from candid.resources.fee_schedules.resources.v_3 import (
            Dimensions,
            RateEntry,
            RateUpload_NewRate,
        )
        from candid.resources.organization_providers.resources.v_2 import LicenseType

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.upload_fee_schedule(
                dry_run=True,
                rates=[
                    RateUpload_NewRate(
                        dimensions=Dimensions(
                            payer_uuid=uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            ),
                            organization_billing_provider_id=uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            ),
                            states=[State.AA],
                            zip_codes={"zip_codes"},
                            license_types=[LicenseType.MD],
                            facility_type_codes=[FacilityTypeCode.PHARMACY],
                            network_types=[NetworkType.PPO],
                            payer_plan_group_ids=[
                                uuid.UUID(
                                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                                )
                            ],
                            cpt_code="cpt_code",
                            modifiers=[ProcedureModifier.AV],
                        ),
                        entries=[
                            RateEntry(
                                start_date=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                rate_cents=1,
                                is_deactivated=True,
                            ),
                            RateEntry(
                                start_date=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                rate_cents=1,
                                is_deactivated=True,
                            ),
                        ],
                    ),
                    RateUpload_NewRate(
                        dimensions=Dimensions(
                            payer_uuid=uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            ),
                            organization_billing_provider_id=uuid.UUID(
                                "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                            ),
                            states=[State.AA],
                            zip_codes={"zip_codes"},
                            license_types=[LicenseType.MD],
                            facility_type_codes=[FacilityTypeCode.PHARMACY],
                            network_types=[NetworkType.PPO],
                            payer_plan_group_ids=[
                                uuid.UUID(
                                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                                )
                            ],
                            cpt_code="cpt_code",
                            modifiers=[ProcedureModifier.AV],
                        ),
                        entries=[
                            RateEntry(
                                start_date=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                rate_cents=1,
                                is_deactivated=True,
                            ),
                            RateEntry(
                                start_date=datetime.date.fromisoformat(
                                    "2023-01-15",
                                ),
                                rate_cents=1,
                                is_deactivated=True,
                            ),
                        ],
                    ),
                ],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.upload_fee_schedule(
            dry_run=dry_run, rates=rates, request_options=request_options
        )
        return _response.data

    async def delete_rate(
        self, rate_id: RateId, version: int, *, request_options: typing.Optional[RequestOptions] = None
    ) -> None:
        """
        Soft deletes a rate from the system.  Only the most recent version of a rate can be deleted.

        Parameters
        ----------
        rate_id : RateId

        version : int

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

        Returns
        -------
        None

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.delete_rate(
                rate_id=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
                version=1,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete_rate(rate_id, version, request_options=request_options)
        return _response.data

    async def get_payer_thresholds_default(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> PayerThreshold:
        """
        Gets the default payer threshold

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

        Returns
        -------
        PayerThreshold

        Examples
        --------
        import asyncio

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.get_payer_thresholds_default()


        asyncio.run(main())
        """
        _response = await self._raw_client.get_payer_thresholds_default(request_options=request_options)
        return _response.data

    async def get_payer_thresholds(
        self,
        *,
        payer_uuids: typing.Union[PayerUuid, typing.Sequence[PayerUuid]],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PayerThresholdsPage:
        """
        Gets a list of payers and thresholds by their uuids

        Parameters
        ----------
        payer_uuids : typing.Union[PayerUuid, typing.Sequence[PayerUuid]]

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

        Returns
        -------
        PayerThresholdsPage

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.get_payer_thresholds(
                payer_uuids=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_payer_thresholds(
            payer_uuids=payer_uuids, request_options=request_options
        )
        return _response.data

    async def set_payer_threshold(
        self, payer_uuid: PayerUuid, *, request: PayerThreshold, request_options: typing.Optional[RequestOptions] = None
    ) -> PayerThreshold:
        """
        Sets the threshold information for a payer

        Parameters
        ----------
        payer_uuid : PayerUuid

        request : PayerThreshold

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

        Returns
        -------
        PayerThreshold

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient
        from candid.resources.fee_schedules.resources.v_3 import PayerThreshold

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.set_payer_threshold(
                payer_uuid=uuid.UUID(
                    "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                ),
                request=PayerThreshold(
                    disable_paid_incorrectly=True,
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.set_payer_threshold(
            payer_uuid, request=request, request_options=request_options
        )
        return _response.data

    async def hard_delete_rates(
        self, *, request: OptionalDimensions, request_options: typing.Optional[RequestOptions] = None
    ) -> int:
        """
        Hard deletes rates from the system that match the provided dimensions.  This is a destructive operation and cannot be undone.  If an empty dimensions object is provided, all rates will be hard deleted.  The maximum number of rates this API will delete at a time is 10000.  Returns the number of rates deleted and if that number is the maximum, the caller should call this API again to continue deleting rates.

        Parameters
        ----------
        request : OptionalDimensions

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

        Returns
        -------
        int

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient
        from candid.resources.commons import (
            FacilityTypeCode,
            NetworkType,
            ProcedureModifier,
            State,
        )
        from candid.resources.fee_schedules.resources.v_3 import OptionalDimensions
        from candid.resources.organization_providers.resources.v_2 import LicenseType

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.hard_delete_rates(
                request=OptionalDimensions(
                    states=[State.AA],
                    zip_codes={"zip_codes"},
                    license_types=[LicenseType.MD],
                    facility_type_codes=[FacilityTypeCode.PHARMACY],
                    network_types=[NetworkType.PPO],
                    payer_plan_group_ids=[
                        uuid.UUID(
                            "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                        )
                    ],
                    modifiers=[ProcedureModifier.AV],
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.hard_delete_rates(request=request, request_options=request_options)
        return _response.data

    async def hard_delete_rates_by_ids(
        self, *, rate_ids: typing.Sequence[RateId], request_options: typing.Optional[RequestOptions] = None
    ) -> int:
        """
        Hard deletes specific rates from the system by their IDs. This is a destructive operation and cannot be undone. Limited to 100 rate IDs maximum per request. For bulk deletion of more than 100 rates, use the hard_delete_rates endpoint with dimension filters. Returns the number of rates deleted.

        Parameters
        ----------
        rate_ids : typing.Sequence[RateId]

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

        Returns
        -------
        int

        Examples
        --------
        import asyncio
        import uuid

        from candid import AsyncCandidApiClient

        client = AsyncCandidApiClient(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.fee_schedules.v_3.hard_delete_rates_by_ids(
                rate_ids=[
                    uuid.UUID(
                        "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                    ),
                    uuid.UUID(
                        "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32",
                    ),
                ],
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.hard_delete_rates_by_ids(rate_ids=rate_ids, request_options=request_options)
        return _response.data
