# coding: utf-8

"""
    Acre Platform User API

    # CORS CORS is implemented by all Acre API endpoints and only certain hostnames are allowed for each deployment of the API. If your use case requires calling the Acre User API from a browser, please contact Acre to arrange the appropriate configuration. # API Authentication The primary method of authentication for users of the Acre API is with the use of JSON Web Tokens (JWTs), which are suplemented by an application specific API Key. The API key must be provided through the `X-API-KEY` HTTP header and will be provided by your Acre Customer Success Manager. The JWT must be provided through a cookie with key of `authorization`. The JWT must be generated and signed as per the following section. # Generating JWTs JWT must either be generated by a third-party such as Azure ADB2C that has been configured for the appropriate service and/or user account, or alternatively can be generated locally and signed by an private key for which the public key has been made available to Acre via a JWKS URL. In addition to being signed by your private key, the JWT will also need to contain at a minimum:  * An issuer `iss`, which must be a valid URI previously agreed with Acre.  * A subject `sub`, which must be a unique identifier for the user and/or service account previously agreed with Acre.  * An expiry time `exp` which must not be more than four hours in the future.  * A not before time `nbf` which must be in the past, but not greater than six hours in the past.  The JWT should be signed using RS256.

    The version of the OpenAPI document: 1.0
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


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

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from acre_api.models.cdm_company_class import CdmCompanyClass
from acre_api.models.cdm_external import CdmExternal
from acre_api.models.cdm_mortgage_arrears_summary import CdmMortgageArrearsSummary
from acre_api.models.cdm_mortgage_calculated_values import CdmMortgageCalculatedValues
from acre_api.models.cdm_mortgage_panel_limit_reason import CdmMortgagePanelLimitReason
from acre_api.models.cdm_mortgage_status import CdmMortgageStatus
from acre_api.models.cdm_mortgage_term_unit import CdmMortgageTermUnit
from acre_api.models.cdm_payment_history import CdmPaymentHistory
from acre_api.models.cdm_property_id_and_version import CdmPropertyIDAndVersion
from acre_api.models.cdm_run_source_response import CdmRunSourceResponse
from acre_api.models.cdm_supplementary_information import CdmSupplementaryInformation
from acre_api.models.client_outstanding_debt_repayment_status_type import ClientOutstandingDebtRepaymentStatusType
from acre_api.models.mortgage_dip_status_type import MortgageDipStatusType
from acre_api.models.mortgage_fees_to_be_added import MortgageFeesToBeAdded
from acre_api.models.mortgage_loan_purpose import MortgageLoanPurpose
from acre_api.models.mortgage_valuation_type import MortgageValuationType
from typing import Optional, Set
from typing_extensions import Self

class CompleteDetailsOfTheMortgageToBeReplacedRequired(BaseModel):
    """
    CompleteDetailsOfTheMortgageToBeReplacedRequired
    """ # noqa: E501
    created_at: Optional[StrictStr] = Field(default=None, description="Creation date (RFC3339) of the mortgage. Populated automatically; cannot be set.")
    version: Optional[StrictInt] = Field(default=None, description="Identifier of the version of mortgage. Populated automatically; cannot be set.")
    version_created_at: Optional[StrictStr] = Field(default=None, description="Creation date (RFC3339) of the mortgage version. Populated automatically; cannot be set.")
    property_secured_ids: Optional[List[StrictStr]] = Field(default=None, description="Property secured IDs.")
    mortgage_product_id: Optional[StrictStr] = Field(default=None, description="Product ID of the mortgage. This field cannot be edited directly and must be updated via the mortgage/product APIs.")
    mortgage_product_source_rank: Optional[StrictInt] = Field(default=None, description="The ranking in the sourcing result (first element is rank 0). This field can only be set directly if it hasn't been set before, otherwise is set by the oracle when adding a product to a mortgage.")
    client_ids: Optional[List[StrictStr]] = Field(default=None, description="Clients associated with the mortgage (borrowers).")
    case_ids: Optional[List[StrictStr]] = Field(default=None, description="Cases associated with this mortgage.  This field cannot be edited directly and must be updated via the mortgage/case APIs.")
    status: Optional[CdmMortgageStatus] = CdmMortgageStatus.INVALID_STATUS
    lender_proposed: Optional[StrictBool] = Field(default=None, description="Lender_proposed Boolean on mortgages that is set when the Status is set to Lender_proposed.  If the status then changes to SELECTED or CURRENT we can still see the origin")
    outstanding_balance: Optional[StrictStr] = Field(default=None, description="Outstanding balance on the applicant’s existing mortgage (in pence, not GBP).")
    current_monthly_payment: Optional[StrictStr] = Field(default=None, description="Current monthly payment on the applicant’s existing mortgage (in pence, not GBP).")
    early_repayment_charge_amount: Optional[StrictStr] = Field(default=None, description="Specifies the amount of any early repayment charge on the existing mortgage. When a value is provided, it will be factored into any residential mortgage product true cost calculation when performing a remortgage search (in pence, not GBP).")
    mortgage_end_date: Optional[StrictStr] = Field(default=None, description="Specifies the date the mortgage will end (YYYY-MM-DD). **IMPORTANT:** This field cannot be updated and is populated automatically.")
    loan_benefits_all_applicants: Optional[StrictBool] = Field(default=None, description="Flag identifying whether this loan benefits all applicants.")
    additional_loan_amount: Optional[StrictStr] = Field(default=None, description="The amount of additional funds required (in pence, not GBP).")
    additional_loan_purposes: Optional[List[MortgageLoanPurpose]] = Field(default=None, description="[DebtConsolidation; Business; OtherProperty; HomeImprovements; Lifestyle; Other; Staircasing]")
    additional_loan_reason_description: Optional[StrictStr] = Field(default=None, description="Additional details on the reason for the additional funds.")
    mortgage_account_number: Optional[StrictStr] = Field(default=None, description="The account number of the mortgage.")
    mortgage_start_date: Optional[StrictStr] = Field(default=None, description="The start date of the mortgage (YYYY-MM-DD).  DEPRECATED: The redemption date of the mortgage (YYYY-MM-DD). string mortgage_redemption_date = 18;  DEPRECATED: The date the property was purchased (YYYY-MM-DD). string property_purchase_date = 19;")
    mortgage_repaid_date: Optional[StrictStr] = Field(default=None, description="The date the mortgage was repaid (YYYY-MM-DD).")
    will_be_repaid_by_mortgage_id: Optional[StrictStr] = Field(default=None, description="If this mortgage will be repaid by a proposed mortgage. Not yet implemented.")
    repayment_amount: Optional[StrictStr] = Field(default=None, description="The amount of the mortgage to be paid on a capital & interest basis (in pence, not GBP).")
    interest_only_amount: Optional[StrictStr] = None
    monthly_payment: Optional[StrictStr] = Field(default=None, description="The monthly payment amount (in pence, not GBP).")
    revert_monthly_payment: Optional[StrictStr] = Field(default=None, description="The monthly payment amount in the reversionary period (in pence, not GBP).")
    requires_offset_facility: Optional[StrictBool] = Field(default=None, description="Flag indicating whether the applicants require the offset facility on this mortgage product.")
    loan_total_fees_added_to_loan: Optional[StrictStr] = Field(default=None, description="The total amount of all fees added to the loan (in pence, not GBP).")
    loan_total_premiums_or_insurance_added_to_loan: Optional[StrictStr] = Field(default=None, description="The total amount of all premiums or insurance fees added to the loan (in pence, not GBP).")
    loan_completion_date: Optional[StrictStr] = Field(default=None, description="The completion date of the mortgage (YYYY-MM-DD).")
    loan_contract_exchange_date: Optional[StrictStr] = Field(default=None, description="The contract exchange date (YYYY-MM-DD).")
    repayment_vehicle_provider_name: Optional[StrictStr] = Field(default=None, description="The name of the provider of the repayment vehicle.")
    repayment_vehicle_reference_number: Optional[StrictStr] = Field(default=None, description="The reference number applicable to the repayment vehicle.")
    repayment_vehicle_current_value_of_vehicle: Optional[StrictStr] = Field(default=None, description="The current value of the vehicle (in pence, not GBP).")
    repayment_vehicle_monthly_contribution: Optional[StrictStr] = Field(default=None, description="The monthly contribution amount to the vehicle (in pence, not GBP).")
    repayment_vehicle_declared_maturity_amount: Optional[StrictStr] = Field(default=None, description="The value of the vehicle on maturity (in pence, not GBP).")
    repayment_vehicle_start_date: Optional[StrictStr] = Field(default=None, description="The start date of the vehicle (YYYY-MM-DD).")
    repayment_vehicle_maturity_date: Optional[StrictStr] = Field(default=None, description="The maturity date of the vehicle (YYYY-MM-DD).")
    repayment_vehicle_additional_information: Optional[StrictStr] = Field(default=None, description="Additional information about the vehicle.")
    mortgage_product_select_reason: Optional[StrictStr] = Field(default=None, description="Reason for selecting the mortgage product. This field can only be set directly if it hasn't been set before, otherwise is set by the oracle when adding a product to a mortgage.")
    mortgage_amount: Optional[StrictStr] = Field(default=None, description="Amount of mortgage (in pence, not GBP).")
    term: Optional[StrictInt] = Field(default=None, description="Mortgage term to be used in sourcing. This field works in conjunction with the TermUnit field.")
    term_unit: Optional[CdmMortgageTermUnit] = CdmMortgageTermUnit.INVALID_TERM_UNIT
    property_value: Optional[StrictInt] = Field(default=None, description="Property value to be used in sourcing.")
    esis_document_id: Optional[StrictStr] = Field(default=None, description="The most recently generated ESIS document for this mortgage.")
    calculated_net_proc_fee: Optional[StrictStr] = Field(default=None, description="Calculated Net Procuration Fee for this product that will be paid to the Brokerage Firm (in pence, not GBP). IMPORTANT: This field is disabled for now.")
    calculated_gross_proc_fee: Optional[StrictStr] = Field(default=None, description="Calculated Net Procuration Fee (i.e. total for SBG + Brokerage Firm) (in pence, not GBP).")
    offer_letter_document_id: Optional[StrictStr] = Field(default=None, description="Offer letter associated with this mortgage, if any.")
    application_letter_document_id: Optional[StrictStr] = Field(default=None, description="Application letter associated with this mortgage, if any.")
    eor_document_ids: Optional[List[StrictStr]] = Field(default=None, description="Evidence Of Research document IDs associated with the mortgage, if any.  DEPRECATED: The ids of all borrowers on the mortgage. Linked to active client_acre_id. Same as client_ids.  repeated string borrower_client_ids = 51;")
    guarantor_client_ids: Optional[List[StrictStr]] = Field(default=None, description="The ids of all guarantors on the mortgage.")
    first_or_second_charge: Optional[StrictInt] = Field(default=None, description="Order of charge.")
    application_date: Optional[StrictStr] = Field(default=None, description="When the mortgage application was submitted (YYYY-MM-DD).")
    source_response: Optional[CdmRunSourceResponse] = None
    initial_rate_end_date: Optional[StrictStr] = Field(default=None, description="Calculated End date of the first mortgage rate (YYYY-MM-DD), **immutable**.")
    fees_to_be_added: Optional[List[MortgageFeesToBeAdded]] = Field(default=None, description="The type of mortgage fees to be added.")
    calculated_values: Optional[CdmMortgageCalculatedValues] = None
    modified_at: Optional[StrictStr] = None
    raw_results_reference: Optional[StrictStr] = Field(default=None, description="A reference to the raw response from sourcing providers other than 27tec. If there is more than one reference, this should be a comma separated list of references.")
    initial_property_versions: Optional[List[CdmPropertyIDAndVersion]] = Field(default=None, description="List of property IDs and their version when they were added to the mortgage, if mortgage was in one the following statuses PROPOSED, SELECTED, or LENDER_PROPOSED.")
    completion_property_versions: Optional[List[CdmPropertyIDAndVersion]] = None
    redemption_property_versions: Optional[List[CdmPropertyIDAndVersion]] = None
    selected_mortgage_club_code: Optional[StrictStr] = Field(default=None, description="The selected mortgage club code from the mortgage product.")
    assumes_continuing: Optional[List[StrictStr]] = Field(default=None, description="Contains the CURRENT mortgages' ids that will be continuing in combination with this mortgage.")
    payment_history: Optional[List[CdmPaymentHistory]] = Field(default=None, description="History of repayments.")
    payment_status_summary: Optional[ClientOutstandingDebtRepaymentStatusType] = ClientOutstandingDebtRepaymentStatusType.INVALID_STATUS
    merged_mortgages: Optional[List[StrictStr]] = Field(default=None, description="Mortgages this has been merged with to deduplicate.")
    acre_dip_id: Optional[StrictStr] = Field(default=None, description="A unique id (GUID) for the last dip result related to this mortgage.")
    provider_dip_reference: Optional[StrictStr] = Field(default=None, description="The providers reference for the last dip result related to this mortgage.")
    provider_application_reference: Optional[StrictStr] = Field(default=None, description="The providers reference for an electronic application.")
    dip_status: Optional[MortgageDipStatusType] = MortgageDipStatusType.INVALID_DIP_STATUS
    dip_amount: Optional[StrictStr] = Field(default=None, description="The mortgage_amount used for the last DIP (in pence).")
    mortgage_panel_limit_reason: Optional[CdmMortgagePanelLimitReason] = None
    manual_product: Optional[StrictBool] = Field(default=None, description="Allow the FE to easily identify manually sourced products.")
    has_arrears: Optional[StrictBool] = Field(default=None, description="Whether the mortgage is in arrears.")
    arrears_summary: Optional[CdmMortgageArrearsSummary] = None
    original_term: Optional[StrictInt] = Field(default=None, description="The agreed term of the loan. Mortgage term to be used in sourcing. This field works in conjunction with the OriginalTermUnit field.")
    original_term_unit: Optional[CdmMortgageTermUnit] = CdmMortgageTermUnit.INVALID_TERM_UNIT
    valuation_type: Optional[MortgageValuationType] = MortgageValuationType.INVALID_VALUATION_TYPE
    external: Optional[List[CdmExternal]] = Field(default=None, description="Identifiers for the mortgage in third-party systems.")
    outstanding_balance_date: Optional[StrictStr] = Field(default=None, description="Specifies the date the mortgage outstanding balance was correct (YYYY-MM-DD).")
    company_class: Optional[CdmCompanyClass] = CdmCompanyClass.INVALID_COMPANY_CLASS
    supplementary_information: Optional[CdmSupplementaryInformation] = CdmSupplementaryInformation.INVALID_SUPPLEMENTARY_INFORMATION
    offer_expiry_date: Optional[StrictStr] = Field(default=None, description="Date that the mortgage offer expires (YYYY-MM-DD).")
    __properties: ClassVar[List[str]] = ["created_at", "version", "version_created_at", "property_secured_ids", "mortgage_product_id", "mortgage_product_source_rank", "client_ids", "case_ids", "status", "lender_proposed", "outstanding_balance", "current_monthly_payment", "early_repayment_charge_amount", "mortgage_end_date", "loan_benefits_all_applicants", "additional_loan_amount", "additional_loan_purposes", "additional_loan_reason_description", "mortgage_account_number", "mortgage_start_date", "mortgage_repaid_date", "will_be_repaid_by_mortgage_id", "repayment_amount", "interest_only_amount", "monthly_payment", "revert_monthly_payment", "requires_offset_facility", "loan_total_fees_added_to_loan", "loan_total_premiums_or_insurance_added_to_loan", "loan_completion_date", "loan_contract_exchange_date", "repayment_vehicle_provider_name", "repayment_vehicle_reference_number", "repayment_vehicle_current_value_of_vehicle", "repayment_vehicle_monthly_contribution", "repayment_vehicle_declared_maturity_amount", "repayment_vehicle_start_date", "repayment_vehicle_maturity_date", "repayment_vehicle_additional_information", "mortgage_product_select_reason", "mortgage_amount", "term", "term_unit", "property_value", "esis_document_id", "calculated_net_proc_fee", "calculated_gross_proc_fee", "offer_letter_document_id", "application_letter_document_id", "eor_document_ids", "guarantor_client_ids", "first_or_second_charge", "application_date", "source_response", "initial_rate_end_date", "fees_to_be_added", "calculated_values", "modified_at", "raw_results_reference", "initial_property_versions", "completion_property_versions", "redemption_property_versions", "selected_mortgage_club_code", "assumes_continuing", "payment_history", "payment_status_summary", "merged_mortgages", "acre_dip_id", "provider_dip_reference", "provider_application_reference", "dip_status", "dip_amount", "mortgage_panel_limit_reason", "manual_product", "has_arrears", "arrears_summary", "original_term", "original_term_unit", "valuation_type", "external", "outstanding_balance_date", "company_class", "supplementary_information", "offer_expiry_date"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


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

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

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

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of source_response
        if self.source_response:
            _dict['source_response'] = self.source_response.to_dict()
        # override the default output from pydantic by calling `to_dict()` of calculated_values
        if self.calculated_values:
            _dict['calculated_values'] = self.calculated_values.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in initial_property_versions (list)
        _items = []
        if self.initial_property_versions:
            for _item_initial_property_versions in self.initial_property_versions:
                if _item_initial_property_versions:
                    _items.append(_item_initial_property_versions.to_dict())
            _dict['initial_property_versions'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in completion_property_versions (list)
        _items = []
        if self.completion_property_versions:
            for _item_completion_property_versions in self.completion_property_versions:
                if _item_completion_property_versions:
                    _items.append(_item_completion_property_versions.to_dict())
            _dict['completion_property_versions'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in redemption_property_versions (list)
        _items = []
        if self.redemption_property_versions:
            for _item_redemption_property_versions in self.redemption_property_versions:
                if _item_redemption_property_versions:
                    _items.append(_item_redemption_property_versions.to_dict())
            _dict['redemption_property_versions'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in payment_history (list)
        _items = []
        if self.payment_history:
            for _item_payment_history in self.payment_history:
                if _item_payment_history:
                    _items.append(_item_payment_history.to_dict())
            _dict['payment_history'] = _items
        # override the default output from pydantic by calling `to_dict()` of mortgage_panel_limit_reason
        if self.mortgage_panel_limit_reason:
            _dict['mortgage_panel_limit_reason'] = self.mortgage_panel_limit_reason.to_dict()
        # override the default output from pydantic by calling `to_dict()` of arrears_summary
        if self.arrears_summary:
            _dict['arrears_summary'] = self.arrears_summary.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in external (list)
        _items = []
        if self.external:
            for _item_external in self.external:
                if _item_external:
                    _items.append(_item_external.to_dict())
            _dict['external'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of CompleteDetailsOfTheMortgageToBeReplacedRequired from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "created_at": obj.get("created_at"),
            "version": obj.get("version"),
            "version_created_at": obj.get("version_created_at"),
            "property_secured_ids": obj.get("property_secured_ids"),
            "mortgage_product_id": obj.get("mortgage_product_id"),
            "mortgage_product_source_rank": obj.get("mortgage_product_source_rank"),
            "client_ids": obj.get("client_ids"),
            "case_ids": obj.get("case_ids"),
            "status": obj.get("status") if obj.get("status") is not None else CdmMortgageStatus.INVALID_STATUS,
            "lender_proposed": obj.get("lender_proposed"),
            "outstanding_balance": obj.get("outstanding_balance"),
            "current_monthly_payment": obj.get("current_monthly_payment"),
            "early_repayment_charge_amount": obj.get("early_repayment_charge_amount"),
            "mortgage_end_date": obj.get("mortgage_end_date"),
            "loan_benefits_all_applicants": obj.get("loan_benefits_all_applicants"),
            "additional_loan_amount": obj.get("additional_loan_amount"),
            "additional_loan_purposes": obj.get("additional_loan_purposes"),
            "additional_loan_reason_description": obj.get("additional_loan_reason_description"),
            "mortgage_account_number": obj.get("mortgage_account_number"),
            "mortgage_start_date": obj.get("mortgage_start_date"),
            "mortgage_repaid_date": obj.get("mortgage_repaid_date"),
            "will_be_repaid_by_mortgage_id": obj.get("will_be_repaid_by_mortgage_id"),
            "repayment_amount": obj.get("repayment_amount"),
            "interest_only_amount": obj.get("interest_only_amount"),
            "monthly_payment": obj.get("monthly_payment"),
            "revert_monthly_payment": obj.get("revert_monthly_payment"),
            "requires_offset_facility": obj.get("requires_offset_facility"),
            "loan_total_fees_added_to_loan": obj.get("loan_total_fees_added_to_loan"),
            "loan_total_premiums_or_insurance_added_to_loan": obj.get("loan_total_premiums_or_insurance_added_to_loan"),
            "loan_completion_date": obj.get("loan_completion_date"),
            "loan_contract_exchange_date": obj.get("loan_contract_exchange_date"),
            "repayment_vehicle_provider_name": obj.get("repayment_vehicle_provider_name"),
            "repayment_vehicle_reference_number": obj.get("repayment_vehicle_reference_number"),
            "repayment_vehicle_current_value_of_vehicle": obj.get("repayment_vehicle_current_value_of_vehicle"),
            "repayment_vehicle_monthly_contribution": obj.get("repayment_vehicle_monthly_contribution"),
            "repayment_vehicle_declared_maturity_amount": obj.get("repayment_vehicle_declared_maturity_amount"),
            "repayment_vehicle_start_date": obj.get("repayment_vehicle_start_date"),
            "repayment_vehicle_maturity_date": obj.get("repayment_vehicle_maturity_date"),
            "repayment_vehicle_additional_information": obj.get("repayment_vehicle_additional_information"),
            "mortgage_product_select_reason": obj.get("mortgage_product_select_reason"),
            "mortgage_amount": obj.get("mortgage_amount"),
            "term": obj.get("term"),
            "term_unit": obj.get("term_unit") if obj.get("term_unit") is not None else CdmMortgageTermUnit.INVALID_TERM_UNIT,
            "property_value": obj.get("property_value"),
            "esis_document_id": obj.get("esis_document_id"),
            "calculated_net_proc_fee": obj.get("calculated_net_proc_fee"),
            "calculated_gross_proc_fee": obj.get("calculated_gross_proc_fee"),
            "offer_letter_document_id": obj.get("offer_letter_document_id"),
            "application_letter_document_id": obj.get("application_letter_document_id"),
            "eor_document_ids": obj.get("eor_document_ids"),
            "guarantor_client_ids": obj.get("guarantor_client_ids"),
            "first_or_second_charge": obj.get("first_or_second_charge"),
            "application_date": obj.get("application_date"),
            "source_response": CdmRunSourceResponse.from_dict(obj["source_response"]) if obj.get("source_response") is not None else None,
            "initial_rate_end_date": obj.get("initial_rate_end_date"),
            "fees_to_be_added": obj.get("fees_to_be_added"),
            "calculated_values": CdmMortgageCalculatedValues.from_dict(obj["calculated_values"]) if obj.get("calculated_values") is not None else None,
            "modified_at": obj.get("modified_at"),
            "raw_results_reference": obj.get("raw_results_reference"),
            "initial_property_versions": [CdmPropertyIDAndVersion.from_dict(_item) for _item in obj["initial_property_versions"]] if obj.get("initial_property_versions") is not None else None,
            "completion_property_versions": [CdmPropertyIDAndVersion.from_dict(_item) for _item in obj["completion_property_versions"]] if obj.get("completion_property_versions") is not None else None,
            "redemption_property_versions": [CdmPropertyIDAndVersion.from_dict(_item) for _item in obj["redemption_property_versions"]] if obj.get("redemption_property_versions") is not None else None,
            "selected_mortgage_club_code": obj.get("selected_mortgage_club_code"),
            "assumes_continuing": obj.get("assumes_continuing"),
            "payment_history": [CdmPaymentHistory.from_dict(_item) for _item in obj["payment_history"]] if obj.get("payment_history") is not None else None,
            "payment_status_summary": obj.get("payment_status_summary") if obj.get("payment_status_summary") is not None else ClientOutstandingDebtRepaymentStatusType.INVALID_STATUS,
            "merged_mortgages": obj.get("merged_mortgages"),
            "acre_dip_id": obj.get("acre_dip_id"),
            "provider_dip_reference": obj.get("provider_dip_reference"),
            "provider_application_reference": obj.get("provider_application_reference"),
            "dip_status": obj.get("dip_status") if obj.get("dip_status") is not None else MortgageDipStatusType.INVALID_DIP_STATUS,
            "dip_amount": obj.get("dip_amount"),
            "mortgage_panel_limit_reason": CdmMortgagePanelLimitReason.from_dict(obj["mortgage_panel_limit_reason"]) if obj.get("mortgage_panel_limit_reason") is not None else None,
            "manual_product": obj.get("manual_product"),
            "has_arrears": obj.get("has_arrears"),
            "arrears_summary": CdmMortgageArrearsSummary.from_dict(obj["arrears_summary"]) if obj.get("arrears_summary") is not None else None,
            "original_term": obj.get("original_term"),
            "original_term_unit": obj.get("original_term_unit") if obj.get("original_term_unit") is not None else CdmMortgageTermUnit.INVALID_TERM_UNIT,
            "valuation_type": obj.get("valuation_type") if obj.get("valuation_type") is not None else MortgageValuationType.INVALID_VALUATION_TYPE,
            "external": [CdmExternal.from_dict(_item) for _item in obj["external"]] if obj.get("external") is not None else None,
            "outstanding_balance_date": obj.get("outstanding_balance_date"),
            "company_class": obj.get("company_class") if obj.get("company_class") is not None else CdmCompanyClass.INVALID_COMPANY_CLASS,
            "supplementary_information": obj.get("supplementary_information") if obj.get("supplementary_information") is not None else CdmSupplementaryInformation.INVALID_SUPPLEMENTARY_INFORMATION,
            "offer_expiry_date": obj.get("offer_expiry_date")
        })
        return _obj


