"""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 List, Optional
from typing_extensions import NotRequired, TypedDict


class PayrollEmployeeCompensationsTypePaymentMethod(str, Enum):
    r"""The employee's compensation payment method."""

    CHECK = "Check"
    DIRECT_DEPOSIT = "Direct Deposit"


class FixedCompensationsTypedDict(TypedDict):
    name: NotRequired[str]
    r"""The name of the compensation. This also serves as the unique, immutable identifier for this compensation."""
    amount: NotRequired[str]
    r"""The amount of the compensation for the pay period."""
    job_uuid: NotRequired[str]
    r"""The UUID of the job for the compensation."""


class FixedCompensations(BaseModel):
    name: Optional[str] = None
    r"""The name of the compensation. This also serves as the unique, immutable identifier for this compensation."""

    amount: Optional[str] = None
    r"""The amount of the compensation for the pay period."""

    job_uuid: Optional[str] = None
    r"""The UUID of the job for the compensation."""


class HourlyCompensationsTypedDict(TypedDict):
    name: NotRequired[str]
    r"""The name of the compensation. This also serves as the unique, immutable identifier for this compensation."""
    hours: NotRequired[str]
    r"""The number of hours to be compensated for this pay period."""
    amount: NotRequired[str]
    r"""The amount of the compensation. This field is only available after the payroll is calculated and cannot be used for updating hourly compensations."""
    job_uuid: NotRequired[str]
    r"""The UUID of the job for the compensation."""
    compensation_multiplier: NotRequired[float]
    r"""The amount multiplied by the base rate to calculate total compensation per hour worked."""
    flsa_status: NotRequired[str]
    r"""The FLSA Status of the employee's primary job compensation"""


class HourlyCompensations(BaseModel):
    name: Optional[str] = None
    r"""The name of the compensation. This also serves as the unique, immutable identifier for this compensation."""

    hours: Optional[str] = None
    r"""The number of hours to be compensated for this pay period."""

    amount: Optional[str] = None
    r"""The amount of the compensation. This field is only available after the payroll is calculated and cannot be used for updating hourly compensations."""

    job_uuid: Optional[str] = None
    r"""The UUID of the job for the compensation."""

    compensation_multiplier: Optional[float] = None
    r"""The amount multiplied by the base rate to calculate total compensation per hour worked."""

    flsa_status: Optional[str] = None
    r"""The FLSA Status of the employee's primary job compensation"""


class PayrollEmployeeCompensationsTypePaidTimeOffTypedDict(TypedDict):
    name: NotRequired[str]
    r"""The name of the PTO. This also serves as the unique, immutable identifier for the PTO."""
    hours: NotRequired[str]
    r"""The hours of this PTO taken during the pay period."""
    final_payout_unused_hours_input: NotRequired[str]
    r"""The outstanding hours paid upon termination. This field is only applicable for termination payrolls."""


class PayrollEmployeeCompensationsTypePaidTimeOff(BaseModel):
    name: Optional[str] = None
    r"""The name of the PTO. This also serves as the unique, immutable identifier for the PTO."""

    hours: Optional[str] = None
    r"""The hours of this PTO taken during the pay period."""

    final_payout_unused_hours_input: Optional[str] = None
    r"""The outstanding hours paid upon termination. This field is only applicable for termination payrolls."""


class BenefitsTypedDict(TypedDict):
    name: NotRequired[str]
    employee_deduction: NotRequired[float]
    company_contribution: NotRequired[float]
    imputed: NotRequired[bool]


class Benefits(BaseModel):
    name: Optional[str] = None

    employee_deduction: Optional[float] = None

    company_contribution: Optional[float] = None

    imputed: Optional[bool] = None


class DeductionsTypedDict(TypedDict):
    name: NotRequired[str]
    amount: NotRequired[float]


class Deductions(BaseModel):
    name: Optional[str] = None

    amount: Optional[float] = None


class TaxesTypedDict(TypedDict):
    name: str
    employer: bool
    amount: float


class Taxes(BaseModel):
    name: str

    employer: bool

    amount: float


