# 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.reconciliation_left_right_address_key_pair import ReconciliationLeftRightAddressKeyPair
from lusid.models.valuation_request import ValuationRequest

class ValuationsReconciliationRequest(BaseModel):
    """
    Specification for the reconciliation request. Left and Right hand sides are constructed. Each consists of a valuation of a portfolio  using an aggregation request. The results of this can then be compared to each other. The difference, which is effectively a risk based  difference allows comparison of the effects of changing a recipe, valuation date, or (though it may or may not make logical sense) a portfolio.  For instance, one might look at the difference in risk caused by the addition of transaction to a portfolio, or through changing the valuation  methodology or system.  # noqa: E501
    """
    left: ValuationRequest
    right: ValuationRequest
    left_to_right_mapping: Optional[List[ReconciliationLeftRightAddressKeyPair]] = Field(default=None, description="The mapping from property keys requested by left aggregation to property keys on right hand side", alias="leftToRightMapping")
    preserve_keys: Optional[List[StrictStr]] = Field(default=None, description="List of keys to preserve (from rhs) in the diff. Used in conjunction with filtering/grouping.  If two values are equal, for a given key then the value is elided from the results. Setting it here  will preserve it (takes the values from the RHS and puts it into the line by line results).", alias="preserveKeys")
    __properties = ["left", "right", "leftToRightMapping", "preserveKeys"]

    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) -> ValuationsReconciliationRequest:
        """Create an instance of ValuationsReconciliationRequest 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 left
        if self.left:
            _dict['left'] = self.left.to_dict()
        # override the default output from pydantic by calling `to_dict()` of right
        if self.right:
            _dict['right'] = self.right.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in left_to_right_mapping (list)
        _items = []
        if self.left_to_right_mapping:
            for _item in self.left_to_right_mapping:
                if _item:
                    _items.append(_item.to_dict())
            _dict['leftToRightMapping'] = _items
        # set to None if left_to_right_mapping (nullable) is None
        # and __fields_set__ contains the field
        if self.left_to_right_mapping is None and "left_to_right_mapping" in self.__fields_set__:
            _dict['leftToRightMapping'] = None

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

        return _dict

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

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

        _obj = ValuationsReconciliationRequest.parse_obj({
            "left": ValuationRequest.from_dict(obj.get("left")) if obj.get("left") is not None else None,
            "right": ValuationRequest.from_dict(obj.get("right")) if obj.get("right") is not None else None,
            "left_to_right_mapping": [ReconciliationLeftRightAddressKeyPair.from_dict(_item) for _item in obj.get("leftToRightMapping")] if obj.get("leftToRightMapping") is not None else None,
            "preserve_keys": obj.get("preserveKeys")
        })
        return _obj

ValuationsReconciliationRequest.update_forward_refs()
