"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from __future__ import annotations
from datetime import datetime
from kombo.types import BaseModel, Nullable, UNSET_SENTINEL
from kombo.utils import validate_const
import pydantic
from pydantic import Field, model_serializer
from pydantic.functional_validators import AfterValidator
from typing import Literal, Optional, Union
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict


class PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndCandidateRemoteIdsTypedDict(
    TypedDict
):
    candidate_remote_id: str
    application_remote_id: str
    id_type: Literal["application_and_candidate_remote_ids"]
    r"""Uses the `Api/Applications/{applicantId}` endpoint to retrieve the relevant application based on the candidate ID."""


class PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndCandidateRemoteIds(
    BaseModel
):
    candidate_remote_id: str

    application_remote_id: str

    ID_TYPE: Annotated[
        Annotated[
            Literal["application_and_candidate_remote_ids"],
            AfterValidator(validate_const("application_and_candidate_remote_ids")),
        ],
        pydantic.Field(alias="id_type"),
    ] = "application_and_candidate_remote_ids"
    r"""Uses the `Api/Applications/{applicantId}` endpoint to retrieve the relevant application based on the candidate ID."""


class PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndJobRemoteIdsTypedDict(
    TypedDict
):
    application_remote_id: str
    job_remote_id: str
    id_type: Literal["application_and_job_remote_ids"]
    r"""Uses the `Api/Applications/ByJob/{jobId}` endpoint to retrieve the relevant application based on the job ID."""


class PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndJobRemoteIds(
    BaseModel
):
    application_remote_id: str

    job_remote_id: str

    ID_TYPE: Annotated[
        Annotated[
            Literal["application_and_job_remote_ids"],
            AfterValidator(validate_const("application_and_job_remote_ids")),
        ],
        pydantic.Field(alias="id_type"),
    ] = "application_and_job_remote_ids"
    r"""Uses the `Api/Applications/ByJob/{jobId}` endpoint to retrieve the relevant application based on the job ID."""


PostAtsImportTrackedApplicationRequestBodyErecruiterUnionTypedDict = TypeAliasType(
    "PostAtsImportTrackedApplicationRequestBodyErecruiterUnionTypedDict",
    Union[
        PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndJobRemoteIdsTypedDict,
        PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndCandidateRemoteIdsTypedDict,
    ],
)


PostAtsImportTrackedApplicationRequestBodyErecruiterUnion = Annotated[
    Union[
        PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndJobRemoteIds,
        PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndCandidateRemoteIds,
    ],
    Field(discriminator="ID_TYPE"),
]


class PostAtsImportTrackedApplicationRequestBodySuccessfactorsApplicationRemoteIDTypedDict(
    TypedDict
):
    application_remote_id: str
    id_type: Literal["application_remote_id"]
    r"""Uses the `/JobApplication` ODATA endpoint to retrieve the relevant application based on the application ID."""


class PostAtsImportTrackedApplicationRequestBodySuccessfactorsApplicationRemoteID(
    BaseModel
):
    application_remote_id: str

    ID_TYPE: Annotated[
        Annotated[
            Literal["application_remote_id"],
            AfterValidator(validate_const("application_remote_id")),
        ],
        pydantic.Field(alias="id_type"),
    ] = "application_remote_id"
    r"""Uses the `/JobApplication` ODATA endpoint to retrieve the relevant application based on the application ID."""


PostAtsImportTrackedApplicationRequestBodySuccessfactorsUnionTypedDict = (
    PostAtsImportTrackedApplicationRequestBodySuccessfactorsApplicationRemoteIDTypedDict
)


PostAtsImportTrackedApplicationRequestBodySuccessfactorsUnion = (
    PostAtsImportTrackedApplicationRequestBodySuccessfactorsApplicationRemoteID
)


class PostAtsImportTrackedApplicationRequestBodyRecruiteePlacementIDTypedDict(
    TypedDict
):
    placement_id: str
    id_type: Literal["placement_id"]
    r"""Uses the `/candidates` endpoint to retrieve all candidates, to find the relevant application based on the placement ID."""


