def get_supplier(code):
    if not can_view_supplier_page(code):
        flash('buyer-role-required', 'error')
        return current_app.login_manager.unauthorized()

    supplier = DataAPIClient().get_supplier(code)['supplier']

    supplier["categories"] = list(set(
        price['serviceRole']['role'].replace('Junior ', '').replace('Senior ', '')  # Mind the white space after Junior
        for price in supplier['prices']
    ))

    supplier["caseStudies"] = []
    for casestudy_id in supplier['case_study_ids']:
        casestudy = DataAPIClient().get_case_study(casestudy_id)['caseStudy']
        supplier["caseStudies"].append(casestudy)

    owns_profile = user_owns_page(code)

    if request_wants_json():
        return jsonify(dict(supplier))

    # add business/authorized representative contact details
    if len(supplier['contacts']) > 0:
        supplier['contact_email'] = supplier.get('contact_email') or supplier['contacts'][0]['email']
        supplier['contact_phone'] = supplier.get('contact_phone') or supplier['contacts'][0]['phone']
        supplier['contact_name'] = supplier.get('contact_name') or supplier['contacts'][0]['name']
        supplier['representative'] = supplier.get('representative') or supplier['contacts'][0]['name']
    props = {"application": {key: supplier[key] for key in supplier if key not in ['disclosures']}}
    props['application']['case_study_url'] = '/case-study/'
    props['application']['public_profile'] = not owns_profile
    props['application']['recruiter'] = 'yes' if supplier.get('is_recruiter') == 'true' else 'no'
    props['application']['digital_marketplace_panel'] = False
    digital_marketplace_framework = data_api_client.req.frameworks('digital-marketplace').get()
    for framework in supplier.get('frameworks', []):
        if framework['framework_id'] == digital_marketplace_framework['frameworks']['id']:
            props['application']['digital_marketplace_panel'] = True
    props['application']['dsp_panel'] = len(supplier.get('domains', {'legacy': []})['legacy']) > 0
    props['basename'] = url_for('.get_supplier', code=code)
    props['form_options'] = {
        'action': "/sellers/edit",
        'submit_url': "/sellers/edit"
    }

    rendered_component = render_component('bundles/SellerRegistration/ApplicationPreviewWidget.js', props)

    return render_template(
        '_react.html',
        page_title=supplier.get('name'),
        component=rendered_component,
        breadcrumb_items=[
            {'link': url_for('main.index'), 'label': 'Home'},
            {'link': url_for('main.supplier_search'), 'label': 'Seller catalogue'},
            {'label': 'Seller details'}
        ],
        main_class='collapse' if not owns_profile else None
    )
def get_supplier_case_study(casestudy_id):
    casestudy = DataAPIClient().get_case_study(casestudy_id)['caseStudy']

    supplier_code = casestudy.get('supplierCode') if casestudy else None
    if supplier_code:
        supplier = DataAPIClient().get_supplier(supplier_code)['supplier']
        casestudy['supplier_name'] = supplier['name']
        casestudy['supplier_url'] = url_for('main.get_supplier',
                                            code=supplier_code)
    else:
        # buyers do not get referee data
        if 'refereeEmail' in casestudy:
            del casestudy['refereeEmail']
        if 'refereeName' in casestudy:
            del casestudy['refereeName']
        if 'refereePosition' in casestudy:
            del casestudy['refereePosition']

    if not can_view_supplier_page(supplier_code):
        flash('buyer-role-required', 'error')
        return current_app.login_manager.unauthorized()

    if request_wants_json():
        return jsonify(casestudy)

    rendered_component = render_component(
        'bundles/CaseStudy/CaseStudyViewWidget.js',
        {"casestudy": dict(casestudy)})
    return render_template('_react.html',
                           breadcrumb_items=[{
                               'link': url_for('main.index'),
                               'label': 'Home'
                           }, {
                               'link':
                               url_for('main.supplier_search'),
                               'label':
                               'Seller catalogue'
                           }, {
                               'link':
                               url_for('main.get_supplier',
                                       code=supplier_code),
                               'label':
                               'Seller details'
                           }, {
                               'label': 'Case Study'
                           }],
                           component=rendered_component)
