# coding: utf-8

"""
    Marqeta Core API

    Simplified management of your payment programs  # noqa: E501

    The version of the OpenAPI document: 3.0.0
    Contact: dev@swadesh.co
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""


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

from datetime import datetime
from typing import List, Optional, Union
from pydantic import BaseModel, Field, StrictBool, StrictFloat, StrictInt, StrictStr, conlist, constr, validator
from marqeta_client.models.card_acceptor_model import CardAcceptorModel
from marqeta_client.models.money_model import MoneyModel
from marqeta_client.models.network_fee_model import NetworkFeeModel
from marqeta_client.models.network_metadata import NetworkMetadata
from marqeta_client.models.original_data_elements import OriginalDataElements
from marqeta_client.models.webhook import Webhook

class AdvancedClearingRequestModel(BaseModel):
    """
    AdvancedClearingRequestModel
    """
    network_fees: Optional[conlist(NetworkFeeModel)] = None
    webhook: Optional[Webhook] = None
    mid: Optional[constr(strict=True, max_length=50, min_length=1)] = None
    amount: Union[StrictFloat, StrictInt] = ...
    source_amount: Union[StrictFloat, StrictInt] = ...
    reconciliation_amount: Union[StrictFloat, StrictInt] = ...
    replacement_amount: Optional[Union[StrictFloat, StrictInt]] = None
    cardholder_billing_amount: Optional[Union[StrictFloat, StrictInt]] = None
    cashback: Optional[Union[StrictFloat, StrictInt]] = None
    local_transaction_amount: Optional[Union[StrictFloat, StrictInt]] = None
    local_currency_code: Optional[StrictStr] = None
    settlement_amount: Optional[Union[StrictFloat, StrictInt]] = None
    settlement_currency_code: Optional[StrictStr] = None
    settlement_conversion_rate: Optional[Union[StrictFloat, StrictInt]] = None
    cardholder_billing_conversion_rate: Optional[Union[StrictFloat, StrictInt]] = None
    cardholder_billing_currency: Optional[StrictStr] = None
    card_token: constr(strict=True, max_length=36, min_length=1) = ...
    card_hash: StrictStr = ...
    acquirer_reference_id: Optional[constr(strict=True, max_length=23, min_length=1)] = None
    rrn: Optional[constr(strict=True, max_length=16, min_length=1)] = None
    stan: Optional[constr(strict=True, max_length=12, min_length=1)] = None
    processing_code: Optional[constr(strict=True, max_length=2, min_length=2)] = None
    acquirer_fee: Optional[MoneyModel] = None
    issuer_fee: Optional[MoneyModel] = None
    function_code: Optional[constr(strict=True, max_length=3, min_length=3)] = None
    reason_code: Optional[constr(strict=True, max_length=4, min_length=4)] = None
    approval_code: Optional[constr(strict=True, max_length=6, min_length=1)] = None
    transaction_date: Optional[datetime] = Field(None, description="yyyy-MM-dd, yyyy-MM-ddThh:mm:ssZ")
    local_transaction_date: Optional[datetime] = Field(None, description="yyyy-MM-dd, yyyy-MM-ddThh:mm:ssZ")
    settlement_date: Optional[datetime] = Field(None, description="yyyy-MM-dd, yyyy-MM-ddThh:mm:ssZ")
    network_reference_id: Optional[constr(strict=True, max_length=16, min_length=1)] = None
    find_original_window_days: Optional[StrictInt] = None
    batch_number: Optional[StrictStr] = None
    batch_file_name: Optional[StrictStr] = None
    sequence_number: Optional[StrictStr] = None
    multi_clearing_count: Optional[StrictStr] = None
    network: Optional[StrictStr] = None
    sub_network: Optional[StrictStr] = Field(None, description="Defaults to VISANET if network is VISA")
    card_acceptor: Optional[CardAcceptorModel] = None
    currency_code: constr(strict=True, max_length=3, min_length=3) = ...
    original_data_elements: Optional[OriginalDataElements] = None
    preceding_related_transaction_token: Optional[StrictStr] = None
    send_expiration_date: Optional[StrictBool] = False
    simulate_batch_for_clearing_record_hash: Optional[StrictBool] = None
    isa_indicator: Optional[StrictStr] = None
    token_pan: Optional[constr(strict=True, max_length=16, min_length=1)] = None
    payment_channel_indicator: Optional[StrictStr] = None
    is_installment: Optional[StrictBool] = None
    is_recurring: Optional[StrictBool] = None
    network_metadata: Optional[NetworkMetadata] = None
    authorization_source_code: Optional[StrictStr] = None
    interchange_rate_descriptor: Optional[StrictStr] = None
    acquirer_institution_id_code: Optional[constr(strict=True, max_length=11, min_length=1)] = None
    terminal_id: Optional[constr(strict=True, max_length=8, min_length=1)] = None
    mti: Optional[StrictStr] = None
    clearing_file_name: Optional[StrictStr] = None
    __properties = ["network_fees", "webhook", "mid", "amount", "source_amount", "reconciliation_amount", "replacement_amount", "cardholder_billing_amount", "cashback", "local_transaction_amount", "local_currency_code", "settlement_amount", "settlement_currency_code", "settlement_conversion_rate", "cardholder_billing_conversion_rate", "cardholder_billing_currency", "card_token", "card_hash", "acquirer_reference_id", "rrn", "stan", "processing_code", "acquirer_fee", "issuer_fee", "function_code", "reason_code", "approval_code", "transaction_date", "local_transaction_date", "settlement_date", "network_reference_id", "find_original_window_days", "batch_number", "batch_file_name", "sequence_number", "multi_clearing_count", "network", "sub_network", "card_acceptor", "currency_code", "original_data_elements", "preceding_related_transaction_token", "send_expiration_date", "simulate_batch_for_clearing_record_hash", "isa_indicator", "token_pan", "payment_channel_indicator", "is_installment", "is_recurring", "network_metadata", "authorization_source_code", "interchange_rate_descriptor", "acquirer_institution_id_code", "terminal_id", "mti", "clearing_file_name"]

    @validator('network')
    def network_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ('DISCOVER', 'MASTERCARD', 'PULSE', 'VISA'):
            raise ValueError("must be one of enum values ('DISCOVER', 'MASTERCARD', 'PULSE', 'VISA')")
        return v

    @validator('sub_network')
    def sub_network_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ('VISANET', 'VISANETDEBIT', 'VISAINTERLINK', 'VISAPLUS'):
            raise ValueError("must be one of enum values ('VISANET', 'VISANETDEBIT', 'VISAINTERLINK', 'VISAPLUS')")
        return v

    @validator('isa_indicator')
    def isa_indicator_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ('SINGLE_CURRENCY', 'MULTI_CURRENCY', 'REBATE_CANCELLED', 'MULTI_CURRENCY_NON_US_COUNTRIES', 'SINGLE_CURRENCY_PAID_BY_ISSUER', 'NO_CHARGE_ASSESSED'):
            raise ValueError("must be one of enum values ('SINGLE_CURRENCY', 'MULTI_CURRENCY', 'REBATE_CANCELLED', 'MULTI_CURRENCY_NON_US_COUNTRIES', 'SINGLE_CURRENCY_PAID_BY_ISSUER', 'NO_CHARGE_ASSESSED')")
        return v

    @validator('mti')
    def mti_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ('0220', '0420'):
            raise ValueError("must be one of enum values ('0220', '0420')")
        return v

    class Config:
        allow_population_by_field_name = True
        validate_assignment = True

    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) -> AdvancedClearingRequestModel:
        """Create an instance of AdvancedClearingRequestModel 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 each item in network_fees (list)
        _items = []
        if self.network_fees:
            for _item in self.network_fees:
                if _item:
                    _items.append(_item.to_dict())
            _dict['network_fees'] = _items
        # override the default output from pydantic by calling `to_dict()` of webhook
        if self.webhook:
            _dict['webhook'] = self.webhook.to_dict()
        # override the default output from pydantic by calling `to_dict()` of acquirer_fee
        if self.acquirer_fee:
            _dict['acquirer_fee'] = self.acquirer_fee.to_dict()
        # override the default output from pydantic by calling `to_dict()` of issuer_fee
        if self.issuer_fee:
            _dict['issuer_fee'] = self.issuer_fee.to_dict()
        # override the default output from pydantic by calling `to_dict()` of card_acceptor
        if self.card_acceptor:
            _dict['card_acceptor'] = self.card_acceptor.to_dict()
        # override the default output from pydantic by calling `to_dict()` of original_data_elements
        if self.original_data_elements:
            _dict['original_data_elements'] = self.original_data_elements.to_dict()
        # override the default output from pydantic by calling `to_dict()` of network_metadata
        if self.network_metadata:
            _dict['network_metadata'] = self.network_metadata.to_dict()
        return _dict

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

        if type(obj) is not dict:
            return AdvancedClearingRequestModel.parse_obj(obj)

        _obj = AdvancedClearingRequestModel.parse_obj({
            "network_fees": [NetworkFeeModel.from_dict(_item) for _item in obj.get("network_fees")] if obj.get("network_fees") is not None else None,
            "webhook": Webhook.from_dict(obj.get("webhook")) if obj.get("webhook") is not None else None,
            "mid": obj.get("mid"),
            "amount": obj.get("amount"),
            "source_amount": obj.get("source_amount"),
            "reconciliation_amount": obj.get("reconciliation_amount"),
            "replacement_amount": obj.get("replacement_amount"),
            "cardholder_billing_amount": obj.get("cardholder_billing_amount"),
            "cashback": obj.get("cashback"),
            "local_transaction_amount": obj.get("local_transaction_amount"),
            "local_currency_code": obj.get("local_currency_code"),
            "settlement_amount": obj.get("settlement_amount"),
            "settlement_currency_code": obj.get("settlement_currency_code"),
            "settlement_conversion_rate": obj.get("settlement_conversion_rate"),
            "cardholder_billing_conversion_rate": obj.get("cardholder_billing_conversion_rate"),
            "cardholder_billing_currency": obj.get("cardholder_billing_currency"),
            "card_token": obj.get("card_token"),
            "card_hash": obj.get("card_hash"),
            "acquirer_reference_id": obj.get("acquirer_reference_id"),
            "rrn": obj.get("rrn"),
            "stan": obj.get("stan"),
            "processing_code": obj.get("processing_code"),
            "acquirer_fee": MoneyModel.from_dict(obj.get("acquirer_fee")) if obj.get("acquirer_fee") is not None else None,
            "issuer_fee": MoneyModel.from_dict(obj.get("issuer_fee")) if obj.get("issuer_fee") is not None else None,
            "function_code": obj.get("function_code"),
            "reason_code": obj.get("reason_code"),
            "approval_code": obj.get("approval_code"),
            "transaction_date": obj.get("transaction_date"),
            "local_transaction_date": obj.get("local_transaction_date"),
            "settlement_date": obj.get("settlement_date"),
            "network_reference_id": obj.get("network_reference_id"),
            "find_original_window_days": obj.get("find_original_window_days"),
            "batch_number": obj.get("batch_number"),
            "batch_file_name": obj.get("batch_file_name"),
            "sequence_number": obj.get("sequence_number"),
            "multi_clearing_count": obj.get("multi_clearing_count"),
            "network": obj.get("network"),
            "sub_network": obj.get("sub_network"),
            "card_acceptor": CardAcceptorModel.from_dict(obj.get("card_acceptor")) if obj.get("card_acceptor") is not None else None,
            "currency_code": obj.get("currency_code"),
            "original_data_elements": OriginalDataElements.from_dict(obj.get("original_data_elements")) if obj.get("original_data_elements") is not None else None,
            "preceding_related_transaction_token": obj.get("preceding_related_transaction_token"),
            "send_expiration_date": obj.get("send_expiration_date") if obj.get("send_expiration_date") is not None else False,
            "simulate_batch_for_clearing_record_hash": obj.get("simulate_batch_for_clearing_record_hash"),
            "isa_indicator": obj.get("isa_indicator"),
            "token_pan": obj.get("token_pan"),
            "payment_channel_indicator": obj.get("payment_channel_indicator"),
            "is_installment": obj.get("is_installment"),
            "is_recurring": obj.get("is_recurring"),
            "network_metadata": NetworkMetadata.from_dict(obj.get("network_metadata")) if obj.get("network_metadata") is not None else None,
            "authorization_source_code": obj.get("authorization_source_code"),
            "interchange_rate_descriptor": obj.get("interchange_rate_descriptor"),
            "acquirer_institution_id_code": obj.get("acquirer_institution_id_code"),
            "terminal_id": obj.get("terminal_id"),
            "mti": obj.get("mti"),
            "clearing_file_name": obj.get("clearing_file_name")
        })
        return _obj

