Example #1
0
    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
Example #2
0
    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
Example #6
0
    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
Example #8
0
    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
Example #9
0
    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
Example #10
0
    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