Ejemplo n.º 3
0
def get_supplier_case_study(casestudy_id):
    casestudy = DataAPIClient().get_case_study(casestudy_id)['caseStudy']

    supplier_code = casestudy.get('supplierCode') if casestudy else None
    if not supplier_code or not user_owns_page(supplier_code):
        abort(404)
    supplier = DataAPIClient().get_supplier(supplier_code)['supplier']
    casestudy['supplier_name'] = supplier['name']
    casestudy['supplier_url'] = url_for('main.get_supplier',
                                        code=supplier_code)

    if request_wants_json():
        return jsonify(casestudy)

    rendered_component = render_component(
        'bundles/CaseStudy/CaseStudyViewWidget.js',
        {"casestudy": dict(casestudy)})
    return render_template('_react.html',
                           page_title=casestudy.get('title'),
                           breadcrumb_items=[{
                               'link': url_for('main.index'),
                               'label': 'Home'
                           }, {
                               'link':
                               url_for('main.supplier_search'),
                               'label':
                               'Seller catalogue'
                           }, {
                               'link':
                               url_for('main.get_supplier',
                                       code=supplier_code),
                               'label':
                               'Seller details'
                           }, {
                               'label': 'Case Study'
                           }],
                           component=rendered_component)
def get_supplier_case_study(casestudy_id):
    casestudy = DataAPIClient().get_case_study(casestudy_id)['caseStudy']

    supplier_code = casestudy.get('supplierCode') if casestudy else None
    if supplier_code:
        supplier = DataAPIClient().get_supplier(supplier_code)['supplier']
        casestudy['supplier_name'] = supplier['name']
        casestudy['supplier_url'] = url_for('main.get_supplier', code=supplier_code)
    else:
        # buyers do not get referee data
        if 'refereeEmail' in casestudy:
            del casestudy['refereeEmail']
        if 'refereeName' in casestudy:
            del casestudy['refereeName']
        if 'refereePosition' in casestudy:
            del casestudy['refereePosition']

    if not can_view_supplier_page(supplier_code):
        flash('buyer-role-required', 'error')
        return current_app.login_manager.unauthorized()

    if request_wants_json():
        return jsonify(casestudy)

    rendered_component = render_component('bundles/CaseStudy/CaseStudyViewWidget.js', {"casestudy": dict(casestudy)})
    return render_template(
        '_react.html',
        page_title=casestudy.get('title'),
        breadcrumb_items=[
            {'link': url_for('main.index'), 'label': 'Home'},
            {'link': url_for('main.supplier_search'), 'label': 'Seller catalogue'},
            {'link': url_for('main.get_supplier', code=supplier_code), 'label': 'Seller details'},
            {'label': 'Case Study'}
        ],
        component=rendered_component
    )