class PostAtsImportTrackedApplicationRequestBodyRecruiteePlacementID(BaseModel):
    placement_id: str

    ID_TYPE: Annotated[
        Annotated[
            Literal["placement_id"], AfterValidator(validate_const("placement_id"))
        ],
        pydantic.Field(alias="id_type"),
    ] = "placement_id"
    r"""Uses the `/candidates` endpoint to retrieve all candidates, to find the relevant application based on the placement ID."""


PostAtsImportTrackedApplicationRequestBodyRecruiteeUnionTypedDict = (
    PostAtsImportTrackedApplicationRequestBodyRecruiteePlacementIDTypedDict
)


PostAtsImportTrackedApplicationRequestBodyRecruiteeUnion = (
    PostAtsImportTrackedApplicationRequestBodyRecruiteePlacementID
)


class PostAtsImportTrackedApplicationRequestBodyGreenhouseApplicationIDTypedDict(
    TypedDict
):
    application_id: str
    id_type: Literal["application_id"]
    r"""Uses the `/applications/{id}` endpoint to retrieve the application."""


class PostAtsImportTrackedApplicationRequestBodyGreenhouseApplicationID(BaseModel):
    application_id: str

    ID_TYPE: Annotated[
        Annotated[
            Literal["application_id"], AfterValidator(validate_const("application_id"))
        ],
        pydantic.Field(alias="id_type"),
    ] = "application_id"
    r"""Uses the `/applications/{id}` endpoint to retrieve the application."""


class PostAtsImportTrackedApplicationRequestBodyOnlyfyApplicationIDTypedDict(TypedDict):
    application_id: str
    id_type: Literal["application_id"]
    r"""Uses the `/v1/application/{id}` endpoint to retrieve the application."""


class PostAtsImportTrackedApplicationRequestBodyOnlyfyApplicationID(BaseModel):
    application_id: str

    ID_TYPE: Annotated[
        Annotated[
            Literal["application_id"], AfterValidator(validate_const("application_id"))
        ],
        pydantic.Field(alias="id_type"),
    ] = "application_id"
    r"""Uses the `/v1/application/{id}` endpoint to retrieve the application."""


PostAtsImportTrackedApplicationRequestBodyGreenhouseUnionTypedDict = (
    PostAtsImportTrackedApplicationRequestBodyGreenhouseApplicationIDTypedDict
)


PostAtsImportTrackedApplicationRequestBodyGreenhouseUnion = (
    PostAtsImportTrackedApplicationRequestBodyGreenhouseApplicationID
)


PostAtsImportTrackedApplicationRequestBodyOnlyfyUnionTypedDict = (
    PostAtsImportTrackedApplicationRequestBodyOnlyfyApplicationIDTypedDict
)


PostAtsImportTrackedApplicationRequestBodyOnlyfyUnion = (
    PostAtsImportTrackedApplicationRequestBodyOnlyfyApplicationID
)


class PostAtsImportTrackedApplicationRequestBodySmartrecruitersCandidateAndJobRemoteIdsTypedDict(
    TypedDict
):
    candidate_remote_id: str
    job_remote_id: str
    id_type: Literal["candidate_and_job_remote_ids"]
    r"""Uses the `/candidates/{candidateId}/jobs/{jobId}` endpoint to retrieve the application."""


class PostAtsImportTrackedApplicationRequestBodySmartrecruitersCandidateAndJobRemoteIds(
    BaseModel
):
    candidate_remote_id: str

    job_remote_id: str

    ID_TYPE: Annotated[
        Annotated[
            Literal["candidate_and_job_remote_ids"],
            AfterValidator(validate_const("candidate_and_job_remote_ids")),
        ],
        pydantic.Field(alias="id_type"),
    ] = "candidate_and_job_remote_ids"
    r"""Uses the `/candidates/{candidateId}/jobs/{jobId}` endpoint to retrieve the application."""


