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

from __future__ import annotations
from enum import Enum
from gusto_embedded.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import Optional
from typing_extensions import NotRequired, TypedDict


class WageType(str, Enum):
    r"""The contractor's wage type, either \"Fixed\" or \"Hourly\"."""

    FIXED = "Fixed"
    HOURLY = "Hourly"


class ContractorType(str, Enum):
    r"""The contractor's type, either \"Individual\" or \"Business\"."""

    INDIVIDUAL = "Individual"
    BUSINESS = "Business"


class AddressTypedDict(TypedDict):
    r"""The contractor’s home address."""

    street_1: NotRequired[str]
    street_2: NotRequired[Nullable[str]]
    city: NotRequired[str]
    state: NotRequired[str]
    zip: NotRequired[str]
    country: NotRequired[str]


class Address(BaseModel):
    r"""The contractor’s home address."""

    street_1: Optional[str] = None

    street_2: OptionalNullable[str] = UNSET

    city: Optional[str] = None

    state: Optional[str] = None

    zip: Optional[str] = None

    country: Optional[str] = None

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["street_1", "street_2", "city", "state", "zip", "country"]
        nullable_fields = ["street_2"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in self.model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class ContractorOnboardingStatus1(str, Enum):
    r"""One of the \"onboarding_status\" enum values."""

    ADMIN_ONBOARDING_INCOMPLETE = "admin_onboarding_incomplete"
    ADMIN_ONBOARDING_REVIEW = "admin_onboarding_review"
    SELF_ONBOARDING_NOT_INVITED = "self_onboarding_not_invited"
    SELF_ONBOARDING_INVITED = "self_onboarding_invited"
    SELF_ONBOARDING_STARTED = "self_onboarding_started"
    SELF_ONBOARDING_REVIEW = "self_onboarding_review"
    ONBOARDING_COMPLETED = "onboarding_completed"


class ContractorPaymentMethod1(str, Enum):
    r"""The contractor's payment method."""

    DIRECT_DEPOSIT = "Direct Deposit"
    CHECK = "Check"


class ContractorTypedDict(TypedDict):
    r"""The representation of a contractor (individual or business) in Gusto."""

    uuid: str
    r"""The UUID of the contractor in Gusto."""
    company_uuid: NotRequired[str]
    r"""The UUID of the company the contractor is employed by."""
    wage_type: NotRequired[WageType]
    r"""The contractor's wage type, either \"Fixed\" or \"Hourly\"."""
    is_active: NotRequired[bool]
    r"""The status of the contractor with the company."""
    version: NotRequired[str]
    r"""The current version of the object. See the [versioning guide](https://docs.gusto.com/embedded-payroll/docs/idempotency) for information on how to use this field."""
    type: NotRequired[ContractorType]
    r"""The contractor's type, either \"Individual\" or \"Business\"."""
    first_name: NotRequired[Nullable[str]]
    r"""The contractor’s first name. This attribute is required for “Individual” contractors and will be ignored for “Business” contractors."""
    last_name: NotRequired[Nullable[str]]
    r"""The contractor’s last name. This attribute is required for “Individual” contractors and will be ignored for “Business” contractors."""
    middle_initial: NotRequired[Nullable[str]]
    r"""The contractor’s middle initial. This attribute is optional for “Individual” contractors and will be ignored for “Business” contractors."""
    business_name: NotRequired[Nullable[str]]
    r"""The name of the contractor business. This attribute is required for “Business” contractors and will be ignored for “Individual” contractors."""
    ein: NotRequired[Nullable[str]]
    r"""The Federal Employer Identification Number of the contractor business. This attribute is optional for “Business” contractors and will be ignored for “Individual” contractors."""
    has_ein: NotRequired[Nullable[bool]]
    r"""Whether company's Employer Identification Number (EIN) is present"""
    email: NotRequired[Nullable[str]]
    r"""The contractor’s email address. This attribute is optional for “Individual” contractors and will be ignored for “Business” contractors."""
    start_date: NotRequired[str]
    r"""The contractor's start date."""
    address: NotRequired[Nullable[AddressTypedDict]]
    r"""The contractor’s home address."""
    hourly_rate: NotRequired[str]
    r"""The contractor’s hourly rate. This attribute is required if the wage_type is “Hourly”."""
    file_new_hire_report: NotRequired[bool]
    r"""The boolean flag indicating whether Gusto will file a new hire report for the contractor"""
    work_state: NotRequired[Nullable[str]]
    r"""State where the contractor will be conducting the majority of their work for the company.
    This value is used when generating the new hire report.
    """
    onboarded: NotRequired[bool]
    r"""The updated onboarding status for the contractor"""
    onboarding_status: NotRequired[ContractorOnboardingStatus1]
    r"""One of the \"onboarding_status\" enum values."""
    payment_method: NotRequired[Nullable[ContractorPaymentMethod1]]
    r"""The contractor's payment method."""
    has_ssn: NotRequired[bool]
    r"""Indicates whether the contractor has an SSN in Gusto."""
    department_uuid: NotRequired[Nullable[str]]
    r"""The UUID of the department the contractor is under"""


class Contractor(BaseModel):
    r"""The representation of a contractor (individual or business) in Gusto."""

    uuid: str
    r"""The UUID of the contractor in Gusto."""

    company_uuid: Optional[str] = None
    r"""The UUID of the company the contractor is employed by."""

    wage_type: Optional[WageType] = None
    r"""The contractor's wage type, either \"Fixed\" or \"Hourly\"."""

    is_active: Optional[bool] = True
    r"""The status of the contractor with the company."""

    version: Optional[str] = None
    r"""The current version of the object. See the [versioning guide](https://docs.gusto.com/embedded-payroll/docs/idempotency) for information on how to use this field."""

    type: Optional[ContractorType] = None
    r"""The contractor's type, either \"Individual\" or \"Business\"."""

    first_name: OptionalNullable[str] = UNSET
    r"""The contractor’s first name. This attribute is required for “Individual” contractors and will be ignored for “Business” contractors."""

    last_name: OptionalNullable[str] = UNSET
    r"""The contractor’s last name. This attribute is required for “Individual” contractors and will be ignored for “Business” contractors."""

    middle_initial: OptionalNullable[str] = UNSET
    r"""The contractor’s middle initial. This attribute is optional for “Individual” contractors and will be ignored for “Business” contractors."""

    business_name: OptionalNullable[str] = UNSET
    r"""The name of the contractor business. This attribute is required for “Business” contractors and will be ignored for “Individual” contractors."""

    ein: OptionalNullable[str] = UNSET
    r"""The Federal Employer Identification Number of the contractor business. This attribute is optional for “Business” contractors and will be ignored for “Individual” contractors."""

    has_ein: OptionalNullable[bool] = UNSET
    r"""Whether company's Employer Identification Number (EIN) is present"""

    email: OptionalNullable[str] = UNSET
    r"""The contractor’s email address. This attribute is optional for “Individual” contractors and will be ignored for “Business” contractors."""

    start_date: Optional[str] = None
    r"""The contractor's start date."""

    address: OptionalNullable[Address] = UNSET
    r"""The contractor’s home address."""

    hourly_rate: Optional[str] = None
    r"""The contractor’s hourly rate. This attribute is required if the wage_type is “Hourly”."""

    file_new_hire_report: Optional[bool] = False
    r"""The boolean flag indicating whether Gusto will file a new hire report for the contractor"""

    work_state: OptionalNullable[str] = UNSET
    r"""State where the contractor will be conducting the majority of their work for the company.
    This value is used when generating the new hire report.
    """

    onboarded: Optional[bool] = None
    r"""The updated onboarding status for the contractor"""

    onboarding_status: Optional[ContractorOnboardingStatus1] = None
    r"""One of the \"onboarding_status\" enum values."""

    payment_method: OptionalNullable[ContractorPaymentMethod1] = UNSET
    r"""The contractor's payment method."""

    has_ssn: Optional[bool] = None
    r"""Indicates whether the contractor has an SSN in Gusto."""

    department_uuid: OptionalNullable[str] = UNSET
    r"""The UUID of the department the contractor is under"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "company_uuid",
            "wage_type",
            "is_active",
            "version",
            "type",
            "first_name",
            "last_name",
            "middle_initial",
            "business_name",
            "ein",
            "has_ein",
            "email",
            "start_date",
            "address",
            "hourly_rate",
            "file_new_hire_report",
            "work_state",
            "onboarded",
            "onboarding_status",
            "payment_method",
            "has_ssn",
            "department_uuid",
        ]
        nullable_fields = [
            "first_name",
            "last_name",
            "middle_initial",
            "business_name",
            "ein",
            "has_ein",
            "email",
            "address",
            "work_state",
            "payment_method",
            "department_uuid",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in self.model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