def supplier_search():

    sort_by = request.args.get('sort_by', 'a-z')
    sort_order = request.args.get('sort_order', 'asc')
    if sort_order not in ('asc', 'desc'):
        abort(400, 'Invalid sort_order: {}'.format(sort_order))
    sort_terms = request.args.getlist('sort_term')
    keyword = request.args.get('keyword', None)

    selected_roles = set(request.args.getlist('role'))
    selected_seller_types = set(request.args.getlist('type'))

    selected_seller_types_keys = [
        to_seller_type_key(x)
        for x
        in selected_seller_types
    ]

    if not sort_terms:  # Sort by A-Z for default
        sort_terms = ['name']

    data_api_client = DataAPIClient()
    real_data_api_client = dmapiclient.DataAPIClient()
    real_data_api_client.init_app(current_app)

    roles = get_all_domains(data_api_client)
    if 'Change, Training and Transformation' in roles:
        roles.remove('Change, Training and Transformation')  # remove from filter
    role_filters = {role: role in selected_roles for role in roles}

    sort_queries = []

    allowed_sort_terms = set(('name',))  # Limit what can be sorted

    for sort_term in sort_terms:
        if sort_term in allowed_sort_terms:
            if sort_term == 'name':  # Use 'name' in url to keep it clean but query needs to search on not analyzed.
                sort_term = 'name.not_analyzed'

            spec = {"order": sort_order, "mode": "min"}

            if sort_by:
                spec['sort_by'] = sort_by

            sort_queries.append({
                sort_term: spec
            })
        else:
            abort(400, 'Invalid sort_term: {}'.format(sort_term))

    query_contents = {}
    filter_terms = {}

    product_search_parameters = dict(
        sort_dir=sort_order,
        seller_types=selected_seller_types_keys,
        search_term=keyword,
        domains=list(selected_roles)
    )

    if selected_roles:
        for each in selected_roles:
            if each not in roles:
                abort(400, 'Invalid role: {}'.format(each))
        filter_terms = {"domains.assessed": list(selected_roles)}

    if selected_seller_types:
        filter_terms['seller_types'] = list(selected_seller_types_keys)

    if filter_terms:
        query_contents['filtered'] = {
            "query": {
                "match_all": {}
            },
            "filter": {
                "terms": filter_terms,
            }
        }

    if keyword:
        query_contents['match_phrase_prefix'] = {
            "name": keyword
        }
    else:
        query_contents['match_all'] = {}

    query = {
        "query": query_contents,
        "sort": sort_queries
    }

    try:
        page = int(request.args.get('page', 1))
    except ValueError:
        abort(400, 'Invalid page number: {}'.format(request.args['page']))
    results_from = (page - 1) * SUPPLIER_RESULTS_PER_PAGE

    page_params = {
        'from': results_from,
        'size': SUPPLIER_RESULTS_PER_PAGE
    }

    query.update(product_search_parameters)

    with ThreadPoolExecutor(max_workers=16) as executor:
        futures_to_result = {
            executor.submit(
                data_api_client.find_suppliers,
                data=query,
                params=page_params): 'suppliers',
        }
        results = {}

        for future in as_completed(futures_to_result):
            results[futures_to_result[future]] = future.result()

    response = results['suppliers']
    products_response = results.get('products')
    casestudies_response = results.get('casestudies')

    results = []
    services = {}
    for supplier in response['hits']['hits']:
        details = supplier['_source']

        domains = details['domains']

        tags = domains['assessed'] + domains['unassessed']

        services = {}
        for tag in sorted(tags):
            services[tag] = True
        seller_type = details.get('seller_type', {})

        is_recruiter = details.get('is_recruiter', False)
        if is_recruiter == 'true' and 'recruiter' not in seller_type.keys():
            seller_type['recruitment'] = True

        result = {
            'title': details['name'],
            'description': details['summary'],
            'link': url_for('.get_supplier', code=details['code']),
            'services': services,
            'badges': seller_type
        }

        results.append(result)

    num_results = response['hits']['total']

    seller_type_filters = {st: to_seller_type_key(st) in selected_seller_types_keys for st in SELLER_TYPES.keys()}

    products_results = []

    if products_response:
        for p in products_response['hits']['hits']:
            details = p['_source']

            supplier = dict()
            supplier['name'] = details.get('supplierName')

            supplier['profile_url'] = '/supplier/%s' % details['supplier_code']
            supplier['support_url'] = details.get('support')
            services = {}
            result = {
                'title': details['name'],
                'description': details['summary'],
                'link': details['website'],
                'services': services,
                'badges': details.get('seller_type', {}),
                'supplier': supplier,
                'pricing': details['pricing']
            }

            products_results.append(result)

    num_products_results = products_response['hits']['total'] if products_response else 0

    casestudies_results = None

    if casestudies_response:
        casestudies_results = []
        for p in casestudies_response['hits']['hits']:
            details = p['_source']

            domains = details.get('domains', {})

            supplier = dict()
            supplier['name'] = details.get('supplierName')
            supplier['profile_url'] = '/supplier/%s' % details.get('supplierCode')

            tags = domains.get('assessed', []) + domains.get('unassessed', [])

            services = {}
            for tag in sorted(tags):
                services[tag] = True

            result = {
                'title': details['title'],
                'description': smart_truncate(details.get('approach', '')),
                'link': url_for('.get_supplier_case_study', casestudy_id=details['id']),
                'services': services,
                'badges': details.get('seller_type', {}),
                'supplier': supplier,
                'pricing': details.get('pricing'),
                'case_study_service': details.get('service')
            }
            casestudies_results.append(result)

    num_casestudies_results = casestudies_response['hits']['total'] if casestudies_response else 0

    def get_pagination(result_count):
        pages = get_page_list(SUPPLIER_RESULTS_PER_PAGE, result_count, page)

        return {
            'pages': pages,
            'page': page,
            'pageCount': pages[-1],
            'total': result_count
        }

    props = {
        'form_options': {
            'action': url_for('.supplier_search')
        },
        'search': {
            'results': results[:SUPPLIER_RESULTS_PER_PAGE],
            'products': products_results[:SUPPLIER_RESULTS_PER_PAGE],
            'casestudies': casestudies_results[:SUPPLIER_RESULTS_PER_PAGE] if casestudies_results else None,
            'keyword': keyword,
            'sort_by': sort_by,
            'view': request.args.get('view', 'sellers'),
            'role': role_filters,
            'type': seller_type_filters,
            'user_role': None if current_user.is_anonymous else current_user.role
        },
        'pagination': {
            'sellers': get_pagination(num_results),
            'products': get_pagination(num_products_results),
            'casestudies': get_pagination(num_casestudies_results)
        },
        'basename': url_for('.supplier_search')
    }

    if request_wants_json():
        return jsonify(dict(props))
    else:
        component = render_component('bundles/Search/SearchWidget.js', props)
        return render_template(
            '_react.html',
            page_title='Seller catalogue',
            component=component,
            breadcrumb_items=[
                {'link': url_for('main.index'), 'label': 'Home'},
                {'label': 'Seller catalogue'}
            ]
        )
