Beispiel #1
0
def create_investment_agreement(agreement):
    # type: (CreateInvestmentAgreementTO) -> InvestmentAgreement
    app_user = users.User(agreement.app_user)
    username = get_iyo_username(app_user)
    tff_profile = get_tff_profile(username)
    if tff_profile.kyc.status != KYCStatus.VERIFIED:
        raise HttpBadRequestException('cannot_invest_not_kyc_verified')

    token_count_float = get_token_count(agreement.currency, agreement.amount)
    agreement_model = _create_investment_agreement(agreement.amount, agreement.currency, agreement.token,
                                                   token_count_float, username, 'manually_created', app_user,
                                                   status=agreement.status, paid_time=agreement.paid_time,
                                                   sign_time=agreement.sign_time)
    prefix, doc_content_base64 = agreement.document.split(',')
    content_type = prefix.split(';')[0].replace('data:', '')
    doc_content = base64.b64decode(doc_content_base64)
    agreement_model.put()

    pdf_name = InvestmentAgreement.filename(agreement_model.id)
    pdf_url = upload_to_gcs(pdf_name, doc_content, content_type)
    deferred.defer(_create_investment_agreement_iyo_see_doc, agreement_model.key, app_user, pdf_url,
                   content_type, send_sign_message=False, pdf_size=len(doc_content))

    return agreement_model
Beispiel #2
0
def send_payment_instructions(app_user, agreement_id, message_prefix, reminder=False):
    agreement = get_investment_agreement(agreement_id)
    if reminder and agreement.status != InvestmentAgreement.STATUS_SIGNED:
        return
    elif not reminder:
        deferred.defer(send_payment_instructions, app_user, agreement_id, message_prefix, True,
                       _countdown=14 * DAY, _queue=SCHEDULED_QUEUE)
    username = get_iyo_username(app_user)
    profile = get_tff_profile(username)
    params = {
        'currency': agreement.currency,
        'reference': agreement.reference,
        'message_prefix': message_prefix,
        'bank_account': get_bank_account_info(agreement.currency, agreement.payment_info,
                                              profile.kyc.utility_bill_verified),
    }

    if agreement.currency == 'BTC':
        params['amount'] = '{:.8f}'.format(agreement.amount)
        params['notes'] = u'Please inform us by email at [email protected] when you have made payment.'
    else:
        params['amount'] = '{:.2f}'.format(agreement.amount)
        params['notes'] = u'For the attention of ThreeFold FZC, a company incorporated under the laws of Sharjah, ' \
            u'United Arab Emirates, with registered office at SAIF Zone, SAIF Desk Q1-07-038/B'

    subject = u'ThreeFold payment instructions'
    msg = u"""%(message_prefix)sHere are your payment instructions for the purchase of your ThreeFold Tokens.

Please use the following transfer details:  
Amount: %(currency)s %(amount)s  
%(bank_account)s

%(notes)s

Please use %(reference)s as reference.""" % params
    send_message_and_email(app_user, msg, subject)
def _set_kyc_status(username, payload, current_user_id):
    if get_tff_profile(username).kyc.status == KYCStatus.SUBMITTED:
        set_kyc_status(username, payload, current_user_id)
def _kyc_part_2(message_flow_run_id, member, steps, end_id,
                end_message_flow_id, parent_message_key, tag, result_key,
                flush_id, flush_message_flow_id, service_identity,
                user_details, flow_params):
    parsed_flow_params = json.loads(flow_params)
    applicant = Applicant(nationality=parsed_flow_params['nationality'],
                          addresses=[Address()])
    documents = []
    username = get_iyo_username(user_details[0])
    if not username:
        logging.error('Could not find username for user %s!' % user_details[0])
        return create_error_message()
    profile = get_tff_profile(username)
    result = validate_kyc_status(profile)
    if isinstance(result, FlowMemberResultCallbackResultTO):
        return result

    def _set_attr(prop, value):
        if hasattr(applicant, prop):
            setattr(applicant, prop, value)
        elif prop.startswith('address_'):
            prop = prop.replace('address_', '')
            if prop == 'country':
                applicant.country = value
            setattr(applicant.addresses[0], prop, value)
        else:
            logging.warn('Ignoring unknown property %s with value %s', prop,
                         value)

    for step in steps:
        # In case of the flowcode_check_skip_passport step
        if not isinstance(step, FormFlowStepTO):
            continue
        step_id_split = step.step_id.split('_', 1)
        if step_id_split[0] == 'message':
            prop = step_id_split[
                1]  # 'type' from one of plugins.tff_backend.consts.kyc.kyc_steps
            step_value = step.form_result.result.get_value()
            if prop.startswith('national_identity_card'):
                side = None
                if prop.endswith('front'):
                    side = 'front'
                elif prop.endswith('back'):
                    side = 'back'
                documents.append({
                    'type': 'national_identity_card',
                    'side': side,
                    'value': step_value
                })
            elif prop == 'utility_bill':
                deferred.defer(save_utility_bill,
                               step_value,
                               profile.key,
                               _transactional=True)
            elif prop.startswith('passport'):
                documents.append({'type': 'passport', 'value': step_value})
            elif isinstance(step.form_result.result, UnicodeWidgetResultTO):
                _set_attr(prop, step.form_result.result.value.strip())
            elif isinstance(step.form_result.result, LongWidgetResultTO):
                # date step
                date = datetime.datetime.utcfromtimestamp(step_value).strftime(
                    '%Y-%m-%d')
                _set_attr(prop, date)
            else:
                logging.info('Ignoring step %s', step)
    try:
        if profile.kyc.applicant_id:
            applicant = update_applicant(profile.kyc.applicant_id, applicant)
        else:
            applicant = create_applicant(applicant)
            profile.kyc.applicant_id = applicant.id
    except ApiException as e:
        if e.status in xrange(400, 499):
            raise BusinessException('Invalid status code from onfido: %s %s' %
                                    (e.status, e.body))
        raise
    for document in documents:
        deferred.defer(upload_document,
                       applicant.id,
                       document['type'],
                       document['value'],
                       document.get('side'),
                       _transactional=True)
    profile.kyc.set_status(KYCStatus.SUBMITTED.value, username)
    profile.put()
    deferred.defer(index_profile, Profile.create_key(username))

    # Automatically set status to PENDING_APPROVAL after 5 minutes
    payload = SetKYCPayloadTO(status=KYCStatus.PENDING_APPROVAL.value,
                              comment='Verification started automatically')
    deferred.defer(_set_kyc_status,
                   username,
                   payload,
                   current_user_id=username,
                   _countdown=300,
                   _queue=SCHEDULED_QUEUE)
Beispiel #5
0
def api_get_tff_user(username):
    username = username.decode('utf-8')  # username must be unicode
    return TffProfileTO.from_model(get_tff_profile(username))