# coding: utf-8

"""
    (v2.0) Dynamics 365 Business Central

    (v2.0) Business Central Standard APIs

    The version of the OpenAPI document: 2.0.0
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from datetime import date
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing_extensions import Annotated
from pybusinesscentral.model.documentlineobjectdetailstype import Documentlineobjectdetailstype
from pybusinesscentral.model.unitofmeasuretype import Unitofmeasuretype
from typing import Optional, Set
from typing_extensions import Self

class PostSalesInvoiceLineForSalesInvoiceRequest(BaseModel):
    """
    PostSalesInvoiceLineForSalesInvoiceRequest
    """ # noqa: E501
    id: Optional[Annotated[str, Field(strict=True, max_length=50)]] = Field(default=None, description="(v1.0) The id property for the Dynamics 365 Business Central salesInvoiceLine entity")
    document_id: Optional[StrictStr] = Field(default=None, description="(v1.0) The documentId property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="documentId")
    sequence: Optional[StrictInt] = Field(default=None, description="(v1.0) The sequence property for the Dynamics 365 Business Central salesInvoiceLine entity")
    item_id: Optional[StrictStr] = Field(default=None, description="(v1.0) The itemId property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="itemId")
    account_id: Optional[StrictStr] = Field(default=None, description="(v1.0) The accountId property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="accountId")
    line_type: Optional[StrictStr] = Field(default=None, description="(v1.0) The lineType property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="lineType")
    line_details: Optional[Documentlineobjectdetailstype] = Field(default=None, alias="lineDetails")
    description: Optional[Annotated[str, Field(strict=True, max_length=100)]] = Field(default=None, description="(v1.0) The description property for the Dynamics 365 Business Central salesInvoiceLine entity")
    unit_of_measure_id: Optional[StrictStr] = Field(default=None, description="(v1.0) The unitOfMeasureId property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="unitOfMeasureId")
    unit_of_measure: Optional[Unitofmeasuretype] = Field(default=None, alias="unitOfMeasure")
    unit_price: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The unitPrice property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="unitPrice")
    quantity: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The quantity property for the Dynamics 365 Business Central salesInvoiceLine entity")
    discount_amount: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The discountAmount property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="discountAmount")
    discount_percent: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The discountPercent property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="discountPercent")
    discount_applied_before_tax: Optional[StrictBool] = Field(default=None, description="(v1.0) The discountAppliedBeforeTax property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="discountAppliedBeforeTax")
    amount_excluding_tax: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The amountExcludingTax property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="amountExcludingTax")
    tax_code: Optional[Annotated[str, Field(strict=True, max_length=50)]] = Field(default=None, description="(v1.0) The taxCode property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="taxCode")
    tax_percent: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The taxPercent property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="taxPercent")
    total_tax_amount: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The totalTaxAmount property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="totalTaxAmount")
    amount_including_tax: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The amountIncludingTax property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="amountIncludingTax")
    invoice_discount_allocation: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The invoiceDiscountAllocation property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="invoiceDiscountAllocation")
    net_amount: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The netAmount property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="netAmount")
    net_tax_amount: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The netTaxAmount property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="netTaxAmount")
    net_amount_including_tax: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="(v1.0) The netAmountIncludingTax property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="netAmountIncludingTax")
    shipment_date: Optional[date] = Field(default=None, description="(v1.0) The shipmentDate property for the Dynamics 365 Business Central salesInvoiceLine entity", alias="shipmentDate")
    __properties: ClassVar[List[str]] = ["id", "documentId", "sequence", "itemId", "accountId", "lineType", "lineDetails", "description", "unitOfMeasureId", "unitOfMeasure", "unitPrice", "quantity", "discountAmount", "discountPercent", "discountAppliedBeforeTax", "amountExcludingTax", "taxCode", "taxPercent", "totalTaxAmount", "amountIncludingTax", "invoiceDiscountAllocation", "netAmount", "netTaxAmount", "netAmountIncludingTax", "shipmentDate"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of PostSalesInvoiceLineForSalesInvoiceRequest from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of line_details
        if self.line_details:
            _dict['lineDetails'] = self.line_details.to_dict()
        # override the default output from pydantic by calling `to_dict()` of unit_of_measure
        if self.unit_of_measure:
            _dict['unitOfMeasure'] = self.unit_of_measure.to_dict()
        # set to None if document_id (nullable) is None
        # and model_fields_set contains the field
        if self.document_id is None and "document_id" in self.model_fields_set:
            _dict['documentId'] = None

        # set to None if sequence (nullable) is None
        # and model_fields_set contains the field
        if self.sequence is None and "sequence" in self.model_fields_set:
            _dict['sequence'] = None

        # set to None if item_id (nullable) is None
        # and model_fields_set contains the field
        if self.item_id is None and "item_id" in self.model_fields_set:
            _dict['itemId'] = None

        # set to None if account_id (nullable) is None
        # and model_fields_set contains the field
        if self.account_id is None and "account_id" in self.model_fields_set:
            _dict['accountId'] = None

        # set to None if line_type (nullable) is None
        # and model_fields_set contains the field
        if self.line_type is None and "line_type" in self.model_fields_set:
            _dict['lineType'] = None

        # set to None if line_details (nullable) is None
        # and model_fields_set contains the field
        if self.line_details is None and "line_details" in self.model_fields_set:
            _dict['lineDetails'] = None

        # set to None if description (nullable) is None
        # and model_fields_set contains the field
        if self.description is None and "description" in self.model_fields_set:
            _dict['description'] = None

        # set to None if unit_of_measure_id (nullable) is None
        # and model_fields_set contains the field
        if self.unit_of_measure_id is None and "unit_of_measure_id" in self.model_fields_set:
            _dict['unitOfMeasureId'] = None

        # set to None if unit_of_measure (nullable) is None
        # and model_fields_set contains the field
        if self.unit_of_measure is None and "unit_of_measure" in self.model_fields_set:
            _dict['unitOfMeasure'] = None

        # set to None if unit_price (nullable) is None
        # and model_fields_set contains the field
        if self.unit_price is None and "unit_price" in self.model_fields_set:
            _dict['unitPrice'] = None

        # set to None if quantity (nullable) is None
        # and model_fields_set contains the field
        if self.quantity is None and "quantity" in self.model_fields_set:
            _dict['quantity'] = None

        # set to None if discount_amount (nullable) is None
        # and model_fields_set contains the field
        if self.discount_amount is None and "discount_amount" in self.model_fields_set:
            _dict['discountAmount'] = None

        # set to None if discount_percent (nullable) is None
        # and model_fields_set contains the field
        if self.discount_percent is None and "discount_percent" in self.model_fields_set:
            _dict['discountPercent'] = None

        # set to None if discount_applied_before_tax (nullable) is None
        # and model_fields_set contains the field
        if self.discount_applied_before_tax is None and "discount_applied_before_tax" in self.model_fields_set:
            _dict['discountAppliedBeforeTax'] = None

        # set to None if amount_excluding_tax (nullable) is None
        # and model_fields_set contains the field
        if self.amount_excluding_tax is None and "amount_excluding_tax" in self.model_fields_set:
            _dict['amountExcludingTax'] = None

        # set to None if tax_code (nullable) is None
        # and model_fields_set contains the field
        if self.tax_code is None and "tax_code" in self.model_fields_set:
            _dict['taxCode'] = None

        # set to None if tax_percent (nullable) is None
        # and model_fields_set contains the field
        if self.tax_percent is None and "tax_percent" in self.model_fields_set:
            _dict['taxPercent'] = None

        # set to None if total_tax_amount (nullable) is None
        # and model_fields_set contains the field
        if self.total_tax_amount is None and "total_tax_amount" in self.model_fields_set:
            _dict['totalTaxAmount'] = None

        # set to None if amount_including_tax (nullable) is None
        # and model_fields_set contains the field
        if self.amount_including_tax is None and "amount_including_tax" in self.model_fields_set:
            _dict['amountIncludingTax'] = None

        # set to None if invoice_discount_allocation (nullable) is None
        # and model_fields_set contains the field
        if self.invoice_discount_allocation is None and "invoice_discount_allocation" in self.model_fields_set:
            _dict['invoiceDiscountAllocation'] = None

        # set to None if net_amount (nullable) is None
        # and model_fields_set contains the field
        if self.net_amount is None and "net_amount" in self.model_fields_set:
            _dict['netAmount'] = None

        # set to None if net_tax_amount (nullable) is None
        # and model_fields_set contains the field
        if self.net_tax_amount is None and "net_tax_amount" in self.model_fields_set:
            _dict['netTaxAmount'] = None

        # set to None if net_amount_including_tax (nullable) is None
        # and model_fields_set contains the field
        if self.net_amount_including_tax is None and "net_amount_including_tax" in self.model_fields_set:
            _dict['netAmountIncludingTax'] = None

        # set to None if shipment_date (nullable) is None
        # and model_fields_set contains the field
        if self.shipment_date is None and "shipment_date" in self.model_fields_set:
            _dict['shipmentDate'] = None

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of PostSalesInvoiceLineForSalesInvoiceRequest from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "id": obj.get("id"),
            "documentId": obj.get("documentId"),
            "sequence": obj.get("sequence"),
            "itemId": obj.get("itemId"),
            "accountId": obj.get("accountId"),
            "lineType": obj.get("lineType"),
            "lineDetails": Documentlineobjectdetailstype.from_dict(obj["lineDetails"]) if obj.get("lineDetails") is not None else None,
            "description": obj.get("description"),
            "unitOfMeasureId": obj.get("unitOfMeasureId"),
            "unitOfMeasure": Unitofmeasuretype.from_dict(obj["unitOfMeasure"]) if obj.get("unitOfMeasure") is not None else None,
            "unitPrice": obj.get("unitPrice"),
            "quantity": obj.get("quantity"),
            "discountAmount": obj.get("discountAmount"),
            "discountPercent": obj.get("discountPercent"),
            "discountAppliedBeforeTax": obj.get("discountAppliedBeforeTax"),
            "amountExcludingTax": obj.get("amountExcludingTax"),
            "taxCode": obj.get("taxCode"),
            "taxPercent": obj.get("taxPercent"),
            "totalTaxAmount": obj.get("totalTaxAmount"),
            "amountIncludingTax": obj.get("amountIncludingTax"),
            "invoiceDiscountAllocation": obj.get("invoiceDiscountAllocation"),
            "netAmount": obj.get("netAmount"),
            "netTaxAmount": obj.get("netTaxAmount"),
            "netAmountIncludingTax": obj.get("netAmountIncludingTax"),
            "shipmentDate": obj.get("shipmentDate")
        })
        return _obj


