from typing import List
from lxml import objectify
from q2_sdk.models.card import Card, CardType, CardVendor
from q2_sdk.models.cores.mappers.card_list import BaseCardListMapper
from q2_sdk.models.cores.queries.base_query import BaseQuery
from ...MiserCohesion.queries import DemographicInfoQuery
[docs]
class CardListMapper(BaseCardListMapper):
VISA_PROD_TYPES = ["01", "02", "03", "04"]
DEBIT_CODES = ["00", "10"]
[docs]
@staticmethod
def parse_returned_queries(list_of_queries: List[BaseQuery]) -> List[Card]:
assert len(list_of_queries) == 1, (
"MiserCohesion CardListMapper only knows how to deal with a single query"
)
assert isinstance(list_of_queries[0], DemographicInfoQuery), (
"Query must be an instance of MiserCohesion.queries.DemographicInfoQuery"
)
response = list_of_queries[0].raw_core_response
root = objectify.fromstring(response)
card_list = []
for account in root.Accounts.Account:
card = None
is_visa_card = CardListMapper.verify_is_visa(account)
is_debit_card = CardListMapper.verify_is_debit(account)
if is_visa_card:
card = CardListMapper._build_visa_card(account)
elif is_debit_card:
card = CardListMapper._build_debit_card(account)
# Verify that we're on a card
if (
card
and len(card.account_number) == 16
and card.account_number.isdigit()
):
card_list.append(card)
return card_list
[docs]
@staticmethod
def verify_is_visa(account):
is_visa_card = False
try:
is_visa_card = any([
x.text in CardListMapper.VISA_PROD_TYPES for x in account.ProdType
])
except AttributeError:
pass
return is_visa_card
[docs]
@staticmethod
def verify_is_debit(account):
is_debit_card = False
try:
is_debit_card = any([
x.text in CardListMapper.DEBIT_CODES for x in account.ApplCode
])
except AttributeError:
pass
return is_debit_card
[docs]
@staticmethod
def verify_is_cancelled(account):
is_cancelled = False
try:
is_cancelled = not bool([
StatusInd.text for StatusInd in account.StatusInd if StatusInd.text
])
except AttributeError:
pass
return is_cancelled
@staticmethod
def _build_debit_card(account):
is_cancelled = CardListMapper.verify_is_cancelled(account)
card = Card(
account.PriAcctNbr.text.split()[0],
CardType.DEBIT,
expiration_date=account.ExpDate.text,
cancelled=is_cancelled,
)
return card
@staticmethod
def _build_visa_card(account):
card = Card(
account.ERAcctNbr.text,
CardType.CREDIT,
vendor=CardVendor.VISA,
limit=account.CreditLimit,
description=account.ProdDesc.text,
expiration_date=account.ExpDate.text,
)
return card