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

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


class EntityType(str, Enum):
    r"""The tax payer type of the company."""

    C_CORPORATION = "C-Corporation"
    S_CORPORATION = "S-Corporation"
    SOLE_PROPRIETOR = "Sole proprietor"
    LLC = "LLC"
    LLP = "LLP"
    LIMITED_PARTNERSHIP = "Limited partnership"
    CO_OWNERSHIP = "Co-ownership"
    ASSOCIATION = "Association"
    TRUSTEESHIP = "Trusteeship"
    GENERAL_PARTNERSHIP = "General partnership"
    JOINT_VENTURE = "Joint venture"
    NON_PROFIT = "Non-Profit"


class Tier(str, Enum):
    r"""The Gusto product tier of the company (not applicable to Embedded partner managed companies)."""

    SIMPLE = "simple"
    PLUS = "plus"
    PREMIUM = "premium"
    CORE = "core"
    COMPLETE = "complete"
    CONCIERGE = "concierge"
    CONTRACTOR_ONLY = "contractor_only"
    BASIC = "basic"


class CompanyStatus(str, Enum):
    r"""The status of the company in Gusto. \"Approved\" companies are approved to run payroll from a risk and compliance perspective. However, an approved company may still need to resolve other [payroll blockers](https://docs.gusto.com/embedded-payroll/docs/payroll-blockers) to be able to run payroll. \"Not Approved\" companies may not yet run payroll with Gusto and may need to complete onboarding or contact support. \"Suspended\" companies may not run payroll with Gusto. In order to unsuspend their account, the company must contact support."""

    APPROVED = "Approved"
    NOT_APPROVED = "Not Approved"
    SUSPENDED = "Suspended"


class PayScheduleType(str, Enum):
    r"""The pay schedule assignment type."""

    SINGLE = "single"
    HOURLY_SALARIED = "hourly_salaried"
    BY_EMPLOYEE = "by_employee"
    BY_DEPARTMENT = "by_department"


class FundingType(str, Enum):
    r"""Company's default funding type"""

    ACH = "ach"
    REVERSE_WIRE = "reverse_wire"
    WIRE_IN = "wire_in"
    BREX = "brex"


class HourlyTypedDict(TypedDict):
    name: NotRequired[str]
    r"""The name of the hourly compensation rate."""
    multiple: NotRequired[float]
    r"""The amount multiplied by the base rate of a job to calculate compensation."""


class Hourly(BaseModel):
    name: Optional[str] = None
    r"""The name of the hourly compensation rate."""

    multiple: Optional[float] = None
    r"""The amount multiplied by the base rate of a job to calculate compensation."""


class FixedTypedDict(TypedDict):
    name: NotRequired[str]
    r"""The name of the fixed compensation."""


class Fixed(BaseModel):
    name: Optional[str] = None
    r"""The name of the fixed compensation."""


class CompanyPaidTimeOffTypedDict(TypedDict):
    name: NotRequired[str]
    r"""The name of the paid time off type."""


class CompanyPaidTimeOff(BaseModel):
    name: Optional[str] = None
    r"""The name of the paid time off type."""


class CompensationsTypedDict(TypedDict):
    r"""The available company-wide compensation rates for the company."""

    hourly: NotRequired[List[HourlyTypedDict]]
    r"""The available hourly compensation rates for the company."""
    fixed: NotRequired[List[FixedTypedDict]]
    r"""The available fixed compensation rates for the company."""
    paid_time_off: NotRequired[List[CompanyPaidTimeOffTypedDict]]
    r"""The available types of paid time off for the company."""


class Compensations(BaseModel):
    r"""The available company-wide compensation rates for the company."""

    hourly: Optional[List[Hourly]] = None
    r"""The available hourly compensation rates for the company."""

    fixed: Optional[List[Fixed]] = None
    r"""The available fixed compensation rates for the company."""

    paid_time_off: Optional[List[CompanyPaidTimeOff]] = None
    r"""The available types of paid time off for the company."""