class PayrollEmployeeCompensationsTypeTypedDict(TypedDict):
    employee_uuid: NotRequired[str]
    r"""The UUID of the employee."""
    excluded: NotRequired[bool]
    r"""This employee will be excluded (skipped) from payroll calculation and will not be paid for the payroll. Cancelling a payroll would reset all employees' excluded back to false."""
    version: NotRequired[str]
    r"""The current version of this employee compensation. This field is only available for prepared payrolls. See the [versioning guide](https://docs.gusto.com/embedded-payroll/docs/idempotency) for information on how to use this field."""
    gross_pay: NotRequired[Nullable[float]]
    r"""The employee's gross pay, equal to regular wages + cash tips + payroll tips + any other additional earnings, excluding imputed income. This value is only available for processed payrolls."""
    net_pay: NotRequired[Nullable[float]]
    r"""The employee's net pay, equal to gross_pay - employee taxes - employee deductions or garnishments - cash tips. This value is only available for processed payrolls."""
    check_amount: NotRequired[Nullable[float]]
    r"""The employee's check amount, equal to net_pay + reimbursements. This value is only available for processed payrolls."""
    payment_method: NotRequired[Nullable[PayrollEmployeeCompensationsTypePaymentMethod]]
    r"""The employee's compensation payment method."""
    memo: NotRequired[Nullable[str]]
    r"""Custom text that will be printed as a personal note to the employee on a paystub."""
    fixed_compensations: NotRequired[List[FixedCompensationsTypedDict]]
    r"""An array of fixed compensations for the employee. Fixed compensations include tips, bonuses, and one time reimbursements. If this payroll has been processed, only fixed compensations with a value greater than 0.00 are returned. For an unprocessed payroll, all active fixed compensations are returned."""
    hourly_compensations: NotRequired[List[HourlyCompensationsTypedDict]]
    r"""An array of hourly compensations for the employee. Hourly compensations include regular, overtime, and double overtime hours. If this payroll has been processed, only hourly compensations with a value greater than 0.00 are returned. For an unprocessed payroll, all active hourly compensations are returned."""
    paid_time_off: NotRequired[
        List[PayrollEmployeeCompensationsTypePaidTimeOffTypedDict]
    ]
    r"""An array of all paid time off the employee is eligible for this pay period."""
    benefits: NotRequired[List[BenefitsTypedDict]]
    r"""An array of employee benefits for the pay period. Benefits are only included for processed payroll when the include parameter is present."""
    deductions: NotRequired[List[DeductionsTypedDict]]
    r"""An array of employee deductions for the pay period. Deductions are only included for processed payroll when the include parameter is present."""
    taxes: NotRequired[List[TaxesTypedDict]]
    r"""An array of employer and employee taxes for the pay period. Only included for processed or calculated payrolls when `taxes` is present in the `include` parameter."""


class PayrollEmployeeCompensationsType(BaseModel):
    employee_uuid: Optional[str] = None
    r"""The UUID of the employee."""

    excluded: Optional[bool] = None
    r"""This employee will be excluded (skipped) from payroll calculation and will not be paid for the payroll. Cancelling a payroll would reset all employees' excluded back to false."""

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

    gross_pay: OptionalNullable[float] = UNSET
    r"""The employee's gross pay, equal to regular wages + cash tips + payroll tips + any other additional earnings, excluding imputed income. This value is only available for processed payrolls."""

    net_pay: OptionalNullable[float] = UNSET
    r"""The employee's net pay, equal to gross_pay - employee taxes - employee deductions or garnishments - cash tips. This value is only available for processed payrolls."""

    check_amount: OptionalNullable[float] = UNSET
    r"""The employee's check amount, equal to net_pay + reimbursements. This value is only available for processed payrolls."""

    payment_method: OptionalNullable[PayrollEmployeeCompensationsTypePaymentMethod] = (
        UNSET
    )
    r"""The employee's compensation payment method."""

    memo: OptionalNullable[str] = UNSET
    r"""Custom text that will be printed as a personal note to the employee on a paystub."""

    fixed_compensations: Optional[List[FixedCompensations]] = None
    r"""An array of fixed compensations for the employee. Fixed compensations include tips, bonuses, and one time reimbursements. If this payroll has been processed, only fixed compensations with a value greater than 0.00 are returned. For an unprocessed payroll, all active fixed compensations are returned."""

    hourly_compensations: Optional[List[HourlyCompensations]] = None
    r"""An array of hourly compensations for the employee. Hourly compensations include regular, overtime, and double overtime hours. If this payroll has been processed, only hourly compensations with a value greater than 0.00 are returned. For an unprocessed payroll, all active hourly compensations are returned."""

    paid_time_off: Optional[List[PayrollEmployeeCompensationsTypePaidTimeOff]] = None
    r"""An array of all paid time off the employee is eligible for this pay period."""

    benefits: Optional[List[Benefits]] = None
    r"""An array of employee benefits for the pay period. Benefits are only included for processed payroll when the include parameter is present."""

    deductions: Optional[List[Deductions]] = None
    r"""An array of employee deductions for the pay period. Deductions are only included for processed payroll when the include parameter is present."""

    taxes: Optional[List[Taxes]] = None
    r"""An array of employer and employee taxes for the pay period. Only included for processed or calculated payrolls when `taxes` is present in the `include` parameter."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "employee_uuid",
            "excluded",
            "version",
            "gross_pay",
            "net_pay",
            "check_amount",
            "payment_method",
            "memo",
            "fixed_compensations",
            "hourly_compensations",
            "paid_time_off",
            "benefits",
            "deductions",
            "taxes",
        ]
        nullable_fields = [
            "gross_pay",
            "net_pay",
            "check_amount",
            "payment_method",
            "memo",
        ]
        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
