# coding: utf-8

"""
    LUSID API

    FINBOURNE Technology  # noqa: E501

    Contact: info@finbourne.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""


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


from typing import List, Dict, Optional, Any, Union, TYPE_CHECKING
from typing_extensions import Annotated
from pydantic.v1 import BaseModel, StrictStr, StrictInt, StrictBool, StrictFloat, StrictBytes, Field, validator, ValidationError, conlist, constr
from datetime import datetime
from lusid.models.currency_and_amount import CurrencyAndAmount

class RealisedGainLoss(BaseModel):
    """
    RealisedGainLoss
    """
    instrument_scope:  Optional[StrictStr] = Field(None,alias="instrumentScope", description="The scope in which the instrument lies.") 
    instrument_uid:  StrictStr = Field(...,alias="instrumentUid", description="The unique Lusid Instrument Id (LUID) of the instrument that this gain or loss is associated with.") 
    units: Union[StrictFloat, StrictInt] = Field(description="The number of units of the associated instrument against which the gain or loss has been realised.")
    purchase_trade_date: Optional[datetime] = Field(default=None, description="The effective datetime at which the units associated with this gain or loss were originally purchased.", alias="purchaseTradeDate")
    purchase_settlement_date: Optional[datetime] = Field(default=None, description="The effective datetime at which the units associated with this gain or loss were originally settled.", alias="purchaseSettlementDate")
    purchase_price: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="The purchase price of each unit associated with this gain or loss.", alias="purchasePrice")
    cost_trade_ccy: CurrencyAndAmount = Field(alias="costTradeCcy")
    cost_portfolio_ccy: CurrencyAndAmount = Field(alias="costPortfolioCcy")
    realised_trade_ccy: CurrencyAndAmount = Field(alias="realisedTradeCcy")
    realised_total: CurrencyAndAmount = Field(alias="realisedTotal")
    realised_market: Optional[CurrencyAndAmount] = Field(default=None, alias="realisedMarket")
    realised_currency: Optional[CurrencyAndAmount] = Field(default=None, alias="realisedCurrency")
    tax_lot_id:  Optional[StrictStr] = Field(None,alias="taxLotId", description="The identifier of the tax lot with which this gain or loss is associated.") 
    realised_amortisation: Optional[CurrencyAndAmount] = Field(default=None, alias="realisedAmortisation")
    __properties = ["instrumentScope", "instrumentUid", "units", "purchaseTradeDate", "purchaseSettlementDate", "purchasePrice", "costTradeCcy", "costPortfolioCcy", "realisedTradeCcy", "realisedTotal", "realisedMarket", "realisedCurrency", "taxLotId", "realisedAmortisation"]

    class Config:
        """Pydantic configuration"""
        allow_population_by_field_name = True
        validate_assignment = True

    def __str__(self):
        """For `print` and `pprint`"""
        return pprint.pformat(self.dict(by_alias=False))

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

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

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        return json.dumps(self.to_dict())

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

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        _dict = self.dict(by_alias=True,
                          exclude={
                            "purchase_trade_date",
                            "purchase_settlement_date",
                          },
                          exclude_none=True)
        # override the default output from pydantic by calling `to_dict()` of cost_trade_ccy
        if self.cost_trade_ccy:
            _dict['costTradeCcy'] = self.cost_trade_ccy.to_dict()
        # override the default output from pydantic by calling `to_dict()` of cost_portfolio_ccy
        if self.cost_portfolio_ccy:
            _dict['costPortfolioCcy'] = self.cost_portfolio_ccy.to_dict()
        # override the default output from pydantic by calling `to_dict()` of realised_trade_ccy
        if self.realised_trade_ccy:
            _dict['realisedTradeCcy'] = self.realised_trade_ccy.to_dict()
        # override the default output from pydantic by calling `to_dict()` of realised_total
        if self.realised_total:
            _dict['realisedTotal'] = self.realised_total.to_dict()
        # override the default output from pydantic by calling `to_dict()` of realised_market
        if self.realised_market:
            _dict['realisedMarket'] = self.realised_market.to_dict()
        # override the default output from pydantic by calling `to_dict()` of realised_currency
        if self.realised_currency:
            _dict['realisedCurrency'] = self.realised_currency.to_dict()
        # override the default output from pydantic by calling `to_dict()` of realised_amortisation
        if self.realised_amortisation:
            _dict['realisedAmortisation'] = self.realised_amortisation.to_dict()
        # set to None if instrument_scope (nullable) is None
        # and __fields_set__ contains the field
        if self.instrument_scope is None and "instrument_scope" in self.__fields_set__:
            _dict['instrumentScope'] = None

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

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

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

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

        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> RealisedGainLoss:
        """Create an instance of RealisedGainLoss from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return RealisedGainLoss.parse_obj(obj)

        _obj = RealisedGainLoss.parse_obj({
            "instrument_scope": obj.get("instrumentScope"),
            "instrument_uid": obj.get("instrumentUid"),
            "units": obj.get("units"),
            "purchase_trade_date": obj.get("purchaseTradeDate"),
            "purchase_settlement_date": obj.get("purchaseSettlementDate"),
            "purchase_price": obj.get("purchasePrice"),
            "cost_trade_ccy": CurrencyAndAmount.from_dict(obj.get("costTradeCcy")) if obj.get("costTradeCcy") is not None else None,
            "cost_portfolio_ccy": CurrencyAndAmount.from_dict(obj.get("costPortfolioCcy")) if obj.get("costPortfolioCcy") is not None else None,
            "realised_trade_ccy": CurrencyAndAmount.from_dict(obj.get("realisedTradeCcy")) if obj.get("realisedTradeCcy") is not None else None,
            "realised_total": CurrencyAndAmount.from_dict(obj.get("realisedTotal")) if obj.get("realisedTotal") is not None else None,
            "realised_market": CurrencyAndAmount.from_dict(obj.get("realisedMarket")) if obj.get("realisedMarket") is not None else None,
            "realised_currency": CurrencyAndAmount.from_dict(obj.get("realisedCurrency")) if obj.get("realisedCurrency") is not None else None,
            "tax_lot_id": obj.get("taxLotId"),
            "realised_amortisation": CurrencyAndAmount.from_dict(obj.get("realisedAmortisation")) if obj.get("realisedAmortisation") is not None else None
        })
        return _obj

RealisedGainLoss.update_forward_refs()