Ejemplo n.º 6
0
def get_supplier(code):
    if not can_view_supplier_page(code):
        flash('buyer-role-required', 'error')
        return current_app.login_manager.unauthorized()

    supplier = DataAPIClient().get_supplier(code)['supplier']

    supplier["categories"] = list(
        set(price['serviceRole']['role'].replace('Junior ', '').replace(
            'Senior ', '')  # Mind the white space after Junior
            for price in supplier['prices']))

    owns_profile = user_owns_page(code)

    supplier["caseStudies"] = []
    if owns_profile:
        for casestudy_id in supplier['case_study_ids']:
            casestudy = DataAPIClient().get_case_study(
                casestudy_id)['caseStudy']
            supplier["caseStudies"].append(casestudy)
    else:
        supplier['case_studies'] = []
        supplier['case_study_ids'] = []

    if request_wants_json():
        return jsonify(dict(supplier))

    # add business/authorized representative contact details
    if len(supplier['contacts']) > 0:
        supplier['contact_email'] = supplier.get(
            'contact_email') or supplier['contacts'][0]['email']
        supplier['contact_phone'] = supplier.get(
            'contact_phone') or supplier['contacts'][0]['phone']
        supplier['contact_name'] = supplier.get(
            'contact_name') or supplier['contacts'][0]['name']
        supplier['representative'] = supplier.get(
            'representative') or supplier['contacts'][0]['name']
    props = {
        "application":
        {key: supplier[key]
         for key in supplier if key not in ['disclosures']}
    }
    props['application']['case_study_url'] = '/case-study/'
    props['application']['public_profile'] = not owns_profile
    props['application']['recruiter'] = 'yes' if supplier.get(
        'is_recruiter') == 'true' else 'no'
    props['application']['digital_marketplace_panel'] = False
    digital_marketplace_framework = data_api_client.req.frameworks(
        'digital-marketplace').get()
    for framework in supplier.get('frameworks', []):
        if framework['framework_id'] == digital_marketplace_framework[
                'frameworks']['id']:
            props['application']['digital_marketplace_panel'] = True
    props['application']['dsp_panel'] = len(
        supplier.get('domains', {'legacy': []})['legacy']) > 0
    props['basename'] = url_for('.get_supplier', code=code)
    props['form_options'] = {
        'action': "/sellers/edit",
        'submit_url': "/sellers/edit"
    }

    rendered_component = render_component(
        'bundles/SellerRegistration/ApplicationPreviewWidget.js', props)

    return render_template('_react.html',
                           page_title=supplier.get('name'),
                           component=rendered_component,
                           breadcrumb_items=[{
                               'link': url_for('main.index'),
                               'label': 'Home'
                           }, {
                               'link':
                               url_for('main.supplier_search'),
                               'label':
                               'Seller catalogue'
                           }, {
                               'label': 'Seller details'
                           }],
                           main_class='collapse' if not owns_profile else None)
