File: //home/arjun/projects/buyercall_forms/buyercall/buyercall/lib/util_credit_reports.py
import logging
from buyercall.integrations.seven_hundred_credit import SevenHundredCredit
from buyercall.integrations.finserv import Finserv
from flask import current_app as app
from buyercall.lib.util_crypto import AESCipher
from dateutil.parser import parse
import re
import us
from uszipcode import SearchEngine
from string import punctuation
log = logging.getLogger(__name__)
HOURS = 3600
DAYS = 86400 # The length of a day in seconds
def seven_hundred_credit_client(partnership_account_id, product_type):
from buyercall.blueprints.partnership.models import PartnershipAccountCreditTie
# Get the encryption key to decrypt credentials
encrypt_key = app.config['CRYPTO_SECRET_KEY']
# Retrieve the 700 credit credit profile for the partnership account
partner_credit_profile = PartnershipAccountCreditTie.\
partner_account_seven_hundred_credit_info(partnership_account_id, product_type)
cipher = AESCipher(encrypt_key)
# Decrypt the credentials
decrypted_username = cipher.decrypt(partner_credit_profile.api_username)
decrypted_password = cipher.decrypt(partner_credit_profile.api_password)
client = SevenHundredCredit(decrypted_username,
decrypted_password,
product_type)
return client
def finserv_credit_client(partnership_account_id, product_type):
from buyercall.blueprints.partnership.models import PartnershipAccountCreditTie, PartnershipCreditTie
# Get the encryption key to decrypt credentials
encrypt_key = app.config['CRYPTO_SECRET_KEY']
# Retrieve the Finserv credit profile for the partnership account
partner_credit_profile = PartnershipAccountCreditTie.\
partner_account_finserv_credit_info(partnership_account_id, product_type)
if not partner_credit_profile:
from buyercall.blueprints.partnership.models import PartnershipAccount
partner_account = PartnershipAccount.query.filter(PartnershipAccount.id == partnership_account_id).first()
partner_credit_profile = PartnershipCreditTie.partner_finserv_credit_info(partner_account.partnership_id,
product_type)
cipher = AESCipher(encrypt_key)
# Decrypt the credentials
decrypted_username = cipher.decrypt(partner_credit_profile.api_username)
decrypted_password = cipher.decrypt(partner_credit_profile.api_password)
decrypted_dealercode = cipher.decrypt(partner_credit_profile.api_account)
client = Finserv(decrypted_username,
decrypted_password,
decrypted_dealercode,
product_type)
return client
def validate_ssn(ssn):
format_ssn = ssn.replace('-', '').replace(' ', '').replace('#', '')
if len(format_ssn) != 9:
log.info('the length is {}'.format(len(str(format_ssn))))
return False
# Check the ssn number against a pattern to ensure its a valid number
pattern = re.match(r'\b(?!000|.+0{4})(?:\d{9}|\d{3}-\d{2}-\d{4})\b', str(format_ssn))
if not pattern:
return False
# When in testing ignore 666 otherwise if in production valid for 666 numbers
if not app.config['DEBUG']:
if format_ssn[:3] == '666':
return False
# Check to make sure the number does not start with 9
if format_ssn[:1] == '9':
return False
# Last check to see the number is not a known spam or fake ssn number
if format_ssn in ['000000000', '219099999', '111111111', '123456789', '333333333']:
return False
return True
def validate_name(firstname, lastname):
if firstname == '' or firstname == '':
return False
# Check to see if the name has numbers
firstname_numbers = bool(re.search(r'\d', firstname))
if firstname_numbers:
return False
if lastname == '' or lastname == '':
return False
# Check to see if the name has numbers
lastname_numbers = bool(re.search(r'\d', lastname))
if lastname_numbers:
return False
return True
# Format an address to match 700 credit requirements
def format_street(street):
# Get a list of not-allowed characters required by 700 Credit
exclude_string = str(punctuation).replace('#', '').replace('-', '').replace('.', '').replace('/', '')
exclude_list = [char for char in exclude_string]
for char in exclude_list:
if char in exclude_list:
street = street.replace(char, '')
return street
# Format the full name of lead by removing special characters
def format_full_name(full_name):
# Get a list of not-allowed characters required by 700 Credit
exclude_string = str(punctuation).replace('-', '')
exclude_list = [char for char in exclude_string]
for char in exclude_list:
if char in exclude_list:
full_name = full_name.replace(char, '')
return full_name
# Format an address to match 700 credit requirements
def format_city(city):
# Get a list of not-allowed characters required by 700 Credit
exclude_string = str(punctuation).replace('#', '').replace('-', '').replace('.', '').replace('/', '')
exclude_list = [char for char in exclude_string]
exclude_number = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
for char in exclude_list:
city = city.replace(char, '')
for num in exclude_number:
city = city.replace(num, '')
return city
def format_state(state):
# Get a list of not-allowed characters required by 700 Credit
exclude_string = str(punctuation).replace('#', '').replace('-', '').replace('.', '').replace('/', '')
exclude_list = [char for char in exclude_string]
exclude_number = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
for char in exclude_list:
state = state.replace(char, '')
for num in exclude_number:
state = state.replace(num, '')
state = state.lower().strip()
state_lookup = us.states.lookup(state)
if state_lookup:
state_abbr = state_lookup.abbr
return state_abbr
return None
def format_zip(zip_):
# Get a list of not-allowed characters required by 700 Credit
exclude_string = str(punctuation)
exclude_list = [char for char in exclude_string]
zip_ = zip_[:5]
for char in exclude_list:
zip_ = zip_.replace(char, '')
zip_ = zip_.replace(' ', '')
return zip_
def validate_address_street(street):
if street == '' or street == ' ':
return False
return True
def validate_address_city(city):
if city == '' or city == ' ':
return False
return True
def validate_address_state(state):
if state == '' or state == ' ':
return False
formatted_state = format_state(state)
if not formatted_state:
return False
#if not app.config['DEBUG']:
# state = (format_state(state)).lower()
# state_lookup = us.states.lookup(state)
# if not state_lookup:
# return False
return True
def validate_address_zip(zip_):
if zip_ == '' or zip_ == ' ':
return False
# if not app.config['DEBUG']:
# search = SearchEngine(simple_zipcode=True, db_file_dir="/tmp/harry")
# zip_lookup = search.by_zipcode(format_zip(zip_))
# if not zip_lookup:
# return False
return True
def validate_city_state_zip_combo(zip_, city, state):
# This doesn't seem to work well. There is combination that is real that comes back as false, so lets just ignore
# this function for now and always return True until package is better and updated
# if not app.config['DEBUG']:
# if zip_ == '' or zip_ == ' ':
# return False
# elif city == '' or city == ' ':
# return False
# search = SearchEngine(simple_zipcode=True, db_file_dir="/tmp")
# zip_lookup = search.by_zipcode(format_zip(zip_))
# zip_to_dict = zip_lookup.to_dict()
# zip_city = zip_to_dict['major_city']
# zip_state = zip_to_dict['state']
# if zip_city.lower() != format_city(city).lower():
# return False
# if zip_state.lower() != format_state(state).lower():
# return False
return True
# Extract a year from dob field for Finserv
def format_dob_year(dob):
if dob:
year = parse(dob, fuzzy=True).year
return year
else:
year = ''
return year