from typing import Optional
from lxml import objectify, etree
from dataclasses import dataclass, field
from q2_sdk.models.tip.schemas.base import TIPModel, TIPRequest
from q2_sdk.models.tip.schemas import descriptions
from q2_sdk.models.tip.exceptions import (
TIPModelValidationFromLxmlObjectifyException,
TIPModelParsingException,
)
from q2_sdk.models.tip.variables import TransactionTypeEnum, TransferDirection
[docs]
@dataclass
class ExternalTransferTransactionDetails(TIPModel):
"""
ExternalTransferTransactionDetails TIPModel
"""
direction: TransferDirection = field(
metadata={
"description": descriptions.ET_DIRECTION_DESCRIPTION,
}
)
originating_account: str = field(
metadata={
"description": descriptions.ET_ORIGINATING_ACCOUNT_DESCRIPTION,
}
)
to_account: str = field(
metadata={"description": descriptions.ET_TO_ACCOUNT_DESCRIPTION}
)
to_account_aba: Optional[str] = field(
metadata={
"description": descriptions.ET_TO_ACCOUNT_ABA_DESCRIPTION,
}
)
originating_account_aba: Optional[str] = field(
metadata={
"description": descriptions.ET_ORIGINATING_ACCOUNT_ABA_DESCRIPTION,
}
)
[docs]
@classmethod
def model_validate_from_elem(
cls, data: etree.Element
) -> "ExternalTransferTransactionDetails":
"""
Create a ExternalTransferTransactionDetails instance from XML element data.
:param data: etree Element containing funds transfer transaction details
:return: ExternalTransferTransactionDetails instance
:raises TIPModelValidationFromLxmlObjectifyException: If data is not an ObjectifiedElement
"""
if isinstance(data, objectify.ObjectifiedElement):
try:
# we do this because if the field is missing from the xml, the ObjectifiedElement
# parsed by lxml will not have the attribute at all. The TIPModel.parse_{dtype}_optional
# covers the case where the field is present in the xml but is None or empty str.
try:
to_account_aba = data.ToAccountABA.text
except AttributeError:
to_account_aba = None
try:
originating_account_aba = data.OriginatingAccountABA.text
except AttributeError:
originating_account_aba = None
return cls(
direction=TransferDirection.from_elem_str(
TIPModel.parse_str(data.Direction.text)
),
originating_account=TIPModel.parse_str(
data.OriginatingAccount.text
),
to_account=TIPModel.parse_str(data.ToAccount.text),
to_account_aba=TIPModel.parse_str_optional(to_account_aba),
originating_account_aba=TIPModel.parse_str_optional(
originating_account_aba
),
)
except AttributeError as e:
raise TIPModelParsingException(
f"Missing required attribute in obj_elem: {str(e)}"
)
raise TIPModelValidationFromLxmlObjectifyException(cls.__name__, type(data))
[docs]
@dataclass
class ExternalTransferTIPRequest(TIPRequest):
"""
ExternalTransferTIPRequest TIPRequest. TIPRequests are converted to this class when TransactionType is ExternalTransfer.
"""
external_transfer: ExternalTransferTransactionDetails
[docs]
@classmethod
def model_validate_from_elem(
cls, data: etree.Element
) -> "ExternalTransferTIPRequest":
"""
Create a ExternalTransferTIPRequest instance from XML element data.
:param data: etree Element containing funds transfer TIP request data
:return: ExternalTransferTIPRequest instance
:raises TIPModelValidationFromLxmlObjectifyException: If data is not an ObjectifiedElement
"""
if isinstance(data, objectify.ObjectifiedElement):
tip_request_dc = TIPRequest.model_validate_from_elem(data)
return cls(
external_transfer=ExternalTransferTransactionDetails.model_validate_from_elem(
TIPModel.try_getattr_from_elem(
data, TransactionTypeEnum.ExternalTransfer.value
)
),
**(tip_request_dc.to_kwargs()),
)
raise TIPModelValidationFromLxmlObjectifyException(cls.__name__, type(data))