# This file was generated by liblab | https://liblab.com/

from __future__ import annotations
from enum import Enum
from .utils.json_map import JsonMap
from .base import BaseModel
from .contract_who_reports_enum import ContractWhoReportsEnum
from .meta_data_of_contract_to_create import MetaDataOfContractToCreate
from .identifier_value import IdentifierValue, IdentifierValueGuard
from .work_statement_cycle_scale_enum import WorkStatementCycleScaleEnum
from .work_statement_cycle_end_type_enum import WorkStatementCycleEndTypeEnum
from .work_statement_payment_due_type_enum import WorkStatementPaymentDueTypeEnum
from .work_statement_scale_enum import WorkStatementScaleEnum


@JsonMap({"id_": "id"})
class ClientLegalEntity4(BaseModel):
    """Choose the Deel legal entity for this contract. Use legal entity endpoint to retrieve a list of legal entities in your organization.

    :param id_: id_
    :type id_: IdentifierValue
    """

    def __init__(self, id_: IdentifierValue):
        self.id_ = IdentifierValueGuard.return_one_of(id_)


@JsonMap({"id_": "id"})
class ClientTeam2(BaseModel):
    """Choose the Deel team for this contract. Use teams endpoint to retrieve a list of teams in your organization.

    :param id_: id_
    :type id_: IdentifierValue
    """

    def __init__(self, id_: IdentifierValue):
        self.id_ = IdentifierValueGuard.return_one_of(id_)


@JsonMap({})
class ContractToCreatePayAsYouGoTimeBasedClient(BaseModel):
    """ContractToCreatePayAsYouGoTimeBasedClient

    :param legal_entity: Choose the Deel legal entity for this contract. Use legal entity endpoint to retrieve a list of legal entities in your organization.
    :type legal_entity: ClientLegalEntity4
    :param team: Choose the Deel team for this contract. Use teams endpoint to retrieve a list of teams in your organization.
    :type team: ClientTeam2
    """

    def __init__(self, legal_entity: ClientLegalEntity4, team: ClientTeam2):
        self.legal_entity = self._define_object(legal_entity, ClientLegalEntity4)
        self.team = self._define_object(team, ClientTeam2)


@JsonMap({"id_": "id"})
class ContractToCreatePayAsYouGoTimeBasedJobTitle(BaseModel):
    """Worker's job title. You can enter a custom job title or use a pre-defiled job title using the Id retrieved in job-titles endpoint.

    :param id_: Unique identifier of this resource., defaults to None
    :type id_: str, optional
    :param name: Job title. Please leave it blank when entering an Id., defaults to None
    :type name: str, optional
    """

    def __init__(self, id_: str = None, name: str = None):
        if id_ is not None:
            self.id_ = id_
        if name is not None:
            self.name = name


@JsonMap({"id_": "id"})
class ContractToCreatePayAsYouGoTimeBasedSeniority(BaseModel):
    """Job seniority level. Please use the seniority levels endpoint to retrieve the list of seniority levels.

    :param id_: id_, defaults to None
    :type id_: IdentifierValue, optional
    """

    def __init__(self, id_: IdentifierValue = None):
        if id_ is not None:
            self.id_ = IdentifierValueGuard.return_one_of(id_)


@JsonMap({})
class ContractToCreatePayAsYouGoTimeBasedWorker(BaseModel):
    """Worker properties

    :param expected_email: Worker's email address.
    :type expected_email: str
    :param first_name: Worker's first name
    :type first_name: str
    :param last_name: Worker's last name, defaults to None
    :type last_name: str, optional
    """

    def __init__(self, expected_email: str, first_name: str, last_name: str = None):
        self.expected_email = expected_email
        self.first_name = first_name
        if last_name is not None:
            self.last_name = last_name


class ContractToCreatePayAsYouGoTimeBasedType(Enum):
    """An enumeration representing different categories.

    :cvar PAY_AS_YOU_GO_TIME_BASED: "pay_as_you_go_time_based"
    :vartype PAY_AS_YOU_GO_TIME_BASED: str
    """

    PAY_AS_YOU_GO_TIME_BASED = "pay_as_you_go_time_based"

    def list():
        """Lists all category values.

        :return: A list of all category values.
        :rtype: list
        """
        return list(
            map(
                lambda x: x.value,
                ContractToCreatePayAsYouGoTimeBasedType._member_map_.values(),
            )
        )


