from logging import Logger
from typing import Optional
from uuid import uuid4
from q2_sdk.hq.models.account import Account
from q2_sdk.models.cores.restricted_queries.base_restricted_query import (
BaseRestrictedQuery,
)
from q2_cores.Symitar.data_helpers import make_symxchange_xml
[docs]
class SymitarPrincipalPaymentQuery(BaseRestrictedQuery):
def __init__(
self,
logger: Logger,
from_account: Account,
to_account: Account,
unit_number: str,
device_type: str,
card_prefix: str,
transaction_amount: float,
memo: Optional[str] = None,
remit_tran_code=None,
use_symxchange=False,
):
self.logger = logger
self.from_account = from_account
self.to_account = to_account
self.unit_number = unit_number
self.device_type = device_type
self.card_prefix = card_prefix
self.transfer_code = (
"XF" # will always be the case for symitar principal payments
)
self.from_account_type = "S" # for loan payment we only ever allow Shares (checking/savings) as source accounts
self.to_account_type = "L" # for loan payment this will always be "L" for loans
self.transaction_payment_type = "1" # 1 = extra payment type for principal payment. will not advance due date
self.transaction_amount = "{:.2f}".format(transaction_amount).replace(".", "")
self.memo = memo if memo else ""
self.remit_tran_code = remit_tran_code
self.use_symxchange = use_symxchange
super().__init__(logger)
[docs]
def build(self, guid: Optional[uuid4] = None) -> str:
"""
We'll build the symitar transaction request string here
"""
from_account_cif = self.from_account.cif
to_account_cif = self.to_account.cif
from_account_share_id = self.from_account.acct_number_internal_unmasked
if not isinstance(from_account_share_id, int):
from_account_share_id = "".join([
n for n in from_account_share_id if n.isdigit()
])
to_account_share_id = self.to_account.acct_number_internal_unmasked
if not isinstance(to_account_share_id, int):
to_account_share_id = "".join([
n for n in to_account_share_id if n.isdigit()
])
if not guid:
guid = uuid4() # pragma: no cover
call = (
"TR~{guid}~A{unit_number}~B{device_type}~DCARD"
"~F{card_prefix}{from_acct_cif}~JTRCODE={tr_code}"
"~JTRFMACCT={from_acct_cif}~JTRFMID={from_acct_id}"
"~JTRFMTYPE={from_acct_type}~JTRTOACCT={to_acct_cif}"
"~JTRTOID={to_acct_id}~JTRTOTYPE={to_acct_type}"
"~JTRAMOUNT={tran_amount}~JTRPRINCIPAL={tran_amount}"
"~JTRCOMMENTCODE=0~JTRCOMMENT={tran_desc}"
"~JTRPAYMENTTYPE={tr_payment_type}"
).format(
guid=str(guid),
unit_number=self.unit_number,
device_type=self.device_type,
card_prefix=self.card_prefix,
from_acct_cif=from_account_cif,
tr_code=self.transfer_code,
from_acct_id=from_account_share_id,
from_acct_type=self.from_account_type,
to_acct_cif=to_account_cif,
to_acct_id=to_account_share_id,
to_acct_type=self.to_account_type,
tran_amount=self.transaction_amount,
tran_desc=self.memo,
tr_payment_type=self.transaction_payment_type,
)
if self.remit_tran_code:
call += f"~JTRREMITTRANCODE={self.remit_tran_code}"
if self.use_symxchange:
call = make_symxchange_xml(call)
return call