# 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.effective_range import EffectiveRange
from lusid.models.property_value import PropertyValue

class ChangeIntervalWithOrderManagementDetail(BaseModel):
    """
    Defines a change that occured for an entity, with extra detail about the change  # noqa: E501
    """
    detail: Optional[Dict[str, Optional[StrictStr]]] = Field(default=None, description="Information about the particular instance of the ChangeInterval (supplied information depends on the type of Action). Contains extra detail for order management actions such as related entity ids and compliance run details.")
    action_description:  Optional[StrictStr] = Field(None,alias="actionDescription", description="Description of the action performed on the entity.") 
    as_at_modified: Optional[datetime] = Field(default=None, description="The date/time of the change.", alias="asAtModified")
    user_id_modified:  Optional[StrictStr] = Field(None,alias="userIdModified", description="The unique identifier of the user that made the change.") 
    request_id_modified:  Optional[StrictStr] = Field(None,alias="requestIdModified", description="The unique identifier of the request that the changes were part of.") 
    reason_modified:  Optional[StrictStr] = Field(None,alias="reasonModified", description="The reason for an entity modification.") 
    as_at_version_number: Optional[StrictInt] = Field(default=None, description="The version number for the entity (the entity was created at version 1). This may refer to the version number of a changed related entity, not a change for the entity itself.", alias="asAtVersionNumber")
    staged_modification_id_modified:  Optional[StrictStr] = Field(None,alias="stagedModificationIdModified", description="The id of the staged modification that was approved. Will be null if the change didn't come from a staged modification.") 
    action:  Optional[StrictStr] = Field(None,alias="action", description="The action performed on the field.") 
    attribute_name:  Optional[StrictStr] = Field(None,alias="attributeName", description="The name of the field or property that has been changed.") 
    previous_value: Optional[PropertyValue] = Field(default=None, alias="previousValue")
    new_value: Optional[PropertyValue] = Field(default=None, alias="newValue")
    effective_range: Optional[EffectiveRange] = Field(default=None, alias="effectiveRange")
    __properties = ["detail", "actionDescription", "asAtModified", "userIdModified", "requestIdModified", "reasonModified", "asAtVersionNumber", "stagedModificationIdModified", "action", "attributeName", "previousValue", "newValue", "effectiveRange"]

    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) -> ChangeIntervalWithOrderManagementDetail:
        """Create an instance of ChangeIntervalWithOrderManagementDetail 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 previous_value
        if self.previous_value:
            _dict['previousValue'] = self.previous_value.to_dict()
        # override the default output from pydantic by calling `to_dict()` of new_value
        if self.new_value:
            _dict['newValue'] = self.new_value.to_dict()
        # override the default output from pydantic by calling `to_dict()` of effective_range
        if self.effective_range:
            _dict['effectiveRange'] = self.effective_range.to_dict()
        # set to None if detail (nullable) is None
        # and __fields_set__ contains the field
        if self.detail is None and "detail" in self.__fields_set__:
            _dict['detail'] = None

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

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

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

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

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

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

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

        return _dict

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

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

        _obj = ChangeIntervalWithOrderManagementDetail.parse_obj({
            "detail": obj.get("detail"),
            "action_description": obj.get("actionDescription"),
            "as_at_modified": obj.get("asAtModified"),
            "user_id_modified": obj.get("userIdModified"),
            "request_id_modified": obj.get("requestIdModified"),
            "reason_modified": obj.get("reasonModified"),
            "as_at_version_number": obj.get("asAtVersionNumber"),
            "staged_modification_id_modified": obj.get("stagedModificationIdModified"),
            "action": obj.get("action"),
            "attribute_name": obj.get("attributeName"),
            "previous_value": PropertyValue.from_dict(obj.get("previousValue")) if obj.get("previousValue") is not None else None,
            "new_value": PropertyValue.from_dict(obj.get("newValue")) if obj.get("newValue") is not None else None,
            "effective_range": EffectiveRange.from_dict(obj.get("effectiveRange")) if obj.get("effectiveRange") is not None else None
        })
        return _obj

ChangeIntervalWithOrderManagementDetail.update_forward_refs()