@JsonMap({})
class ContractToCreatePayAsYouGoTimeBasedCompensationDetails(BaseModel):
    """ContractToCreatePayAsYouGoTimeBasedCompensationDetails

    :param amount: amount
    :type amount: float
    :param currency_code: currency_code
    :type currency_code: str
    :param frequency: Scale of the invoice cycle.
    :type frequency: WorkStatementCycleScaleEnum
    :param cycle_end: Date invoice cycle ends.
    :type cycle_end: float
    :param cycle_end_type: Cycle end can be weekly 1-7 (Monday = 1) or monthly 1-31.
    :type cycle_end_type: WorkStatementCycleEndTypeEnum
    :param payment_due_type: Type of payment due. If the payment is due on the last day of month, enter 'WITHIN_MONTH'.
    :type payment_due_type: WorkStatementPaymentDueTypeEnum
    :param payment_due_days: payment_due_days
    :type payment_due_days: float
    :param pay_before_weekends: If the payment due is on a weekend, pay on Friday., defaults to None
    :type pay_before_weekends: bool, optional
    :param first_payment_date: Short date in format ISO-8601 (YYYY-MM-DD). For example 2022-12-31., defaults to None
    :type first_payment_date: str, optional
    :param first_payment: First payment amount., defaults to None
    :type first_payment: float, optional
    :param notice_period: Days before to notice the termination of contract for eather party., defaults to None
    :type notice_period: float, optional
    :param scale: Defines the scale at which the amount is paid. For example, enter 'hourly' to define the amount per hour. This field can be excluded when creating a Pay-as-you-go task-based or Milestone contracts.
    :type scale: WorkStatementScaleEnum
    """

    def __init__(
        self,
        amount: float,
        currency_code: str,
        frequency: WorkStatementCycleScaleEnum,
        cycle_end: float,
        cycle_end_type: WorkStatementCycleEndTypeEnum,
        payment_due_type: WorkStatementPaymentDueTypeEnum,
        payment_due_days: float,
        scale: WorkStatementScaleEnum,
        pay_before_weekends: bool = None,
        first_payment_date: str = None,
        first_payment: float = None,
        notice_period: float = None,
    ):
        self.amount = amount
        self.currency_code = self._pattern_matching(
            currency_code, "^[A-Z]{3}$", "currency_code"
        )
        self.frequency = self._enum_matching(
            frequency, WorkStatementCycleScaleEnum.list(), "frequency"
        )
        self.cycle_end = cycle_end
        self.cycle_end_type = self._enum_matching(
            cycle_end_type, WorkStatementCycleEndTypeEnum.list(), "cycle_end_type"
        )
        self.payment_due_type = self._enum_matching(
            payment_due_type, WorkStatementPaymentDueTypeEnum.list(), "payment_due_type"
        )
        self.payment_due_days = payment_due_days
        if pay_before_weekends is not None:
            self.pay_before_weekends = pay_before_weekends
        if first_payment_date is not None:
            self.first_payment_date = self._pattern_matching(
                first_payment_date, "^\d{4}-\d{2}-\d{2}$", "first_payment_date"
            )
        if first_payment is not None:
            self.first_payment = first_payment
        if notice_period is not None:
            self.notice_period = notice_period
        self.scale = self._enum_matching(scale, WorkStatementScaleEnum.list(), "scale")


