def application_update(id, step=None):
    old_application = data_api_client.get_application(id)
    if not can_user_view_application(old_application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(old_application) and not current_user.has_role('admin'):
        return redirect(url_for('.submit_application', id=id))

    json = request.content_type == 'application/json'
    form_data = from_response(request)
    application = form_data['application'] if json else form_data

    try:
        del application['status']
    except KeyError:
        pass

    result = data_api_client.update_application(id, application)

    if json:
        try:
            appdata = result['application']
            del appdata['links']
        except KeyError:
            pass
        return jsonify(result)
    else:
        return redirect(url_for('.render_application', id=id, step=form_data['next_step_slug']))
def application_update(id, step=None):
    old_application = data_api_client.get_application(id)
    if not can_user_view_application(old_application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(
            old_application) and not current_user.has_role('admin'):
        return redirect(url_for('.submit_application', id=id))

    json = request.content_type == 'application/json'
    form_data = from_response(request)
    application = form_data['application'] if json else form_data

    try:
        del application['status']
    except KeyError:
        pass

    result = data_api_client.update_application(id, application)

    if json:
        try:
            appdata = result['application']
            del appdata['links']
        except KeyError:
            pass
        return jsonify(result)
    else:
        return redirect(
            url_for('.render_application',
                    id=id,
                    step=form_data['next_step_slug']))
def render_application(id, step=None, substep=None):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(application) and not current_user.has_role('admin'):
        return redirect(url_for('.submit_application', id=id))

    props = dict(application)
    props['basename'] = url_for('.render_application', id=id, step=None)
    props['form_options'] = {
        'action': url_for('.render_application', id=id, step=step),
        'submit_url': url_for('.submit_application', id=id),
        'document_url': url_for('.upload_single_file', id=id, slug=''),
        'authorise_url': url_for('.authorise_application', id=id),
        'user_name': current_user.name,
        'user_email': current_user.email_address
    }

    # Add service pricing
    if 'services' in application['application']:
        props['application']['domains'] = {'prices': {'maximum': {}}}
        for domain_name in application['application']['services'].keys():
            props['application']['domains']['prices']['maximum'][domain_name] = (
                application['domains']['prices']['maximum'][domain_name]
            )

    widget = application['application'].get('type') == 'edit' and 'ProfileEdit' or 'ApplicantSignup'
    rendered_component = render_component('bundles/SellerRegistration/{}Widget.js'.format(widget), props)

    return render_template(
        '_react.html',
        component=rendered_component
    )
def render_application(id, step=None, substep=None):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(
            application) and not current_user.has_role('admin'):
        return redirect(url_for('.submit_application', id=id))

    props = dict(application)
    props['basename'] = url_for('.render_application', id=id, step=None)
    props['form_options'] = {
        'action': url_for('.render_application', id=id, step=step),
        'submit_url': url_for('.submit_application', id=id),
        'document_url': url_for('.upload_single_file', id=id, slug=''),
        'authorise_url': url_for('.authorise_application', id=id),
        'user_name': current_user.name,
        'user_email': current_user.email_address
    }

    # Add service pricing
    if 'services' in application['application']:
        props['application']['domains'] = {'prices': {'maximum': {}}}
        for domain_name in application['application']['services'].keys():
            props['application']['domains']['prices']['maximum'][
                domain_name] = (
                    application['domains']['prices']['maximum'][domain_name])

    widget = application['application'].get(
        'type') == 'edit' and 'ProfileEdit' or 'ApplicantSignup'
    rendered_component = render_component(
        'bundles/SellerRegistration/{}Widget.js'.format(widget), props)

    return render_template('_react.html', component=rendered_component)
def my_application():
    # if an applicant has no application, create a new one for them
    if current_user.role == 'applicant' and current_user.application_id is None:
        application = data_api_client.req.applications().post({
            'application': {
                'status': 'saved',
                'framework': 'digital-marketplace'
            },
            'updated_by':
            current_user.email_address,
            'name':
            current_user.name
        })['application']
        data_api_client.req.users(current_user.id).post({
            'users': {
                'application_id': application['id']
            },
            'updated_by':
            current_user.email_address
        })
    else:
        try:
            application = data_api_client.get_application(
                current_user.application_id)['application']
        except APIError as e:
            current_app.logger.error(e)
            abort(e.status_code)

    # if application not in saved state, it has been submitted so show message after submit
    if application.get('status', 'saved') != 'saved':
        return redirect(url_for('.submit_application', id=application['id']))
    else:
        return redirect(
            url_for('.render_application', id=application['id'], step="start"))
def upload_single_file(id, slug):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(application) and not current_user.has_role('admin'):
        abort(400, 'Application already submitted')

    return s3_upload_file_from_request(request, slug, os.path.join(S3_PATH, str(id)))
def download_single_file(id, slug):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application) and not current_user.has_role('admin'):
        abort(403, 'Not authorised to access application')

    file = s3_download_file(slug, os.path.join(S3_PATH, str(id)))

    mimetype = mimetypes.guess_type(slug)[0] or 'binary/octet-stream'
    return Response(file, mimetype=mimetype)
def submit_application(id):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')

    if application['application']['status'] == 'saved':
        data_api_client.req.applications(id).submit().post(data={'user_id': current_user.id})

    return render_template('suppliers/application_submitted.html',
                           application_type=application['application'].get('type'))
def upload_single_file(id, slug):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(
            application) and not current_user.has_role('admin'):
        abort(400, 'Application already submitted')

    return s3_upload_file_from_request(request, slug,
                                       os.path.join(S3_PATH, str(id)))
def discard_application(id):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(application):
        return redirect(url_for('.submit_application', id=id))

    data_api_client.req.applications(id).delete(data={"updated_by": current_user.email_address})

    flash('Your profile changes have been discarded', 'success')
    return redirect(url_for('.dashboard'))
def download_single_file(id, slug):
    application = data_api_client.get_application(id)
    if not can_user_view_application(
            application) and not current_user.has_role('admin'):
        abort(403, 'Not authorised to access application')

    mimetype = mimetypes.guess_type(slug)[0] or 'binary/octet-stream'
    return Response(s3_download_file(
        current_app.config.get('S3_BUCKET_NAME', None), slug,
        os.path.join(S3_PATH, str(id))),
                    mimetype=mimetype)
def discard_application(id):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(application):
        return redirect(url_for('.submit_application', id=id))

    data_api_client.req.applications(id).delete(
        data={"updated_by": current_user.email_address})

    flash('Your profile changes have been discarded', 'success')
    return redirect(url_for('.dashboard'))
def submit_application(id):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')

    if application['application']['status'] == 'saved':
        data_api_client.req.applications(id).submit().post(
            data={'user_id': current_user.id})
        current_user.notification_count = None

    return render_template(
        'suppliers/application_submitted.html',
        application_type=application['application'].get('type'))
def authorise_application(id):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(application):
        return redirect(url_for('.submit_application', id=id))

    application = application['application']
    url = url_for('main.render_application',
                  id=id,
                  step='submit',
                  _external=True)
    user_json = data_api_client.get_user(email_address=application['email'])
    template = 'emails/create_authorise_email_has_account.html'

    if not user_json:
        token_data = {
            'id': id,
            'name': application['representative'],
            'email_address': application['email']
        }
        token = generate_application_invitation_token(token_data)
        url = url_for('main.render_create_application',
                      token=token,
                      _external=True)
        template = 'emails/create_authorise_email_no_account.html'

    email_body = render_template(
        template,
        url=url,
        name=application['representative'],
        business_name=application['name'],
    )

    try:
        send_email(application['email'], email_body,
                   current_app.config['AUTHREP_EMAIL_SUBJECT'],
                   current_app.config['INVITE_EMAIL_FROM'],
                   current_app.config['INVITE_EMAIL_NAME'])
    except EmailError as e:
        rollbar.report_exc_info()
        current_app.logger.error(
            'Authorisation email failed to send. '
            'error {error}',
            extra={'error': six.text_type(e)})
        abort(503, 'Failed to send user invite reset')

    return render_template('suppliers/authorisation_submitted.html',
                           name=application['representative'],
                           email_address=application['email'],
                           subject=current_app.config['AUTHREP_EMAIL_SUBJECT'])
def authorise_application(id):
    application = data_api_client.get_application(id)
    if not can_user_view_application(application):
        abort(403, 'Not authorised to access application')
    if is_application_submitted(application):
        return redirect(url_for('.submit_application', id=id))

    application = application['application']
    url = url_for('main.render_application', id=id, step='submit', _external=True)
    user_json = data_api_client.get_user(email_address=application['email'])
    template = 'emails/create_authorise_email_has_account.html'

    if not user_json:
        token_data = {'id': id, 'name': application['representative'], 'email_address': application['email']}
        token = generate_application_invitation_token(token_data)
        url = url_for('main.render_create_application', token=token, _external=True)
        template = 'emails/create_authorise_email_no_account.html'

    email_body = render_template(
        template,
        url=url,
        name=application['representative'],
        business_name=application['name'],
    )

    try:
        send_email(
            application['email'],
            email_body,
            current_app.config['AUTHREP_EMAIL_SUBJECT'],
            current_app.config['INVITE_EMAIL_FROM'],
            current_app.config['INVITE_EMAIL_NAME']
        )
    except EmailError as e:
        rollbar.report_exc_info()
        current_app.logger.error(
            'Authorisation email failed to send. '
            'error {error}',
            extra={'error': six.text_type(e)}
        )
        abort(503, 'Failed to send user invite reset')

    return render_template('suppliers/authorisation_submitted.html',
                           name=application['representative'],
                           email_address=application['email'],
                           subject=current_app.config['AUTHREP_EMAIL_SUBJECT'])
def my_application():
    # if an applicant has no application, create a new one for them
    if current_user.role == 'applicant' and current_user.application_id is None:
        application = data_api_client.req.applications().post({
            'application': {'status': 'saved', 'framework': 'digital-marketplace'},
            'updated_by': current_user.email_address,
            'name': current_user.name
        })['application']
        data_api_client.req.users(current_user.id).post({'users': {'application_id': application['id']},
                                                         'updated_by': current_user.email_address})
    else:
        try:
            application = data_api_client.get_application(current_user.application_id)['application']
        except APIError as e:
            current_app.logger.error(e)
            abort(e.status_code)

    # if application not in saved state, it has been submitted so show message after submit
    if application.get('status', 'saved') != 'saved':
        return redirect(url_for('.submit_application', id=application['id']))
    else:
        return redirect(url_for('.render_application', id=application['id'], step="start"))