from datetime import datetime
from dataclasses import dataclass
from uuid import uuid4
import base64
import json
from lxml import etree
from lxml.etree import Element, SubElement, QName, tostring
from q2_sdk.hq.models.account import Account
from q2_sdk.models.online_transaction import Transaction
from q2_cores.data_helpers import get_online_request_str_acct, get_online_request_acct
from q2_cores.data_helpers import * # noqa: F403
# Symitar
SYMITAR_GUID = "7a1eae0e-969a-4825-98a0-fc7df51bb28f"
SYMITAR_UNIT_NUMBER = "1"
SYMITAR_DEVICE_TYPE = "Q2"
SYMITAR_CARD_PREFIX = "20610"
SYMITAR_IND_NUMBER = "0000000001"
SYMITAR_IND_NUMBER_TWO = "0000000002"
SYMITAR_REPGEN_NAME = "Q2"
SYMITAR_PROCEDURE = "STARTSTATE"
SYMITAR_LIST_ALL_CARDS_PROCEDURE = "LISTALLCARDS"
SYMITAR_CUST_NUM = "0000234567"
SYMITAR_DATA_ATTR_KEY = "KEY1"
SYMITAR_DATA_ATTR_VALUE = "VALUE1"
SYMITAR_REPGEN_RGPARAM_KEY = "RGUSERCHR1"
SYMITAR_REPGEN_RGPARAM_VALUE = "VALUE1"
# Symitar SkipAPay
ELIGIBLE_LOAN_CIF = "1"
ELIGIBLE_LOAN_ID = "1"
INELIGIBLE_LOAN_CIF = "2"
INELIGIBLE_LOAN_ID = "2"
NEW_DUE_DATE = "2/1/17"
SKIP_FEE = "25"
LOAN_NOTE = "test note"
GL_CODE = "GL"
# Open Sub Account
SHARE_TYPE_ID = 1
FUNDING_AMOUNT = 100.00
SHARE_START_ID = 1
DATA_FILE_NAME = "/tmp/foo.txt"
WITHHOLDINGS = 7
JOINTMEMBERLOC = 6
ACCOUNT_LIST_OBJ = get_online_request_acct()
[docs]
def get_account_objects(account_list_obj):
account1 = Account(account_list_obj[0])
account_2 = Account(account_list_obj[1])
return account1, account_2
TRANSACTION_AMOUNT = 500.0
MEMO = "Testing Symitar Principal Payment"
REMIT_TRAN_CODE = "XYZ"
TRANSFER_CODE = "XF"
FROM_ACCOUNT_TYPE = "S"
TO_ACCOUNT_TYPE = "L"
TRANSACTION_PAYMENT_TYPE = "1"
PRINCIPAL_PAYMENT_TYPE = "PrincipalPayment"
TRANSACTION_DATE = datetime.strptime("10/20/2017", "%m/%d/%Y").date()
GUID = uuid4()
ACCOUNT1, ACCOUNT2 = get_account_objects(ACCOUNT_LIST_OBJ)
TRANSACTION_OBJ = Transaction(
ACCOUNT1,
ACCOUNT2,
TRANSACTION_AMOUNT,
TRANSACTION_DATE,
PRINCIPAL_PAYMENT_TYPE,
memo=MEMO,
)
STR_ACCT_LIST_OBJ = get_online_request_str_acct()
STR_ACCOUNT1, STR_ACCOUNT2 = get_account_objects(STR_ACCT_LIST_OBJ)
STR_TRANSACTION_OBJ = Transaction(
STR_ACCOUNT1,
STR_ACCOUNT2,
TRANSACTION_AMOUNT,
TRANSACTION_DATE,
PRINCIPAL_PAYMENT_TYPE,
memo=MEMO,
)
# Address Change
UPDATELOCATOR = "123"
UPDATEADDRESSTYPE = "00"
UPDATESTREET = "123 Main Street"
UPDATEEXTRAADDRESS = ""
UPDATESHAREID = ""
UPDATECITY = "Austin"
UPDATESTATE = "TX"
UPDATECOUNTRY = ""
UPDATECOUNTRYCODE = ""
UPDATELASTADDRVERIFDATE = "07/01/2018"
UPDATEZIPCODE = "78748"
UPDATEPHONETYPE = "00"
UPDATEHOMEPHONE = "512-777-3333"
UPDATEMOBILEPHONE = ""
UPDATEWORKPHONE = ""
UPDATEWORKPHONEEXTENSION = ""
UPDATEEMAIL = "email@email"
UPDATEALTEMAIL = ""
UPDATEEXPIRATIONDATE = ""
UPDATEEXPIRATION = ""
UPDATEMAILINGTYPE = "02"
UPDATEPREFERREDCONTACTMETHOD = ""
SETWARNINGCODE = "80"
GOODSTATEMENTMAILCODE = "02"
BADSTATEMENTMAILCODE = "18"
RESETWARININGCODE = "81"
SSN = "123456789"
NAME_TYPE_LIST = "01,02,14"
[docs]
def principal_payment_query(str_acct_num_internal=False) -> str:
account_1 = STR_ACCOUNT1 if str_acct_num_internal else ACCOUNT1
account_2 = STR_ACCOUNT2 if str_acct_num_internal else ACCOUNT2
from_account_share_id = account_1.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 = account_2.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()])
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=SYMITAR_GUID,
unit_number=SYMITAR_UNIT_NUMBER,
device_type=SYMITAR_DEVICE_TYPE,
card_prefix=SYMITAR_CARD_PREFIX,
from_acct_cif=ACCOUNT1.cif,
tr_code=TRANSFER_CODE,
from_acct_id=from_account_share_id,
from_acct_type=FROM_ACCOUNT_TYPE,
to_acct_cif=ACCOUNT2.cif,
to_acct_id=to_account_share_id,
to_acct_type=TO_ACCOUNT_TYPE,
tran_amount="{:.2f}".format(TRANSACTION_AMOUNT).replace(".", ""),
tran_desc=MEMO,
tr_payment_type=TRANSACTION_PAYMENT_TYPE,
)
return call
[docs]
def demographic_test_records():
payload = """
<DATA>
<PPVERSION>1.000.A000</PPVERSION>
<MEMOMODE>FALSE</MEMOMODE>
<ACCOUNTNUMBER>0000000001</ACCOUNTNUMBER>
<ACCOUNTTYPE>0001</ACCOUNTTYPE>
<ACCOUNTCLOSEDATE>--/--/----</ACCOUNTCLOSEDATE>
<ESTATEMENTS>0</ESTATEMENTS>
<ESTMTNOTIFY>00</ESTMTNOTIFY>
<ENROLLDATE>--/--/----</ENROLLDATE>
<NAMERECORDS>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>0000</NAMETYPE>
<LOCATOR>0000000001</LOCATOR>
<LONGNAME>TEST Q2</LONGNAME>
<FIRST>TEST</FIRST>
<MIDDLE></MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME>TESTTEST</EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456789</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 WASHINGTON AVE</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>07110</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
</NAME>
<NAME>
<LICENSENUMBER></LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>01</NAMETYPE>
<LOCATOR>0000000002</LOCATOR>
<LONGNAME>INTERNATIONAL TEST Q2</LONGNAME>
<FIRST>INTERNATIONAL</FIRST>
<MIDDLE>TEST</MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456781</SSN>
<ADDRESSTYPE>01</ADDRESSTYPE>
<STREET>123 INTERNATIONAL AVE</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>PARIS</CITY>
<STATE></STATE>
<COUNTRY>FRANCE</COUNTRY>
<COUNTRYCODE>FR</COUNTRYCODE>
<ZIPCODE>0711012</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
</NAME>
<NAME>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>14</NAMETYPE>
<LOCATOR>0000000003</LOCATOR>
<LONGNAME>JOINT Q2</LONGNAME>
<FIRST>JOINT</FIRST>
<MIDDLE>TEST</MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456782</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 WASHINGTON AVE</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>07110</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>02</NAMETYPE>
<LOCATOR>0000000004</LOCATOR>
<LONGNAME>MAILING TEST Q2</LONGNAME>
<FIRST>MAILING</FIRST>
<MIDDLE></MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456789</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 PO BOX</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>77723</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
<EXPIRATIONDATE></EXPIRATIONDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>02</NAMETYPE>
<LOCATOR>0000000005</LOCATOR>
<LONGNAME>TEST Q2</LONGNAME>
<FIRST>TEST</FIRST>
<MIDDLE></MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456789</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 WASHINGTON AVE</STREET>
<EXTRAADDRESS>ATTENTION: TEST Q2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>07110</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
<EXPIRATIONDATE>07/20/2010</EXPIRATIONDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>FALSE</ACCOUNTLEVELSIGNER>
<SHAREID>0001</SHAREID>
<NAMETYPE>01</NAMETYPE>
<LOCATOR>0000000006</LOCATOR>
<LONGNAME>SHARE JOINT Q2</LONGNAME>
<FIRST>SHARE</FIRST>
<MIDDLE>JOINT</MIDDLE>
<LAST>Q2</LAST>
<MMN>TEST</MMN>
<BIRTHDATE>09/19/2017</BIRTHDATE>
<SSN>123456784</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>1234 MAIN STREET</STREET>
<EXTRAADDRESS></EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>78748</ZIPCODE>
<HOMEPHONE>015123334444</HOMEPHONE>
<MOBILEPHONE>015129098888</MOBILEPHONE>
<WORKPHONE>015123026000</WORKPHONE>
<WORKPHONEEXTENSION>1234</WORKPHONEEXTENSION>
<PHONETYPE>01</PHONETYPE>
<EMAIL>MYEMAIL@EMAIL.COM</EMAIL>
<ALTEMAIL>ALTMAIL@EMAIL.COM</ALTEMAIL>
<LASTADDRVERIFDATE>01/20/2018</LASTADDRVERIFDATE>
</NAME>
</NAMERECORDS>
</DATA>"""
return payload
[docs]
def demographic_test_closed_accounts():
payload = """<DATA>
<PPVERSION>1.000.A000</PPVERSION>
<MEMOMODE>FALSE</MEMOMODE>
<ACCOUNTNUMBER>0000000001</ACCOUNTNUMBER>
<ACCOUNTTYPE>0001</ACCOUNTTYPE>
<ACCOUNTCLOSEDATE>05/01/2018</ACCOUNTCLOSEDATE>
<ESTATEMENTS>0</ESTATEMENTS>
<ESTMTNOTIFY>00</ESTMTNOTIFY>
<ENROLLDATE>05/08/2018</ENROLLDATE>
<NAMERECORDS>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>0000</NAMETYPE>
<LOCATOR>0000000001</LOCATOR>
<LONGNAME>TEST Q2</LONGNAME>
<FIRST>TEST</FIRST>
<MIDDLE></MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME>TESTTEST</EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456789</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 WASHINGTON AVE</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>07110</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>01</NAMETYPE>
<LOCATOR>0000000002</LOCATOR>
<LONGNAME>INTERNATIONAL TEST Q2</LONGNAME>
<FIRST>INTERNATIONAL</FIRST>
<MIDDLE>TEST</MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456781</SSN>
<ADDRESSTYPE>01</ADDRESSTYPE>
<STREET>123 INTERNATIONAL AVE</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>PARIS</CITY>
<STATE></STATE>
<COUNTRY>FRANCE</COUNTRY>
<COUNTRYCODE>FR</COUNTRYCODE>
<ZIPCODE>0711012</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>14</NAMETYPE>
<LOCATOR>0000000003</LOCATOR>
<LONGNAME>JOINT Q2</LONGNAME>
<FIRST>JOINT</FIRST>
<MIDDLE>TEST</MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456782</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 WASHINGTON AVE</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>07110</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>02</NAMETYPE>
<LOCATOR>0000000004</LOCATOR>
<LONGNAME>MAILING TEST Q2</LONGNAME>
<FIRST>MAILING</FIRST>
<MIDDLE></MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456789</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 PO BOX</STREET>
<EXTRAADDRESS>ATTENTION: TESTQ2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>77723</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
<EXPIRATIONDATE></EXPIRATIONDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>TRUE</ACCOUNTLEVELSIGNER>
<NAMETYPE>02</NAMETYPE>
<LOCATOR>0000000005</LOCATOR>
<LONGNAME>TEST Q2</LONGNAME>
<FIRST>TEST</FIRST>
<MIDDLE></MIDDLE>
<LAST>Q2</LAST>
<EXTENDEDNAME></EXTENDEDNAME>
<MMN>SMITH</MMN>
<BIRTHDATE>02/06/1962</BIRTHDATE>
<SSN>123456789</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>123 WASHINGTON AVE</STREET>
<EXTRAADDRESS>ATTENTION: TEST Q2</EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>07110</ZIPCODE>
<HOMEPHONE>512-333-5555</HOMEPHONE>
<MOBILEPHONE>512-220-5758</MOBILEPHONE>
<WORKPHONE>512-333-5555</WORKPHONE>
<WORKPHONEEXTENSION>2054</WORKPHONEEXTENSION>
<PHONETYPE>00</PHONETYPE>
<EMAIL>myemail@email.com</EMAIL>
<ALTEMAIL></ALTEMAIL>
<LASTADDRVERIFDATE>07/19/2018</LASTADDRVERIFDATE>
<EXPIRATIONDATE>07/20/2010</EXPIRATIONDATE>
</NAME>
<NAME>
<LICENSENUMBER>0123456789</LICENSENUMBER>
<ACCOUNTLEVELSIGNER>FALSE</ACCOUNTLEVELSIGNER>
<SHAREID>0001</SHAREID>
<NAMETYPE>01</NAMETYPE>
<LOCATOR>0000000006</LOCATOR>
<LONGNAME>SHARE JOINT Q2</LONGNAME>
<FIRST>SHARE</FIRST>
<MIDDLE>JOINT</MIDDLE>
<LAST>Q2</LAST>
<MMN>TEST</MMN>
<BIRTHDATE>09/19/2017</BIRTHDATE>
<SSN>123456784</SSN>
<ADDRESSTYPE>00</ADDRESSTYPE>
<STREET>1234 MAIN STREET</STREET>
<EXTRAADDRESS></EXTRAADDRESS>
<CITY>AUSTIN</CITY>
<STATE>TX</STATE>
<COUNTRY></COUNTRY>
<COUNTRYCODE></COUNTRYCODE>
<ZIPCODE>78748</ZIPCODE>
<HOMEPHONE>015123334444</HOMEPHONE>
<MOBILEPHONE>015129098888</MOBILEPHONE>
<WORKPHONE>015123026000</WORKPHONE>
<WORKPHONEEXTENSION>1234</WORKPHONEEXTENSION>
<PHONETYPE>01</PHONETYPE>
<EMAIL>MYEMAIL@EMAIL.COM</EMAIL>
<ALTEMAIL>ALTMAIL@EMAIL.COM</ALTEMAIL>
<LASTADDRVERIFDATE>01/20/2018</LASTADDRVERIFDATE>
</NAME>
</NAMERECORDS>
</DATA>
"""
return payload
[docs]
def get_build_query(repggen, state, ssn=None, name_list=None):
call_replacements = {
"guid": SYMITAR_GUID,
"rep": repggen,
"state": state,
"c1": ssn if ssn else "",
"c2": name_list if name_list else "",
}
temp = """RG~{guid}~A1~BQ2~DCARD~F206100000000001~G{rep}~JRGSESSION=10~JRGSTATE={state}~JRGUSERCHR1={c1}~JRGUSERCHR2={c2}"""
return temp.format(**call_replacements)
[docs]
def populate_rg_user_vars(repgen_string):
rg_user_vars = {}
for num in range(1, 6):
start_location = repgen_string.find("~JRGUSERCHR" + str(num) + "=")
if start_location > 0: # if the string was found
value = repgen_string[start_location + 13 :].split("~")[0]
if len(value) > 0 and num == 5:
if value[-1] == "|":
rg_user_vars[num] = (
str(value) + "UseSymX=1|"
) # this should be appended to the existing value.
else:
rg_user_vars[num] = str(value) + "|UseSymX=1|"
elif len(value) > 0:
rg_user_vars[num] = str(value)
else:
rg_user_vars[num] = "?"
elif num == 5:
rg_user_vars[num] = (
"|UseSymX=1|" # RG devs want this to route to a different version of the RG file.
)
continue
else:
rg_user_vars[num] = "?"
return rg_user_vars
[docs]
def populate_rg_user_nums(repgen_string):
rg_user_nums = {}
for num in range(1, 6):
start_location = repgen_string.find("~JRGUSERNUM" + str(num) + "=")
if start_location > 0: # if the string was found
value = repgen_string[start_location + 13 :].split("~")[0]
rg_user_nums[num] = value
else:
rg_user_nums[num] = "0"
return rg_user_nums
def _chunk_str(inp: str, size: int):
"Takes a string and splits it into chunks of size"
for i in range(0, len(inp), size):
yield inp[i : i + size]
[docs]
@dataclass
class XMLNamespaces:
soapenv: str = "http://schemas.xmlsoap.org/soap/envelope/"
pow_ns: str = "http://www.symxchange.generated.symitar.com/poweron"
tns: str = "http://www.symxchange.generated.symitar.com/common/dto/common"
[docs]
def make_symxchange_xml(symconnect_string):
"""reformat repgen string into SOAP request which differ based on call signature.
https://confluence.q2ebanking.com/display/ProServ/SymConn+to+SymX
"""
nsmap = {
"soapenv": XMLNamespaces.soapenv,
"pow": XMLNamespaces.pow_ns,
"tns": XMLNamespaces.tns,
}
call_signature = symconnect_string[:2]
if call_signature == "RG":
file_name = extract_symconnect_value(symconnect_string, "~G")
rg_state = extract_symconnect_value(symconnect_string, "~JRGSTATE=")
else:
file_name = "Q2.SOAP"
rg_state = "Get"
guid = extract_symconnect_value(symconnect_string, call_signature + "~")
card_number = extract_symconnect_value(symconnect_string, "~F")
device_type = extract_symconnect_value(symconnect_string, "~B")
device_number = extract_symconnect_value(symconnect_string, "~A")
envelope = Element(QName(XMLNamespaces.soapenv, "Envelope"), nsmap=nsmap)
SubElement(envelope, QName(XMLNamespaces.soapenv, "Header"))
body = SubElement(envelope, QName(XMLNamespaces.soapenv, "Body"))
power_on = SubElement(body, QName(XMLNamespaces.pow_ns, "executePowerOn"))
request = SubElement(power_on, "Request")
credentials = SubElement(
request, "Credentials", attrib={QName(XMLNamespaces.tns, "ProcessorUser"): "1"}
)
card_credentials = SubElement(credentials, "CardCredentials")
card_number_element = SubElement(card_credentials, "CardNumber")
card_number_element.text = card_number
SubElement(
request,
"DeviceInformation",
attrib={"DeviceType": device_type, "DeviceNumber": device_number},
)
sub_header = SubElement(request, "Header")
message_id_element = SubElement(sub_header, "MessageID")
message_id_element.text = guid
rg_state_element = SubElement(sub_header, "RGState")
rg_state_element.text = rg_state
sub_body = SubElement(request, "Body")
file_element = SubElement(sub_body, "File")
file_element.text = file_name
rg_session = SubElement(sub_body, "RGSession")
rg_session.text = "1"
user_defined_parameters = SubElement(sub_body, "UserDefinedParameters")
datafile_body = None
datafile_name = None
if call_signature and "DATAFILENAME" in symconnect_string:
rg_user_vars = populate_rg_user_vars(symconnect_string)
rg_user_nums = populate_rg_user_nums(symconnect_string)
datafile_lines = rg_user_vars.get(1).split("\n")[1:]
datafile_body = "\n".join(datafile_lines)
rg_user_vars[1] = rg_user_vars.get(1).split("\n")[0]
datafile_name = rg_user_vars.get(1).split("=")[-1]
datafile_name = datafile_name[:28]
for key, value in rg_user_vars.items():
rg_user_chr = SubElement(user_defined_parameters, "RGUserChr")
rg_id = SubElement(rg_user_chr, "ID")
rg_id.text = str(key)
rg_value = SubElement(rg_user_chr, "Value")
rg_value.text = value[: len("DATAFILENAME=") + len(datafile_name)]
for num, value in rg_user_nums.items():
rg_user_num = SubElement(user_defined_parameters, "RGUserNum")
rg_id = SubElement(rg_user_num, "ID")
rg_id.text = str(num)
rg_value = SubElement(rg_user_num, "Value")
rg_value.text = value
elif call_signature == "RG":
rg_user_vars = populate_rg_user_vars(symconnect_string)
rg_user_nums = populate_rg_user_nums(symconnect_string)
for key, value in rg_user_vars.items():
rg_user_chr = SubElement(user_defined_parameters, "RGUserChr")
rg_id = SubElement(rg_user_chr, "ID")
rg_id.text = str(key)
rg_value = SubElement(rg_user_chr, "Value")
rg_value.text = value
for num, value in rg_user_nums.items():
rg_user_num = SubElement(user_defined_parameters, "RGUserNum")
rg_id = SubElement(rg_user_num, "ID")
rg_id.text = str(num)
rg_value = SubElement(rg_user_num, "Value")
rg_value.text = value
else:
rsl = _chunk_str(symconnect_string, 100)
rg_user_count = 1
for substr in rsl:
rg_user_chr = SubElement(user_defined_parameters, "RGUserChr")
rg_id = SubElement(rg_user_chr, "ID")
rg_id.text = str(rg_user_count)
rg_value = SubElement(rg_user_chr, "Value")
rg_value.text = substr
rg_user_count += 1
flattened_envelope_bytes = etree.tostring(envelope)
encoded_inner_body = base64.b64encode(flattened_envelope_bytes).decode()
if not datafile_body:
root = Element("PassThru", attrib={"service": "poweron"})
root.text = encoded_inner_body
return tostring(root).decode()
else:
passthru = {
"service": "poweron",
"body": encoded_inner_body,
"file": {
"name": datafile_name,
"contents": base64.b64encode(datafile_body.encode("utf-8")).decode(),
},
}
return json.dumps(passthru)