def get(self, kyc_application_id): # we only support MASTER (ngo) KYC application currently business_details = KycApplication.query.filter_by(type='MASTER').first() if business_details is None: response_object = { 'message': 'No business verification details found' } return make_response(jsonify(response_object)), 404 if g.user.is_superadmin: response_object = { 'message': 'Successfully loaded business verification details', 'data': {'kyc_application': kyc_application_schema.dump(business_details).data} } return make_response(jsonify(response_object)), 200 # displays kyc_status state only. response_object = { 'message': 'Successfully loaded business verification details', 'data': {'kyc_application': kyc_application_state_schema.dump(business_details).data} } return make_response(jsonify(response_object)), 200
def post(self, kyc_application_id): post_data = request.get_json() type = post_data.get('type') first_name = post_data.get('first_name') last_name = post_data.get('last_name') phone = post_data.get('phone') business_legal_name = post_data.get('business_legal_name') business_type = post_data.get('business_type') tax_id = post_data.get('tax_id') website = post_data.get('website') date_established = post_data.get('date_established') country = post_data.get('country') street_address = post_data.get('street_address') street_address_2 = post_data.get('street_address_2') city = post_data.get('city') region = post_data.get('region') postal_code = post_data.get('postal_code') beneficial_owners = post_data.get('beneficial_owners') # check for existing business based on Legal Name and Tax ID. business_details = KycApplication.query.filter_by(business_legal_name=business_legal_name, tax_id=tax_id).first() if business_details is not None: response_object = { 'message': 'Business Verification profile already exists for business name: {} and tax ID: {}'.format(business_legal_name, tax_id) } return make_response(jsonify(response_object)), 400 if beneficial_owners is not None: # filter empty beneficial owners beneficial_owners = [owner for owner in beneficial_owners if(owner['full_name'].strip(' ',) != '')] if g.user.is_superadmin: type = 'MASTER' create_business_details = KycApplication( type=type, first_name=first_name, last_name=last_name, phone=phone, business_legal_name=business_legal_name, business_type=business_type, tax_id=tax_id, website=website, date_established=date_established, country=country, street_address=street_address, street_address_2=street_address_2, city=city, region=region, postal_code=postal_code, beneficial_owners=beneficial_owners, ) db.session.add(create_business_details) db.session.commit() response_object = { 'message': 'Business Verification profile created', 'data': {'kyc_application': kyc_application_schema.dump(create_business_details).data} } return make_response(jsonify(response_object)), 201
def post(self): reference = None kyc_application_id = None if 'kyc_application_id' in request.form: kyc_application_id = request.form['kyc_application_id'] if 'document' not in request.files: return make_response(jsonify({'message': 'No File'})), 400 document = request.files['document'] filename = document.filename if kyc_application_id is None: return make_response(jsonify({'message': 'You must append documents to a business profile'})), 400 business_details = KycApplication.query.filter_by(id=kyc_application_id).first() if not business_details: return make_response(jsonify({'message': 'Cannot find kyc for id {}'.format(kyc_application_id)})), 404 if business_details.organisation_id and AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response(jsonify({'message': 'Must be a superadmin to edit admin org KYC object'})), 401 if filename == '': return make_response(jsonify({'message': 'No File'})), 400 if not allowed_file(filename): return make_response(jsonify({'message': 'Must be JPG, JPEG, PNG or PDF'})), 400 file_type = filename.rsplit('.', 1)[1].lower() new_filename = generate_new_filename(filename, file_type) saved_document = UploadedResource.query.filter_by(filename=new_filename).first() if saved_document: return make_response(jsonify({'message': 'Document already exists'})), 400 save_to_s3_from_document(document=document, new_filename=new_filename) if 'reference' in request.form: reference = request.form['reference'] uploaded_document = UploadedResource(filename=new_filename, file_type=file_type, reference=reference, user_filename=filename) db.session.add(uploaded_document) # tie document to kyc application uploaded_document.kyc_application_id = business_details.id response_object = { 'message': 'Document uploaded', 'data': {'kyc_application': kyc_application_schema.dump(business_details).data} } return make_response(jsonify(response_object)), 201
def put(self, bank_account_id): put_data = request.get_json() kyc_application_id = put_data.get('kyc_application_id') bank_country = put_data.get('bank_country') routing_number = put_data.get('routing_number') account_number = put_data.get('account_number') currency = put_data.get('currency') if bank_account_id is None: return make_response( jsonify({'message': 'You need to provide a bank account ID'})), 400 bank_account = BankAccount.query.filter_by(id=bank_account_id).first() if kyc_application_id is None: kyc_application_id = bank_account.kyc_application_id business_details = KycApplication.query.filter_by( id=kyc_application_id).first() if not business_details: return make_response( jsonify({ 'message': 'Cannot find kyc for id {}'.format(kyc_application_id) })), 404 if business_details.organisation_id and AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be a superadmin to edit admin org KYC object' })), 401 if bank_account: bank_account.kyc_application_id = kyc_application_id bank_account.bank_country = bank_country bank_account.routing_number = routing_number bank_account.account_number = account_number bank_account.currency = currency response_object = { 'message': 'Bank account edited', 'data': { 'kyc_application': kyc_application_schema.dump(business_details).data } } return make_response(jsonify(response_object)), 200
def post(self, bank_account_id): post_data = request.get_json() kyc_application_id = post_data.get('kyc_application_id') bank_country = post_data.get('bank_country') routing_number = post_data.get('routing_number') account_number = post_data.get('account_number') currency = post_data.get('currency') business_details = KycApplication.query.filter_by(id=kyc_application_id).first() if not business_details: return make_response(jsonify({'message': 'Cannot find kyc for id {}'.format(kyc_application_id)})), 404 if business_details.organisation_id and AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response(jsonify({'message': 'Must be a superadmin to edit admin org KYC object'})), 401 if routing_number is None or account_number is None or bank_country is None or currency is None or kyc_application_id is None: response_object = { 'message': 'Need routing_number, account_number, bank_country, currency and business profile id', } return make_response(jsonify(response_object)), 400 # can't create a duplicate bank account at present bank_account = BankAccount.query.filter_by(routing_number=routing_number, account_number=account_number).first() if bank_account: response_object = { 'message': 'Bank account already exists', } return make_response(jsonify(response_object)), 400 # create new bank account create_bank_account = BankAccount( bank_country=bank_country, routing_number=routing_number, account_number=account_number, currency=currency, ) create_bank_account.kyc_application = business_details db.session.add(create_bank_account) response_object = { 'message': 'Bank account added', 'data': {'kyc_application': kyc_application_schema.dump(business_details).data} } return make_response(jsonify(response_object)), 201
def post(self): reference = None kyc_application_id = None if 'kyc_application_id' in request.form: kyc_application_id = request.form['kyc_application_id'] if 'document' not in request.files: return make_response(jsonify({'message': 'No File'})), 400 document = request.files['document'] filename = document.filename if kyc_application_id is None: return make_response(jsonify({'message': 'You must append documents to a business profile'})), 400 if filename == '': return make_response(jsonify({'message': 'No File'})), 400 if not allowed_file(filename): return make_response(jsonify({'message': 'Must be JPG, JPEG, PNG or PDF'})), 400 file_type = filename.rsplit('.', 1)[1].lower() new_filename = generate_new_filename(filename, file_type) saved_document = UploadedDocument.query.filter_by(filename=new_filename).first() if saved_document: return make_response(jsonify({'message': 'Document already exists'})), 400 save_to_s3_from_document(document=document, new_filename=new_filename) if 'reference' in request.form: reference = request.form['reference'] uploaded_document = UploadedDocument(filename=new_filename, file_type=file_type, reference=reference, user_filename=filename) db.session.add(uploaded_document) business_details = KycApplication.query.filter_by(id=kyc_application_id).first() # tie document to kyc application uploaded_document.kyc_application_id = business_details.id db.session.commit() response_object = { 'message': 'Document uploaded', 'data': {'kyc_application': kyc_application_schema.dump(business_details).data} } return make_response(jsonify(response_object)), 201
def get(self, kyc_application_id): user_id = request.args.get('user_id') trulioo_countries = request.args.get('trulioo_countries', None) trulioo_documents = request.args.get('trulioo_documents', None) country = request.args.get('country', None) if trulioo_countries: trulioo_countries = supported_countries return make_response(jsonify({'message': 'Trulioo Countries', 'data': {'kyc_application': {'trulioo_countries': trulioo_countries}}})), 200 if trulioo_documents: trulioo_documents = {country: supported_documents[country]} return make_response(jsonify({'message': 'Trulioo Countries', 'data': {'kyc_application': {'trulioo_documents': trulioo_documents}}})), 200 if AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'subadmin'}): if user_id: # user account KYC kyc_details = KycApplication.query.filter_by(user_id=user_id).first() else: # main organisation KYC kyc_details = KycApplication.query.filter_by(organisation_id=g.active_organisation.id).first() if kyc_details is None: response_object = { 'message': 'No business verification details found' } return make_response(jsonify(response_object)), 404 if user_id and AccessControl.has_suffient_role(g.user.roles, {'ADMIN': 'admin'}): response_object = { 'message': 'Successfully loaded business verification details', 'data': {'kyc_application': kyc_application_schema.dump(kyc_details).data} } return make_response(jsonify(response_object)), 200 else: # must be an individual (mobile) user account kyc_details = KycApplication.query.filter_by(user_id=g.user.id).first() if kyc_details is None: return make_response(jsonify({'message': 'No KYC object found for user.', 'data': {'kyc_application': {}}})) # displays kyc_status and kyc_actions state only. response_object = { 'message': 'Loaded KYC details', 'data': {'kyc_application': kyc_application_state_schema.dump(kyc_details).data} } return make_response(jsonify(response_object)), 200
def post(self, bank_account_id): post_data = request.get_json() kyc_application_id = post_data.get('kyc_application_id') bank_country = post_data.get('bank_country') routing_number = post_data.get('routing_number') account_number = post_data.get('account_number') currency = post_data.get('currency') if routing_number is None or account_number is None or bank_country is None or currency is None or kyc_application_id is None: response_object = { 'message': 'Need routing_number, account_number, bank_country, currency and business profile id', } return make_response(jsonify(response_object)), 400 # can't create a duplicate bank account at present bank_account = BankAccount.query.filter_by(routing_number=routing_number, account_number=account_number).first() if bank_account: response_object = { 'message': 'Bank account already exists', } return make_response(jsonify(response_object)), 400 # create new bank account create_bank_account = BankAccount( bank_country=bank_country, routing_number=routing_number, account_number=account_number, currency=currency, ) create_bank_account.kyc_application_id = kyc_application_id db.session.add(create_bank_account) db.session.commit() business_profile = KycApplication.query.filter_by(id=kyc_application_id).first() response_object = { 'message': 'Bank account added', 'data': {'kyc_application': kyc_application_schema.dump(business_profile).data} } return make_response(jsonify(response_object)), 201
def put(self, bank_account_id): put_data = request.get_json() kyc_application_id = put_data.get('kyc_application_id') bank_country = put_data.get('bank_country') routing_number = put_data.get('routing_number') account_number = put_data.get('account_number') currency = put_data.get('currency') if bank_account_id is None: return make_response(jsonify({'message': 'You need to provide a bank account ID'})), 400 bank_account = BankAccount.query.filter_by(id=bank_account_id).first() if kyc_application_id is None: kyc_application_id = bank_account.kyc_application_id business_profile = KycApplication.query.filter_by(id=kyc_application_id) if business_profile is None: return make_response(jsonify({'message': 'You need to provide a provide a valid business profile ID'})), 400 if bank_account: bank_account.kyc_application_id = kyc_application_id bank_account.bank_country = bank_country bank_account.routing_number = routing_number bank_account.account_number = account_number bank_account.currency = currency db.session.commit() response_object = { 'message': 'Bank account edited', 'data': {'kyc_application': kyc_application_schema.dump(business_profile).data} } return make_response(jsonify(response_object)), 200
def put(self, kyc_application_id): put_data = request.get_json() kyc_status = put_data.get('kyc_status') first_name = put_data.get('first_name') last_name = put_data.get('last_name') phone = put_data.get('phone') business_legal_name = put_data.get('business_legal_name') business_type = put_data.get('business_type') tax_id = put_data.get('tax_id') website = put_data.get('website') date_established = put_data.get('date_established') country = put_data.get('country') street_address = put_data.get('street_address') street_address_2 = put_data.get('street_address_2') city = put_data.get('city') region = put_data.get('region') postal_code = put_data.get('postal_code') beneficial_owners = put_data.get('beneficial_owners') if kyc_application_id is None: response_object = { 'message': 'Must provide business profile ID' } return make_response(jsonify(response_object)), 400 business = KycApplication.query.get(kyc_application_id) if not business: response_object = { 'message': 'Business Verification Profile not found' } return make_response(jsonify(response_object)), 404 # update business profile if kyc_status: business.kyc_status = kyc_status if first_name: business.first_name = first_name if last_name: business.last_name = last_name if phone: business.phone = phone if business_legal_name: business.business_legal_name = business_legal_name if business_type: business.business_type = business_type if tax_id: business.tax_id = tax_id if website: business.website = website if date_established: business.date_established = date_established if country: business.country = country if street_address: business.street_address = street_address if street_address_2: business.street_address_2 = street_address_2 if city: business.city = city if region: business.region = region if postal_code: business.postal_code = postal_code if beneficial_owners is not None: # filter empty beneficial owners beneficial_owners = [owner for owner in beneficial_owners if (owner['full_name'].strip(' ', ) != '')] if beneficial_owners: business.beneficial_owners = beneficial_owners db.session.commit() response_object = { 'message': 'Successfully Updated KYC Application.', 'data': { 'kyc_application': kyc_application_schema.dump(business).data } } return make_response(jsonify(response_object)), 200
def put(self, kyc_application_id): put_data = request.get_json() is_mobile = put_data.get('is_mobile') document_type = put_data.get('document_type') document_country = put_data.get('document_country') document_front_base64 = put_data.get('document_front_base64') # image document_back_base64 = put_data.get('document_back_base64') # image selfie_base64 = put_data.get('selfie_base64') # image kyc_status = put_data.get('kyc_status') first_name = put_data.get('first_name') last_name = put_data.get('last_name') phone = put_data.get('phone') business_legal_name = put_data.get('business_legal_name') business_type = put_data.get('business_type') tax_id = put_data.get('tax_id') website = put_data.get('website') date_established = put_data.get('date_established') country = put_data.get('country') street_address = put_data.get('street_address') street_address_2 = put_data.get('street_address_2') city = put_data.get('city') region = put_data.get('region') postal_code = put_data.get('postal_code') beneficial_owners = put_data.get('beneficial_owners') kyc_details = None if is_mobile: if document_type is None or document_country is None or document_front_base64 is None or selfie_base64 is None: return make_response( jsonify({'message': 'Must provide correct parameters'})), 400 kyc_details = KycApplication.query.filter_by( user_id=g.user.id).first() if kyc_details is None: return make_response( jsonify({'message': 'No KYC object found'})), 400 kyc_details.kyc_attempts = kyc_details.kyc_attempts + 1 if kyc_details.kyc_attempts > 2: # only allow two attempts kyc_details.kyc_status = 'REJECTED' db.session.commit() return make_response( jsonify( {'message': 'KYC attempts exceeded. Contact Support.'})), 400 kyc_details.kyc_status = 'PENDING' # handle document upload to s3 handle_kyc_documents(data=put_data, document_country=document_country, document_type=document_type, kyc_details=kyc_details) # Post verification message to slack post_verification_message(user=g.user) response_object = { 'message': 'Successfully Updated KYC Application.', 'data': { 'kyc_application': kyc_application_schema.dump(kyc_details).data } } return make_response(jsonify(response_object)), 200 if not is_mobile: if kyc_application_id is None: response_object = { 'message': 'Must provide business profile ID' } return make_response(jsonify(response_object)), 400 kyc_details = KycApplication.query.get(kyc_application_id) if not kyc_details: response_object = { 'message': 'Business Verification Profile not found' } return make_response(jsonify(response_object)), 404 if kyc_details.organisation_id and AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'superadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be a superadmin to edit admin org KYC object' })), 401 if AccessControl.has_suffient_role( g.user.roles, {'ADMIN': 'subadmin'}) is not True: return make_response( jsonify({ 'message': 'Must be a subadmin to edit any KYC object' })), 401 # update business profile if kyc_status: kyc_details.kyc_status = kyc_status if first_name: kyc_details.first_name = first_name if last_name: kyc_details.last_name = last_name if phone: kyc_details.phone = phone if business_legal_name: kyc_details.business_legal_name = business_legal_name if business_type: kyc_details.business_type = business_type if tax_id: kyc_details.tax_id = tax_id if website: kyc_details.website = website if date_established: kyc_details.date_established = date_established if country: kyc_details.country = country if street_address: kyc_details.street_address = street_address if street_address_2: kyc_details.street_address_2 = street_address_2 if city: kyc_details.city = city if region: kyc_details.region = region if postal_code: kyc_details.postal_code = postal_code if beneficial_owners is not None: # filter empty beneficial owners beneficial_owners = [ owner for owner in beneficial_owners if (owner['full_name'].strip(' ', ) != '') ] if beneficial_owners: kyc_details.beneficial_owners = beneficial_owners if kyc_status == 'PENDING': # Final web submission. Post verification message to slack post_verification_message(user=kyc_details.user) response_object = { 'message': 'Successfully Updated KYC Application.', 'data': { 'kyc_application': kyc_application_schema.dump(kyc_details).data } } return make_response(jsonify(response_object)), 200