@JsonMap({"type_": "type"})
class ContractToCreatePayAsYouGoTimeBased(BaseModel):
    """ContractToCreatePayAsYouGoTimeBased

    :param title: The title of the contract.
    :type title: str
    :param country_code: Country code., defaults to None
    :type country_code: str, optional
    :param state_code: The state or province code. Use country lookup endpoint to retrieve state codes., defaults to None
    :type state_code: str, optional
    :param scope_of_work: Describe the work to be performed., defaults to None
    :type scope_of_work: str, optional
    :param special_clause: Enter any special clause you may have., defaults to None
    :type special_clause: str, optional
    :param termination_date: Short date in format ISO-8601 (YYYY-MM-DD). For example 2022-12-31., defaults to None
    :type termination_date: str, optional
    :param client: client
    :type client: ContractToCreatePayAsYouGoTimeBasedClient
    :param job_title: Worker's job title. You can enter a custom job title or use a pre-defiled job title using the Id retrieved in job-titles endpoint.
    :type job_title: ContractToCreatePayAsYouGoTimeBasedJobTitle
    :param seniority: Job seniority level. Please use the seniority levels endpoint to retrieve the list of seniority levels., defaults to None
    :type seniority: ContractToCreatePayAsYouGoTimeBasedSeniority, optional
    :param notice_period: Days before to notice the termination of contract for eather party., defaults to None
    :type notice_period: float, optional
    :param who_reports: Flag to indicate who is supposed to provide regular reports, defaults to None
    :type who_reports: ContractWhoReportsEnum, optional
    :param meta: Additional custom info about a contract
    :type meta: MetaDataOfContractToCreate
    :param external_id: External Id., defaults to None
    :type external_id: str, optional
    :param worker: Worker properties, defaults to None
    :type worker: ContractToCreatePayAsYouGoTimeBasedWorker, optional
    :param type_: type_
    :type type_: ContractToCreatePayAsYouGoTimeBasedType
    :param start_date: Short date in format ISO-8601 (YYYY-MM-DD). For example: 2022-12-31.
    :type start_date: str
    :param compensation_details: compensation_details
    :type compensation_details: ContractToCreatePayAsYouGoTimeBasedCompensationDetails
    """

    def __init__(
        self,
        title: str,
        client: ContractToCreatePayAsYouGoTimeBasedClient,
        job_title: ContractToCreatePayAsYouGoTimeBasedJobTitle,
        meta: MetaDataOfContractToCreate,
        type_: ContractToCreatePayAsYouGoTimeBasedType,
        start_date: str,
        compensation_details: ContractToCreatePayAsYouGoTimeBasedCompensationDetails,
        country_code: str = None,
        state_code: str = None,
        scope_of_work: str = None,
        special_clause: str = None,
        termination_date: str = None,
        seniority: ContractToCreatePayAsYouGoTimeBasedSeniority = None,
        notice_period: float = None,
        who_reports: ContractWhoReportsEnum = None,
        external_id: str = None,
        worker: ContractToCreatePayAsYouGoTimeBasedWorker = None,
    ):
        self.title = title
        if country_code is not None:
            self.country_code = self._pattern_matching(
                country_code, "^[A-Z]{2}$", "country_code"
            )
        if state_code is not None:
            self.state_code = state_code
        if scope_of_work is not None:
            self.scope_of_work = scope_of_work
        if special_clause is not None:
            self.special_clause = special_clause
        if termination_date is not None:
            self.termination_date = self._pattern_matching(
                termination_date, "^\d{4}-\d{2}-\d{2}$", "termination_date"
            )
        self.client = self._define_object(
            client, ContractToCreatePayAsYouGoTimeBasedClient
        )
        self.job_title = self._define_object(
            job_title, ContractToCreatePayAsYouGoTimeBasedJobTitle
        )
        if seniority is not None:
            self.seniority = self._define_object(
                seniority, ContractToCreatePayAsYouGoTimeBasedSeniority
            )
        if notice_period is not None:
            self.notice_period = notice_period
        if who_reports is not None:
            self.who_reports = self._enum_matching(
                who_reports, ContractWhoReportsEnum.list(), "who_reports"
            )
        self.meta = self._define_object(meta, MetaDataOfContractToCreate)
        if external_id is not None:
            self.external_id = external_id
        if worker is not None:
            self.worker = self._define_object(
                worker, ContractToCreatePayAsYouGoTimeBasedWorker
            )
        self.type_ = self._enum_matching(
            type_, ContractToCreatePayAsYouGoTimeBasedType.list(), "type_"
        )
        self.start_date = start_date
        self.compensation_details = self._define_object(
            compensation_details, ContractToCreatePayAsYouGoTimeBasedCompensationDetails
        )
