from dataclasses import dataclass, field
from lxml import objectify, etree
from typing import List
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
[docs]
@dataclass
class AchDetail(TIPModel):
"""
AchDetail TIPModel
"""
account_number: int = field(
metadata={
"description": descriptions.ACH_ACCOUNT_NUMBER_DESCRIPTION,
}
)
aba: str = field(
metadata={
"description": descriptions.ACH_ABA_DESCRIPTION,
}
)
amount: float = field(
metadata={
"description": descriptions.ACH_AMOUNT_DESCRIPTION,
}
)
[docs]
@classmethod
def model_validate_from_elem(cls, data: etree.Element) -> "AchDetail":
"""
Create an AchDetail instance from XML element data.
:param data: etree Element containing ACH batch pair data
:return: AchDetail instance
:raises TIPModelValidationFromLxmlObjectifyException: If data is not an ObjectifiedElement
:raises TIPModelParsingException: If data does not contain all required attributes
"""
if isinstance(data, objectify.ObjectifiedElement):
try:
return cls(
account_number=TIPModel.parse_int(data.AccountNumber),
aba=TIPModel.parse_str(data.ABA.text),
amount=TIPModel.parse_float(data.Amount),
)
except AttributeError as e:
raise TIPModelParsingException(
f"Missing required attribute in obj_elem: {str(e)}"
)
raise TIPModelValidationFromLxmlObjectifyException(cls.__name__, type(data))
[docs]
@dataclass
class AchTransactionDetails(TIPModel):
"""
AchTransactionDetails TIPModel
"""
details: List[AchDetail]
[docs]
@classmethod
def model_validate_from_elem(cls, data: etree.Element) -> "AchTransactionDetails":
"""
Create an AchTransactionDetails instance from XML element data.
:param data: etree Element containing ACH transaction details
:return: AchTransactionDetails instance
:raises TIPModelValidationFromLxmlObjectifyException: If data is not an ObjectifiedElement
:raises TIPModelParsingException: If data does not contain all required attributes
"""
if isinstance(data, objectify.ObjectifiedElement):
details = TIPModel.try_getattr_from_elem(data, "Details")
val_details = [
AchDetail.model_validate_from_elem(batch)
for batch in details.getchildren()
]
try:
return cls(
details=val_details,
)
except AttributeError as e:
raise TIPModelParsingException(
f"Missing required attribute in obj_elem: {str(e)}"
)
raise TIPModelValidationFromLxmlObjectifyException(cls.__name__, type(data))
[docs]
@dataclass
class AchTIPRequest(TIPRequest):
"""
AchTIPRequest TIPRequest. TIPRequests are converted to this class when TransactionType is Ach.
"""
ach: AchTransactionDetails
[docs]
@classmethod
def model_validate_from_elem(cls, data: etree.Element) -> "AchTIPRequest":
"""
Create an AchTIPRequest instance from XML element data.
:param data: etree Element containing ACH TIP request data
:return: AchTIPRequest 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(
ach=AchTransactionDetails.model_validate_from_elem(
TIPModel.try_getattr_from_elem(data, TransactionTypeEnum.Ach.value)
),
**(tip_request_dc.to_kwargs()),
)
raise TIPModelValidationFromLxmlObjectifyException(cls.__name__, type(data))