PostAtsImportTrackedApplicationRequestBodySmartrecruitersUnionTypedDict = PostAtsImportTrackedApplicationRequestBodySmartrecruitersCandidateAndJobRemoteIdsTypedDict


PostAtsImportTrackedApplicationRequestBodySmartrecruitersUnion = (
    PostAtsImportTrackedApplicationRequestBodySmartrecruitersCandidateAndJobRemoteIds
)


class PostAtsImportTrackedApplicationRequestBodyTypedDict(TypedDict):
    tracked_at: Nullable[datetime]
    r"""YYYY-MM-DDTHH:mm:ss.sssZ
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
    """
    erecruiter: NotRequired[
        PostAtsImportTrackedApplicationRequestBodyErecruiterUnionTypedDict
    ]
    successfactors: NotRequired[
        PostAtsImportTrackedApplicationRequestBodySuccessfactorsUnionTypedDict
    ]
    recruitee: NotRequired[
        PostAtsImportTrackedApplicationRequestBodyRecruiteeUnionTypedDict
    ]
    greenhouse: NotRequired[
        PostAtsImportTrackedApplicationRequestBodyGreenhouseUnionTypedDict
    ]
    onlyfy: NotRequired[PostAtsImportTrackedApplicationRequestBodyOnlyfyUnionTypedDict]
    smartrecruiters: NotRequired[
        PostAtsImportTrackedApplicationRequestBodySmartrecruitersUnionTypedDict
    ]


class PostAtsImportTrackedApplicationRequestBody(BaseModel):
    tracked_at: Nullable[datetime]
    r"""YYYY-MM-DDTHH:mm:ss.sssZ
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
    """

    erecruiter: Optional[PostAtsImportTrackedApplicationRequestBodyErecruiterUnion] = (
        None
    )

    successfactors: Optional[
        PostAtsImportTrackedApplicationRequestBodySuccessfactorsUnion
    ] = None

    recruitee: Optional[PostAtsImportTrackedApplicationRequestBodyRecruiteeUnion] = None

    greenhouse: Optional[PostAtsImportTrackedApplicationRequestBodyGreenhouseUnion] = (
        None
    )

    onlyfy: Optional[PostAtsImportTrackedApplicationRequestBodyOnlyfyUnion] = None

    smartrecruiters: Optional[
        PostAtsImportTrackedApplicationRequestBodySmartrecruitersUnion
    ] = None

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = set(
            [
                "erecruiter",
                "successfactors",
                "recruitee",
                "greenhouse",
                "onlyfy",
                "smartrecruiters",
            ]
        )
        nullable_fields = set(["tracked_at"])
        serialized = handler(self)
        m = {}

        for n, f in type(self).model_fields.items():
            k = f.alias or n
            val = serialized.get(k, serialized.get(n))
            is_nullable_and_explicitly_set = (
                k in nullable_fields
                and (self.__pydantic_fields_set__.intersection({n}))  # pylint: disable=no-member
            )

            if val != UNSET_SENTINEL:
                if (
                    val is not None
                    or k not in optional_fields
                    or is_nullable_and_explicitly_set
                ):
                    m[k] = val

        return m


try:
    PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndCandidateRemoteIds.model_rebuild()
except NameError:
    pass
try:
    PostAtsImportTrackedApplicationRequestBodyErecruiterApplicationAndJobRemoteIds.model_rebuild()
except NameError:
    pass
try:
    PostAtsImportTrackedApplicationRequestBodySuccessfactorsApplicationRemoteID.model_rebuild()
except NameError:
    pass
try:
    PostAtsImportTrackedApplicationRequestBodyRecruiteePlacementID.model_rebuild()
except NameError:
    pass
try:
    PostAtsImportTrackedApplicationRequestBodyGreenhouseApplicationID.model_rebuild()
except NameError:
    pass
try:
    PostAtsImportTrackedApplicationRequestBodyOnlyfyApplicationID.model_rebuild()
except NameError:
    pass
try:
    PostAtsImportTrackedApplicationRequestBodySmartrecruitersCandidateAndJobRemoteIds.model_rebuild()
except NameError:
    pass