class CompanyHomeAddressTypedDict(TypedDict):
    r"""The company's primary signatory'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 CompanyHomeAddress(BaseModel):
    r"""The company's primary signatory'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 PrimarySignatoryTypedDict(TypedDict):
    r"""The primary signatory of the company."""

    uuid: NotRequired[str]
    r"""The UUID of the company's primary signatory."""
    first_name: NotRequired[str]
    r"""The company's primary signatory's first name."""
    middle_initial: NotRequired[str]
    r"""The company's primary signatory's middle initial."""
    last_name: NotRequired[str]
    r"""The company's primary signatory's last name."""
    phone: NotRequired[str]
    r"""The company's primary signatory's phone number."""
    email: NotRequired[str]
    r"""The company's primary signatory's email address."""
    home_address: NotRequired[CompanyHomeAddressTypedDict]
    r"""The company's primary signatory's home address."""


class PrimarySignatory(BaseModel):
    r"""The primary signatory of the company."""

    uuid: Optional[str] = None
    r"""The UUID of the company's primary signatory."""

    first_name: Optional[str] = None
    r"""The company's primary signatory's first name."""

    middle_initial: Optional[str] = None
    r"""The company's primary signatory's middle initial."""

    last_name: Optional[str] = None
    r"""The company's primary signatory's last name."""

    phone: Optional[str] = None
    r"""The company's primary signatory's phone number."""

    email: Optional[str] = None
    r"""The company's primary signatory's email address."""

    home_address: Optional[CompanyHomeAddress] = None
    r"""The company's primary signatory's home address."""


class PrimaryPayrollAdminTypedDict(TypedDict):
    r"""The primary payroll admin of the company."""

    first_name: NotRequired[str]
    r"""The company's primary payroll admin's first name."""
    last_name: NotRequired[str]
    r"""The company's primary payroll admin's last name."""
    phone: NotRequired[Nullable[str]]
    r"""The company's primary payroll admin's phone number."""
    email: NotRequired[str]
    r"""The company's primary payroll admin's email address."""


class PrimaryPayrollAdmin(BaseModel):
    r"""The primary payroll admin of the company."""

    first_name: Optional[str] = None
    r"""The company's primary payroll admin's first name."""

    last_name: Optional[str] = None
    r"""The company's primary payroll admin's last name."""

    phone: OptionalNullable[str] = UNSET
    r"""The company's primary payroll admin's phone number."""

    email: Optional[str] = None
    r"""The company's primary payroll admin's email address."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["first_name", "last_name", "phone", "email"]
        nullable_fields = ["phone"]
        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 CompanyTypedDict(TypedDict):
    r"""The representation of a company in Gusto."""

    uuid: str
    r"""A unique identifier of the company in Gusto."""
    ein: NotRequired[str]
    r"""The Federal Employer Identification Number of the company."""
    entity_type: NotRequired[Nullable[EntityType]]
    r"""The tax payer type of the company."""
    contractor_only: NotRequired[bool]
    r"""Whether the company only supports contractors."""
    tier: NotRequired[Nullable[Tier]]
    r"""The Gusto product tier of the company (not applicable to Embedded partner managed companies)."""
    is_suspended: NotRequired[bool]
    r"""Whether or not the company is suspended in Gusto. Suspended companies may not run payroll."""
    company_status: NotRequired[CompanyStatus]
    r"""The status of the company in Gusto. \"Approved\" companies are approved to run payroll from a risk and compliance perspective. However, an approved company may still need to resolve other [payroll blockers](https://docs.gusto.com/embedded-payroll/docs/payroll-blockers) to be able to run payroll. \"Not Approved\" companies may not yet run payroll with Gusto and may need to complete onboarding or contact support. \"Suspended\" companies may not run payroll with Gusto. In order to unsuspend their account, the company must contact support."""
    name: NotRequired[str]
    r"""The name of the company."""
    slug: NotRequired[str]
    r"""The slug of the name of the company."""
    trade_name: NotRequired[Nullable[str]]
    r"""The trade name of the company."""
    is_partner_managed: NotRequired[bool]
    r"""Whether the company is fully managed by a partner via the API"""
    pay_schedule_type: NotRequired[Nullable[PayScheduleType]]
    r"""The pay schedule assignment type."""
    join_date: NotRequired[Nullable[str]]
    r"""Company's first invoiceable event date"""
    funding_type: NotRequired[Nullable[FundingType]]
    r"""Company's default funding type"""
    locations: NotRequired[List[CompanyAddressTypedDict]]
    r"""The locations of the company."""
    compensations: NotRequired[CompensationsTypedDict]
    r"""The available company-wide compensation rates for the company."""
    primary_signatory: NotRequired[Nullable[PrimarySignatoryTypedDict]]
    r"""The primary signatory of the company."""
    primary_payroll_admin: NotRequired[PrimaryPayrollAdminTypedDict]
    r"""The primary payroll admin of the company."""


