# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing

import pydantic

from ......core.datetime_utils import serialize_datetime
from ......core.pydantic_utilities import deep_union_pydantic_dicts
from .....commons.types.decimal import Decimal
from .....commons.types.facility_type_code import FacilityTypeCode
from .....commons.types.procedure_modifier import ProcedureModifier
from .....commons.types.service_line_units import ServiceLineUnits
from .....encounter_providers.resources.v_2.types.initial_referring_provider import InitialReferringProvider
from .....encounter_providers.resources.v_2.types.ordering_provider import OrderingProvider
from .....encounter_providers.resources.v_2.types.referring_provider import ReferringProvider
from .....encounter_providers.resources.v_2.types.supervising_provider import SupervisingProvider
from .drug_identification import DrugIdentification


class ServiceLineCreate(pydantic.BaseModel):
    modifiers: typing.Optional[typing.List[ProcedureModifier]] = None
    procedure_code: str
    quantity: Decimal = pydantic.Field()
    """
    String representation of a Decimal that can be parsed by most libraries.
    A ServiceLine quantity cannot contain more than one digit of precision.
    Example: 1.1 is valid, 1.11 is not.
    """

    units: ServiceLineUnits
    charge_amount_cents: typing.Optional[int] = pydantic.Field(default=None)
    """
    The total amount charged for this service line taking quantity into account. For example, if a single unit
    costs 100 cents and 2 units were rendered, the charge_amount_cents should be 200. Should be greater than or
    equal to 0.
    """

    diagnosis_pointers: typing.List[int] = pydantic.Field()
    """
    Indices (zero-indexed) of all the diagnoses this service line references
    """

    drug_identification: typing.Optional[DrugIdentification] = None
    place_of_service_code: typing.Optional[FacilityTypeCode] = None
    description: typing.Optional[str] = pydantic.Field(default=None)
    """
    A free-form description to clarify the related data elements and their content. Maps to SV1-01, C003-07 on the 837-P.
    """

    date_of_service: typing.Optional[dt.date] = None
    end_date_of_service: typing.Optional[dt.date] = None
    referring_provider: typing.Optional[ReferringProvider] = pydantic.Field(default=None)
    """
    The final provider who referred the services that were rendered.
    All physicians who order services or refer Medicare beneficiaries must
    report this data.
    """

    initial_referring_provider: typing.Optional[InitialReferringProvider] = pydantic.Field(default=None)
    """
    The second iteration of Loop ID-2310. Use code "P3 - Primary Care Provider" in this loop to
    indicate the initial referral from the primary care provider or whatever provider wrote the initial referral for this patient's episode of care being billed/reported in this transaction.
    Information in Loop ID-2310 applies to the entire claim unless overridden on a service line by the presence of Loop ID-2420 with the same value in NM101.
    """

    supervising_provider: typing.Optional[SupervisingProvider] = pydantic.Field(default=None)
    """
    Required when the rendering provider is supervised by a physician. If not required by this implementation guide, do not send.
    Information in Loop ID-2310 applies to the entire claim unless overridden on a service line by the presence of Loop ID-2420 with the same value in NM101.
    """

    ordering_provider: typing.Optional[OrderingProvider] = pydantic.Field(default=None)
    """
    Required when the service or supply was ordered by a provider who is different than the rendering provider for this service line.
    If not required by this implementation guide, do not send.
    """

    def json(self, **kwargs: typing.Any) -> str:
        kwargs_with_defaults: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
        return super().json(**kwargs_with_defaults)

    def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]:
        kwargs_with_defaults_exclude_unset: typing.Any = {"by_alias": True, "exclude_unset": True, **kwargs}
        kwargs_with_defaults_exclude_none: typing.Any = {"by_alias": True, "exclude_none": True, **kwargs}

        return deep_union_pydantic_dicts(
            super().dict(**kwargs_with_defaults_exclude_unset), super().dict(**kwargs_with_defaults_exclude_none)
        )

    class Config:
        frozen = True
        smart_union = True
        extra = pydantic.Extra.forbid
        json_encoders = {dt.datetime: serialize_datetime}