def supplier_search():

    sort_by = request.args.get('sort_by', 'a-z')
    sort_order = request.args.get('sort_order', 'asc')
    if sort_order not in ('asc', 'desc'):
        abort(400, 'Invalid sort_order: {}'.format(sort_order))
    sort_terms = request.args.getlist('sort_term')
    keyword = request.args.get('keyword', None)

    selected_roles = set(request.args.getlist('role'))
    selected_seller_types = set(request.args.getlist('type'))

    selected_seller_types_keys = [
        to_seller_type_key(x) for x in selected_seller_types
    ]

    if not sort_terms:  # Sort by A-Z for default
        sort_terms = ['name']

    data_api_client = DataAPIClient()
    real_data_api_client = dmapiclient.DataAPIClient()
    real_data_api_client.init_app(current_app)

    roles = get_all_domains(data_api_client)

    role_filters = {role: role in selected_roles for role in roles}

    sort_queries = []

    allowed_sort_terms = set(('name', ))  # Limit what can be sorted

    for sort_term in sort_terms:
        if sort_term in allowed_sort_terms:
            if sort_term == 'name':  # Use 'name' in url to keep it clean but query needs to search on not analyzed.
                sort_term = 'name.not_analyzed'

            spec = {"order": sort_order, "mode": "min"}

            if sort_by:
                spec['sort_by'] = sort_by

            sort_queries.append({sort_term: spec})
        else:
            abort(400, 'Invalid sort_term: {}'.format(sort_term))

    query_contents = {}
    filter_terms = {}

    product_search_parameters = dict(sort_dir=sort_order,
                                     seller_types=selected_seller_types_keys,
                                     search_term=keyword,
                                     domains=list(selected_roles))

    if selected_roles:
        for each in selected_roles:
            if each not in roles:
                abort(400, 'Invalid role: {}'.format(each))
        filter_terms = {"domains.assessed": list(selected_roles)}

    if selected_seller_types:
        filter_terms['seller_types'] = list(selected_seller_types_keys)

    if filter_terms:
        query_contents['filtered'] = {
            "query": {
                "match_all": {}
            },
            "filter": {
                "terms": filter_terms,
            }
        }

    if keyword:
        query_contents['match_phrase_prefix'] = {"name": keyword}
    else:
        query_contents['match_all'] = {}

    query = {"query": query_contents, "sort": sort_queries}

    try:
        page = int(request.args.get('page', 1))
    except ValueError:
        abort(400, 'Invalid page number: {}'.format(request.args['page']))
    results_from = (page - 1) * SUPPLIER_RESULTS_PER_PAGE

    page_params = {'from': results_from, 'size': SUPPLIER_RESULTS_PER_PAGE}

    query.update(product_search_parameters)

    products_requester = real_data_api_client.req.products().search()
    casestudies_requester = real_data_api_client.req.casestudies().search()

    with ThreadPoolExecutor(max_workers=16) as executor:
        futures_to_result = {
            executor.submit(data_api_client.find_suppliers,
                            data=query,
                            params=page_params):
            'suppliers',
            executor.submit(products_requester.get,
                            data=query,
                            params=page_params):
            'products',
            executor.submit(casestudies_requester.get,
                            data=query,
                            params=page_params):
            'casestudies'
        }
        results = {}

        for future in as_completed(futures_to_result):
            results[futures_to_result[future]] = future.result()

    response = results['suppliers']
    products_response = results['products']
    casestudies_response = results.get('casestudies')

    results = []
    services = {}
    for supplier in response['hits']['hits']:
        details = supplier['_source']

        domains = details['domains']

        tags = domains['assessed'] + domains['unassessed']

        services = {}
        for tag in sorted(tags):
            services[tag] = True
        seller_type = details.get('seller_type', {})

        is_recruiter = details.get('is_recruiter', False)
        if is_recruiter == 'true' and 'recruiter' not in seller_type.keys():
            seller_type['recruitment'] = True

        result = {
            'title': details['name'],
            'description': details['summary'],
            'link': url_for('.get_supplier', code=details['code']),
            'services': services,
            'badges': seller_type
        }

        results.append(result)

    num_results = response['hits']['total']

    seller_type_filters = {
        st: to_seller_type_key(st) in selected_seller_types_keys
        for st in SELLER_TYPES.keys()
    }

    products_results = []

    for p in products_response['hits']['hits']:
        details = p['_source']

        supplier = dict()
        supplier['name'] = details.get('supplierName')

        supplier['profile_url'] = '/supplier/%s' % details['supplier_code']
        supplier['support_url'] = details.get('support')
        services = {}
        result = {
            'title': details['name'],
            'description': details['summary'],
            'link': details['website'],
            'services': services,
            'badges': details.get('seller_type', {}),
            'supplier': supplier,
            'pricing': details['pricing']
        }

        products_results.append(result)

    num_products_results = products_response['hits']['total']

    casestudies_results = None

    if current_user.is_authenticated and current_user.role == 'buyer':
        casestudies_results = []
        for p in casestudies_response['hits']['hits']:
            details = p['_source']

            domains = details.get('domains', {})

            supplier = dict()
            supplier['name'] = details.get('supplierName')
            supplier['profile_url'] = '/supplier/%s' % details.get(
                'supplierCode')

            tags = domains.get('assessed', []) + domains.get('unassessed', [])

            services = {}
            for tag in sorted(tags):
                services[tag] = True

            result = {
                'title':
                details['title'],
                'description':
                smart_truncate(details.get('approach', '')),
                'link':
                url_for('.get_supplier_case_study',
                        casestudy_id=details['id']),
                'services':
                services,
                'badges':
                details.get('seller_type', {}),
                'supplier':
                supplier,
                'pricing':
                details.get('pricing'),
                'case_study_service':
                details.get('service')
            }
            casestudies_results.append(result)

    num_casestudies_results = casestudies_response['hits'][
        'total'] if casestudies_response else 0

    def get_pagination(result_count):
        pages = get_page_list(SUPPLIER_RESULTS_PER_PAGE, result_count, page)

        return {
            'pages': pages,
            'page': page,
            'pageCount': pages[-1],
            'total': result_count
        }

    props = {
        'form_options': {
            'action': url_for('.supplier_search')
        },
        'search': {
            'results':
            results[:SUPPLIER_RESULTS_PER_PAGE],
            'products':
            products_results[:SUPPLIER_RESULTS_PER_PAGE],
            'casestudies':
            casestudies_results[:SUPPLIER_RESULTS_PER_PAGE]
            if casestudies_results else None,
            'keyword':
            keyword,
            'sort_by':
            sort_by,
            'view':
            request.args.get('view', 'sellers'),
            'role':
            role_filters,
            'type':
            seller_type_filters,
            'user_role':
            None if current_user.is_anonymous else current_user.role
        },
        'pagination': {
            'sellers': get_pagination(num_results),
            'products': get_pagination(num_products_results),
            'casestudies': get_pagination(num_casestudies_results)
        },
        'basename': url_for('.supplier_search')
    }

    if request_wants_json():
        return jsonify(dict(props))
    else:
        component = render_component('bundles/Search/SearchWidget.js', props)
        return render_template('_react.html',
                               component=component,
                               breadcrumb_items=[{
                                   'link': url_for('main.index'),
                                   'label': 'Home'
                               }, {
                                   'label': 'Seller catalogue'
                               }])