# 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.aggregated_transactions_request import AggregatedTransactionsRequest
from lusid.models.reconciliation_left_right_address_key_pair import ReconciliationLeftRightAddressKeyPair
from lusid.models.reconciliation_rule import ReconciliationRule

class TransactionReconciliationRequestV2(BaseModel):
    """
    Specification for the reconciliation request. Left and Right hand sides are constructed. Each consists of transactions from a portfolio  The results of this can then be compared to each other.  # noqa: E501
    """
    left: AggregatedTransactionsRequest
    right: AggregatedTransactionsRequest
    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")
    comparison_rules: Optional[List[ReconciliationRule]] = Field(default=None, description="The set of rules to be used in comparing values. These are the rules that determine what constitutes a match.  The simplest is obviously an exact one-for-one comparison, but tolerances on numerical or date time values and  case-insensitive string comparison are supported amongst other types.", alias="comparisonRules")
    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", "comparisonRules", "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) -> TransactionReconciliationRequestV2:
        """Create an instance of TransactionReconciliationRequestV2 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
        # override the default output from pydantic by calling `to_dict()` of each item in comparison_rules (list)
        _items = []
        if self.comparison_rules:
            for _item in self.comparison_rules:
                if _item:
                    _items.append(_item.to_dict())
            _dict['comparisonRules'] = _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 comparison_rules (nullable) is None
        # and __fields_set__ contains the field
        if self.comparison_rules is None and "comparison_rules" in self.__fields_set__:
            _dict['comparisonRules'] = 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) -> TransactionReconciliationRequestV2:
        """Create an instance of TransactionReconciliationRequestV2 from a dict"""
        if obj is None:
            return None

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

        _obj = TransactionReconciliationRequestV2.parse_obj({
            "left": AggregatedTransactionsRequest.from_dict(obj.get("left")) if obj.get("left") is not None else None,
            "right": AggregatedTransactionsRequest.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,
            "comparison_rules": [ReconciliationRule.from_dict(_item) for _item in obj.get("comparisonRules")] if obj.get("comparisonRules") is not None else None,
            "preserve_keys": obj.get("preserveKeys")
        })
        return _obj

TransactionReconciliationRequestV2.update_forward_refs()
