# 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.resource_id import ResourceId

class NavType(BaseModel):
    """
    NavType
    """
    status:  StrictStr = Field(...,alias="status", description="The Status of the Nav Type. Can be 'Active' or 'Inactive'.") 
    code:  Optional[StrictStr] = Field(None,alias="code", description="The Code for the Nav Type. Must be unique within the Fund.") 
    display_name:  Optional[StrictStr] = Field(None,alias="displayName", description="The Display Name for the Nav Type. Must be unique within the Fund.") 
    description:  Optional[StrictStr] = Field(None,alias="description", description="The Description for the Nav Type.") 
    chart_of_accounts_id: ResourceId = Field(alias="chartOfAccountsId")
    posting_module_codes: Optional[List[StrictStr]] = Field(default=None, description="The Posting Module Codes from which the rules to be applied are retrieved.", alias="postingModuleCodes")
    cleardown_module_codes: Optional[List[StrictStr]] = Field(default=None, description="The Cleardown Module Codes from which the rules to be applied are retrieved.", alias="cleardownModuleCodes")
    valuation_recipe_id: ResourceId = Field(alias="valuationRecipeId")
    holding_recipe_id: ResourceId = Field(alias="holdingRecipeId")
    accounting_method:  StrictStr = Field(...,alias="accountingMethod", description="Determines the accounting treatment given to the simple position portfolio's tax lots. A non-default value is required.") 
    sub_holding_keys: Optional[List[StrictStr]] = Field(default=None, description="A set of unique transaction properties to group the derived transaction portfolio's holdings by, perhaps for strategy tagging. Each property must be from the 'Transaction' domain and identified by a key in the format {domain}/{scope}/{code}, for example 'Transaction/strategies/quantsignal'. See https://support.lusid.com/knowledgebase/article/KA-01879/en-us for more information.", alias="subHoldingKeys")
    amortisation_method:  StrictStr = Field(...,alias="amortisationMethod", description="The amortisation method used by the portfolio for the calculation. The available values are: NoAmortisation, StraightLine, EffectiveYield, StraightLineSettlementDate, EffectiveYieldSettlementDate") 
    transaction_type_scope:  StrictStr = Field(...,alias="transactionTypeScope", description="The scope of the transaction types.") 
    cash_gain_loss_calculation_date:  StrictStr = Field(...,alias="cashGainLossCalculationDate", description="The option when the Cash Gain Loss to be calulated, TransactionDate/SettlementDate. A non-default value is required.") 
    amortisation_rule_set_id: Optional[ResourceId] = Field(default=None, alias="amortisationRuleSetId")
    leader_nav_type_code:  Optional[StrictStr] = Field(None,alias="leaderNavTypeCode", description="The code of the Nav Type that this Nav Type will follow when set.") 
    transaction_template_scope:  Optional[StrictStr] = Field(None,alias="transactionTemplateScope", description="The Transaction Template Scope used by the NavType. Will default to the scope set on the parent portfolio. If the fund has multiple parent portfolios, then the Transaction Template Scope must be provided.") 
    __properties = ["status", "code", "displayName", "description", "chartOfAccountsId", "postingModuleCodes", "cleardownModuleCodes", "valuationRecipeId", "holdingRecipeId", "accountingMethod", "subHoldingKeys", "amortisationMethod", "transactionTypeScope", "cashGainLossCalculationDate", "amortisationRuleSetId", "leaderNavTypeCode", "transactionTemplateScope"]

    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) -> NavType:
        """Create an instance of NavType 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={
                          },
                          exclude_none=True)
        # override the default output from pydantic by calling `to_dict()` of chart_of_accounts_id
        if self.chart_of_accounts_id:
            _dict['chartOfAccountsId'] = self.chart_of_accounts_id.to_dict()
        # override the default output from pydantic by calling `to_dict()` of valuation_recipe_id
        if self.valuation_recipe_id:
            _dict['valuationRecipeId'] = self.valuation_recipe_id.to_dict()
        # override the default output from pydantic by calling `to_dict()` of holding_recipe_id
        if self.holding_recipe_id:
            _dict['holdingRecipeId'] = self.holding_recipe_id.to_dict()
        # override the default output from pydantic by calling `to_dict()` of amortisation_rule_set_id
        if self.amortisation_rule_set_id:
            _dict['amortisationRuleSetId'] = self.amortisation_rule_set_id.to_dict()
        # set to None if code (nullable) is None
        # and __fields_set__ contains the field
        if self.code is None and "code" in self.__fields_set__:
            _dict['code'] = None

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

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

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

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

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

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

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

        return _dict

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

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

        _obj = NavType.parse_obj({
            "status": obj.get("status"),
            "code": obj.get("code"),
            "display_name": obj.get("displayName"),
            "description": obj.get("description"),
            "chart_of_accounts_id": ResourceId.from_dict(obj.get("chartOfAccountsId")) if obj.get("chartOfAccountsId") is not None else None,
            "posting_module_codes": obj.get("postingModuleCodes"),
            "cleardown_module_codes": obj.get("cleardownModuleCodes"),
            "valuation_recipe_id": ResourceId.from_dict(obj.get("valuationRecipeId")) if obj.get("valuationRecipeId") is not None else None,
            "holding_recipe_id": ResourceId.from_dict(obj.get("holdingRecipeId")) if obj.get("holdingRecipeId") is not None else None,
            "accounting_method": obj.get("accountingMethod"),
            "sub_holding_keys": obj.get("subHoldingKeys"),
            "amortisation_method": obj.get("amortisationMethod"),
            "transaction_type_scope": obj.get("transactionTypeScope"),
            "cash_gain_loss_calculation_date": obj.get("cashGainLossCalculationDate"),
            "amortisation_rule_set_id": ResourceId.from_dict(obj.get("amortisationRuleSetId")) if obj.get("amortisationRuleSetId") is not None else None,
            "leader_nav_type_code": obj.get("leaderNavTypeCode"),
            "transaction_template_scope": obj.get("transactionTemplateScope")
        })
        return _obj

NavType.update_forward_refs()