class Company(BaseModel):
    r"""The representation of a company in Gusto."""

    uuid: str
    r"""A unique identifier of the company in Gusto."""

    ein: Optional[str] = None
    r"""The Federal Employer Identification Number of the company."""

    entity_type: OptionalNullable[EntityType] = UNSET
    r"""The tax payer type of the company."""

    contractor_only: Optional[bool] = None
    r"""Whether the company only supports contractors."""

    tier: OptionalNullable[Tier] = UNSET
    r"""The Gusto product tier of the company (not applicable to Embedded partner managed companies)."""

    is_suspended: Optional[bool] = None
    r"""Whether or not the company is suspended in Gusto. Suspended companies may not run payroll."""

    company_status: Optional[CompanyStatus] = None
    r"""The status of the company in Gusto. \"Approved\" companies are approved to run payroll from a risk and compliance perspective. However, an approved company may still need to resolve other [payroll blockers](https://docs.gusto.com/embedded-payroll/docs/payroll-blockers) to be able to run payroll. \"Not Approved\" companies may not yet run payroll with Gusto and may need to complete onboarding or contact support. \"Suspended\" companies may not run payroll with Gusto. In order to unsuspend their account, the company must contact support."""

    name: Optional[str] = None
    r"""The name of the company."""

    slug: Optional[str] = None
    r"""The slug of the name of the company."""

    trade_name: OptionalNullable[str] = UNSET
    r"""The trade name of the company."""

    is_partner_managed: Optional[bool] = None
    r"""Whether the company is fully managed by a partner via the API"""

    pay_schedule_type: OptionalNullable[PayScheduleType] = UNSET
    r"""The pay schedule assignment type."""

    join_date: OptionalNullable[str] = UNSET
    r"""Company's first invoiceable event date"""

    funding_type: OptionalNullable[FundingType] = UNSET
    r"""Company's default funding type"""

    locations: Optional[List[CompanyAddress]] = None
    r"""The locations of the company."""

    compensations: Optional[Compensations] = None
    r"""The available company-wide compensation rates for the company."""

    primary_signatory: OptionalNullable[PrimarySignatory] = UNSET
    r"""The primary signatory of the company."""

    primary_payroll_admin: Optional[PrimaryPayrollAdmin] = None
    r"""The primary payroll admin of the company."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "ein",
            "entity_type",
            "contractor_only",
            "tier",
            "is_suspended",
            "company_status",
            "name",
            "slug",
            "trade_name",
            "is_partner_managed",
            "pay_schedule_type",
            "join_date",
            "funding_type",
            "locations",
            "compensations",
            "primary_signatory",
            "primary_payroll_admin",
        ]
        nullable_fields = [
            "entity_type",
            "tier",
            "trade_name",
            "pay_schedule_type",
            "join_date",
            "funding_type",
            "primary_signatory",
        ]
        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
