def test_edit_empty_requirements_document_does_not_update_requirements_document(self, briefs):
        rfx_brief = brief_service.get(3)
        original_template = rfx_brief.data['requirementsDocument']
        requirements_document = []

        brief_edit_business.edit_requirements_document(rfx_brief, requirements_document)
        assert rfx_brief.data['requirementsDocument'] == original_template
Exemplo n.º 2
0
def publish_answer(current_user, brief_id, data):
    brief = briefs.get(brief_id)
    if not brief:
        raise NotFoundError("Invalid brief id '{}'".format(brief_id))

    if not briefs.has_permission_to_brief(current_user.id, brief.id):
        raise UnauthorisedError('Unauthorised to publish answer')

    publish_question = data.get('question')
    if not publish_question:
        raise ValidationError('Question is required')

    answer = data.get('answer')
    if not answer:
        raise ValidationError('Answer is required')

    brief_clarification_question = brief_clarification_question_service.save(
        BriefClarificationQuestion(_brief_id=brief.id,
                                   question=publish_question,
                                   answer=answer,
                                   user_id=current_user.id))

    question_id = data.get('questionId')
    if question_id:
        question = brief_question_service.get(question_id)
        if question.brief_id == brief.id:
            question.answered = True
            brief_question_service.save(question)

    audit_service.log_audit_event(
        audit_type=audit_types.create_brief_clarification_question,
        user=current_user.email_address,
        data={'briefId': brief.id},
        db_object=brief_clarification_question)
Exemplo n.º 3
0
def download_brief_attachment(brief_id, slug):
    """Get brief attachments.
    ---
    tags:
        - brief
    parameters:
      - name: brief_id
        in: path
        type: number
        required: true
      - name: slug
        in: path
        type: string
        required: true
    responses:
        200:
            description: Attachment retrieved successfully.
        404:
            description: Attachment not found.
        500:
            description: Unexpected error.
    """
    brief = briefs.get(brief_id)
    brief_user_ids = [user.id for user in brief.users]

    if (hasattr(current_user, 'role') and
        (current_user.role == 'buyer' or
            (current_user.role == 'supplier' and _can_do_brief_response(brief_id)))):
        file = s3_download_file(slug, os.path.join(brief.framework.slug, 'attachments',
                                                   'brief-' + str(brief_id)))
        mimetype = mimetypes.guess_type(slug)[0] or 'binary/octet-stream'
        return Response(file, mimetype=mimetype)
    else:
        return not_found('File not found')
def close_opportunity_early(user_id, brief_id):
    brief = brief_service.get(brief_id)
    if not brief:
        raise NotFoundError('Opportunity {} does not exist'.format(brief_id))

    if not brief_service.has_permission_to_brief(user_id, brief_id):
        raise UnauthorisedError(
            'Not authorised to close opportunity {}'.format(brief_id))

    if not can_close_opportunity_early(brief):
        raise BriefError('Unable to close opportunity {}'.format(brief_id))

    user = users.get(user_id)
    if not user:
        raise NotFoundError('User {} does not exist'.format(user_id))

    brief = brief_service.close_opportunity_early(brief)
    create_responses_zip(brief.id)
    send_opportunity_closed_early_email(brief, user)

    try:
        audit_service.log_audit_event(
            audit_type=audit_types.close_opportunity_early,
            data={'briefId': brief.id},
            db_object=brief,
            user=user.email_address)

        publish_tasks.brief.delay(publish_tasks.compress_brief(brief),
                                  'closed_early',
                                  email_address=user.email_address,
                                  name=user.name)
    except Exception as e:
        rollbar.report_exc_info()

    return brief
Exemplo n.º 5
0
def update_brief_remove_user(brief_id, user):
    updater_json = validate_and_return_updater_request()
    brief = briefs.get(brief_id)

    if user.isdigit():
        u = [users.get(int(user))]
    else:
        u = [users.get_by_email(user)]
    if len(u) < 1:
        raise ValidationError("No user found: " + user)
    else:
        brief.users.remove(u[0])
        audit = AuditEvent(
            audit_type=AuditTypes.update_brief,
            user=updater_json['updated_by'],
            data={
                'briefId': brief.id,
                'briefJson': {
                    'remove_user': user
                },
            },
            db_object=brief,
        )

    db.session.add(brief)
    db.session.add(audit)
    db.session.commit()

    return jsonify(briefs=brief.serialize(with_users=True)), 200
Exemplo n.º 6
0
def update_brief_add_rfx_seller(brief_id, supplier_code):
    updater_json = validate_and_return_updater_request()
    # Using the helper.py methods to get the matching brief.
    brief = briefs.get(brief_id)
    supplier = suppliers.get_supplier_by_code(supplier_code)

    if not supplier:
        raise ValidationError("No supplier found: " + supplier_code)
    sellers = brief.data['sellers']
    sellers[str(supplier_code)] = {'name': supplier.name}
    brief.data['sellers'] = sellers
    audit = AuditEvent(
        audit_type=AuditTypes.seller_added_to_rfx_opportunity_admin,
        user=updater_json['updated_by'],
        data={
            'briefId': brief.id,
            'supplier_code': supplier_code,
        },
        db_object=brief,
    )

    db.session.add(brief)
    db.session.add(audit)
    db.session.commit()

    return jsonify(briefs=brief.serialize(with_users=True)), 200
    def test_edit_closing_date_updates_questions_closed_at(self, briefs):
        atm_brief = brief_service.get(1)
        new_closing_date = pendulum.now('Australia/Sydney').add(days=7)
        original_questions_closed_at = atm_brief.questions_closed_at

        brief_edit_business.edit_closing_date(atm_brief, new_closing_date.to_date_string())
        assert atm_brief.questions_closed_at > original_questions_closed_at
Exemplo n.º 8
0
def update_brief_remove_rfx_seller(brief_id, supplier_code):
    updater_json = validate_and_return_updater_request()
    brief = briefs.get(brief_id)
    sellers = brief.data['sellers']

    for key in sellers.keys():
        try:
            if key == str(supplier_code):
                del sellers[key]
        except KeyError:
            raise ValidationError("No supplier found: " + supplier_code)

    brief.data['sellers'] = sellers
    audit = AuditEvent(
        audit_type=AuditTypes.seller_removed_from_rfx_opportunity_admin,
        user=updater_json['updated_by'],
        data={
            'briefId': brief.id,
            'supplier_code': supplier_code,
        },
        db_object=brief,
    )

    db.session.add(brief)
    db.session.add(audit)
    db.session.commit()

    return jsonify(briefs=brief.serialize(with_users=True)), 200
    def test_edit_empty_response_template_does_not_update_response_template(self, briefs):
        rfx_brief = brief_service.get(3)
        original_template = rfx_brief.data['responseTemplate']
        response_template = []

        brief_edit_business.edit_response_template(rfx_brief, response_template)
        assert rfx_brief.data['responseTemplate'] == original_template
    def test_edit_documents_only_apply_edits_with_edited_flag_set(self, agency_service, briefs, users):
        atm_brief = brief_service.get(1)
        user = user_service.get(2)
        agency_service.get_agency_name.return_value = 'DTA'
        original_attachments = atm_brief.data['attachments']

        edits = {
            'closingDate': '',
            'title': 'test',
            'summary': 'test',
            'sellers': {},
            'attachments': [],
            'documentsEdited': False
        }

        brief = brief_edit_business.edit_opportunity(user.id, atm_brief.id, edits)
        assert len(original_attachments) > 0
        assert brief.data['attachments'] == original_attachments

        edits = {
            'closingDate': '',
            'title': 'test',
            'summary': 'test',
            'sellers': {},
            'attachments': ['ABC.PDF'],
            'documentsEdited': True
        }

        brief = brief_edit_business.edit_opportunity(user.id, atm_brief.id, edits)
        assert brief.data['attachments'] == ['ABC.PDF']
    def test_edit_closing_date_updates_closing_time_to_6pm(self, briefs):
        atm_brief = brief_service.get(1)
        timezone = 'Australia/Sydney'
        new_closing_date = pendulum.now(timezone).add(days=7)

        brief_edit_business.edit_closing_date(atm_brief, new_closing_date.to_date_string())

        local_closing_date = atm_brief.closed_at.in_timezone(timezone)
        assert local_closing_date.hour == 18
    def test_edit_sellers_does_not_update_sellers_for_atm_opportunity(self, briefs):
        atm_brief = brief_service.get(1)
        new_sellers = {
            '1': {
                'name': 'Seller 1'
            }
        }

        brief_edit_business.edit_sellers(atm_brief, new_sellers)
        assert 'sellers' not in atm_brief.data
    def test_edit_sellers_does_not_update_seller_selector(self, briefs):
        specialist_brief = brief_service.get(2)
        new_sellers = {
            '1': {
                'name': 'Seller 1'
            }
        }

        assert specialist_brief.data['sellerSelector'] == 'oneSeller'
        brief_edit_business.edit_sellers(specialist_brief, new_sellers)
        assert specialist_brief.data['sellerSelector'] == 'oneSeller'
    def test_edit_sellers_does_not_update_sellers(self, briefs):
        specialist_brief = brief_service.get(2)
        original_sellers = specialist_brief.data['sellers']
        new_sellers = {
            '1': {
                'name': 'Seller 1'
            }
        }

        brief_edit_business.edit_sellers(specialist_brief, new_sellers)
        assert specialist_brief.data['sellers'] == original_sellers
    def test_edit_sellers_updates_sellers(self, briefs):
        specialist_brief = brief_service.get(2)
        new_sellers = {
            '1': {
                'name': 'Seller 1'
            },
            '2': {
                'name': 'Seller 2'
            }
        }

        brief_edit_business.edit_sellers(specialist_brief, new_sellers)
        assert specialist_brief.data['sellers'] == new_sellers
    def test_get_sellers_to_invite_returns_empty_dictionary_when_no_new_sellers(self, briefs):
        specialist_brief = brief_service.get(2)
        new_sellers = {
            '1': {
                'name': 'Seller 1'
            }
        }

        sellers_to_invite = brief_edit_business.get_sellers_to_invite(specialist_brief, new_sellers)
        seller_codes = sellers_to_invite.keys()

        assert len(seller_codes) == 0
        assert '1' not in seller_codes
Exemplo n.º 17
0
def get_notification_template(brief_id, template):
    brief = briefs.get(brief_id)
    if brief:
        frontend_url = current_app.config['FRONTEND_ADDRESS']
        return render_email_template(
            '{}.md'.format(template),
            frontend_url=frontend_url,
            brief_name=brief.data['title'],
            brief_id=brief.id,
            brief_url='{}/digital-marketplace/opportunities/{}'.format(frontend_url, brief_id)
        )

    return not_found('brief not found')
def withdraw_opportunity(user_id, brief_id, withdrawal_reason):
    brief = brief_service.get(brief_id)
    if not brief:
        raise NotFoundError('Opportunity {} does not exist'.format(brief_id))

    if not brief_service.has_permission_to_brief(user_id, brief_id):
        raise UnauthorisedError(
            'Not authorised to withdraw opportunity {}'.format(brief_id))

    if brief.status != 'live':
        raise BriefError('Unable to withdraw opportunity {}'.format(brief_id))

    if not withdrawal_reason:
        raise ValidationError(
            'Withdrawal reason is required for opportunity {}'.format(
                brief_id))

    user = users.get(user_id)
    if not user:
        raise NotFoundError('User {} does not exist'.format(user_id))

    brief = brief_service.withdraw_opportunity(brief, withdrawal_reason)
    organisation = agency_service.get_agency_name(user.agency_id)
    sellers_to_contact = brief_service.get_sellers_to_notify(
        brief, brief_business.is_open_to_all(brief))

    for email_address in sellers_to_contact:
        send_opportunity_withdrawn_email_to_seller(brief, email_address,
                                                   organisation)

    send_opportunity_withdrawn_email_to_buyers(brief, user)

    try:
        audit_service.log_audit_event(
            audit_type=audit_types.withdraw_opportunity,
            data={'briefId': brief.id},
            db_object=brief,
            user=user.email_address)

        publish_tasks.brief.delay(publish_tasks.compress_brief(brief),
                                  'withdrawn',
                                  email_address=user.email_address,
                                  name=user.name)
    except Exception as e:
        rollbar.report_exc_info()

    return brief
Exemplo n.º 19
0
def get_suppliers_responded(brief_id):
    """Get suppliers responded (role=buyer)
    ---
    tags:
      - "Brief Response"
    security:
      - basicAuth: []
    parameters:
      - name: brief_response_id
        in: path
        type: number
        required: true
    definitions:
      BriefResponse:
        type: object
        properties:
          id:
            type: number
          data:
            type: object
          brief_id:
            type: number
          supplier_code:
            type: number
    responses:
      200:
        description: Suppliers that have responded to brief_id
        schema:
          id: BriefResponse
      404:
        description: brief_response_id not found
    """
    brief = briefs.get(brief_id)
    if not brief:
        return not_found('brief {} not found'.format(brief_id))

    if not briefs.has_permission_to_brief(current_user.id, brief.id):
        return forbidden('Unauthorised to get suppliers responded')

    suppliers = brief_responses_service.get_suppliers_responded(brief_id)
    work_order = work_order_service.find(brief_id=brief_id).one_or_none()

    return jsonify(brief=brief.serialize(with_users=False),
                   suppliers=suppliers,
                   workOrderCreated=True if work_order else False)
    def test_edit_opportunity_creates_history_record(self, agency_service, briefs, users):
        specialist_brief = brief_service.get(2)
        user = user_service.get(2)
        agency_service.get_agency_name.return_value = 'DTA'

        edits = {
            'closingDate': '',
            'title': 'test',
            'sellers': {},
            'summary': ''
        }

        brief = brief_edit_business.edit_opportunity(user.id, specialist_brief.id, edits)
        history = brief_history_service.all()

        assert len(history) == 1
        assert history[0].brief_id == brief.id
        assert history[0].user_id == user.id
    def test_edit_opportunity_creates_audit_event(self, agency_service, briefs, users):
        specialist_brief = brief_service.get(2)
        user = user_service.get(2)
        agency_service.get_agency_name.return_value = 'DTA'

        edits = {
            'closingDate': '',
            'title': 'test',
            'sellers': {},
            'summary': ''
        }

        brief = brief_edit_business.edit_opportunity(user.id, specialist_brief.id, edits)
        audit_event = audit_service.find(
            object_id=specialist_brief.id,
            object_type='Brief',
            type=audit_types.opportunity_edited.value
        ).one_or_none()

        assert audit_event is not None
    def test_edit_opportunity_creates_history_record_with_original_data(self, agency_service, briefs, users):
        specialist_brief = brief_service.get(2)
        original_closed_at = copy.deepcopy(specialist_brief.closed_at)
        original_specialist_data = copy.deepcopy(specialist_brief.data)
        user = user_service.get(2)
        agency_service.get_agency_name.return_value = 'DTA'

        edits = {
            'closingDate': '',
            'title': 'test',
            'sellers': {},
            'summary': ''
        }

        brief = brief_edit_business.edit_opportunity(user.id, specialist_brief.id, edits)
        history = brief_history_service.all()

        assert pendulum.parse(history[0].data['closed_at'], tz='utc') == original_closed_at
        assert history[0].data['sellers'] == original_specialist_data['sellers']
        assert history[0].data['sellerSelector'] == original_specialist_data['sellerSelector']
        assert history[0].data['title'] == original_specialist_data['title']
    def test_get_sellers_to_invite_returns_new_sellers(self, briefs):
        specialist_brief = brief_service.get(2)
        new_sellers = {
            '1': {
                'name': 'Seller 1'
            },
            '2': {
                'name': 'Seller 2'
            },
            '3': {
                'name': 'Seller 3'
            }
        }

        sellers_to_invite = brief_edit_business.get_sellers_to_invite(specialist_brief, new_sellers)
        seller_codes = sellers_to_invite.keys()

        assert len(seller_codes) == 2
        assert '1' not in seller_codes
        assert '2' in seller_codes
        assert '3' in seller_codes
Exemplo n.º 24
0
def upload_brief_rfx_attachment_file(brief_id, slug):
    """Add brief attachments (role=buyer)
    ---
    tags:
        - brief
    parameters:
      - name: brief_id
        in: path
        type: number
        required: true
      - name: slug
        in: path
        type: string
        required: true
      - name: file
        in: body
        required: true
    responses:
        200:
            description: Attachment uploaded successfully.
        403:
            description: Unauthorised to update brief.
        404:
            description: Brief not found.
        500:
            description: Unexpected error.
    """
    brief = briefs.get(brief_id)

    if not brief:
        not_found("Invalid brief id '{}'".format(brief_id))

    brief_user_ids = [user.id for user in brief.users]
    if current_user.id not in brief_user_ids:
        return forbidden('Unauthorised to update brief')

    return jsonify({"filename": s3_upload_file_from_request(request, slug,
                                                            os.path.join(brief.framework.slug, 'attachments',
                                                                         'brief-' + str(brief_id)))
                    })
    def test_only_sellers_were_edited_is_false_when_title_edited(self, agency_service, briefs, users):
        specialist_brief = brief_service.get(2)
        user = user_service.get(2)
        agency_service.get_agency_name.return_value = 'DTA'

        edits = {
            'closingDate': '',
            'title': 'test',
            'sellers': {
                '1': {
                    'name': 'Seller 1'
                },
                '2': {
                    'name': 'Seller 2'
                }
            },
            'summary': ''
        }

        brief = brief_edit_business.edit_opportunity(user.id, specialist_brief.id, edits)
        only_sellers_edited = brief_edit_business.only_sellers_were_edited(specialist_brief.id)
        assert only_sellers_edited is False
    def test_only_sellers_were_edited_is_false_when_summary_edited(self, agency_service, briefs, users):
        specialist_brief = brief_service.get(2)
        user = user_service.get(2)
        agency_service.get_agency_name.return_value = 'DTA'

        edits = {
            'closingDate': pendulum.now('Australia/Canberra').add(days=7).to_date_string(),
            'title': '',
            'sellers': {
                '1': {
                    'name': 'Seller 1'
                },
                '2': {
                    'name': 'Seller 2'
                }
            },
            'summary': 'New summary'
        }

        brief = brief_edit_business.edit_opportunity(user.id, specialist_brief.id, edits)
        only_sellers_edited = brief_edit_business.only_sellers_were_edited(specialist_brief.id)
        assert only_sellers_edited is False
Exemplo n.º 27
0
def delete_brief(brief_id):
    """Delete brief (role=buyer)
    ---
    tags:
        - brief
    definitions:
        DeleteBrief:
            type: object
            properties:
                message:
                    type: string
    parameters:
      - name: brief_id
        in: path
        type: number
        required: true
    responses:
        200:
            description: Brief deleted successfully.
            schema:
                $ref: '#/definitions/DeleteBrief'
        400:
            description: Bad request. Brief status must be 'draft'.
        403:
            description: Unauthorised to delete brief.
        404:
            description: brief_id not found.
        500:
            description: Unexpected error.
    """
    brief = briefs.get(brief_id)

    if not brief:
        not_found("Invalid brief id '{}'".format(brief_id))

    if current_user.role == 'buyer':
        brief_user_ids = [user.id for user in brief.users]
        if current_user.id not in brief_user_ids:
            return forbidden('Unauthorised to delete brief')

    if brief.status != 'draft':
        abort('Cannot delete a {} brief'.format(brief.status))

    audit = AuditEvent(
        audit_type=AuditTypes.delete_brief,
        user=current_user.email_address,
        data={
            'briefId': brief_id
        },
        db_object=None
    )

    try:
        deleted_brief = publish_tasks.compress_brief(brief)
        audit_service.save(audit)
        briefs.delete(brief)
        publish_tasks.brief.delay(
            deleted_brief,
            'deleted',
            user=current_user.email_address
        )
    except Exception as e:
        extra_data = {'audit_type': AuditTypes.delete_brief, 'briefId': brief.id, 'exception': e.message}
        rollbar.report_exc_info(extra_data=extra_data)

    return jsonify(message='Brief {} deleted'.format(brief_id)), 200
    def test_edit_attachments_updates_attachments(self, briefs):
        specialist_brief = brief_service.get(2)
        attachments = ['1.pdf', '2.pdf']

        brief_edit_business.edit_attachments(specialist_brief, attachments)
        assert specialist_brief.data['attachments'] == attachments
Exemplo n.º 29
0
def withdraw_brief_response(brief_response_id):
    """Withdraw brief responses (role=supplier)
    ---
    tags:
      - "Brief Response"
    security:
      - basicAuth: []
    parameters:
      - name: brief_response_id
        in: path
        type: number
        required: true
    responses:
      200:
        description: Successfully withdrawn a candidate
        schema:
          id: BriefResponse
      400:
        description: brief_response_id not found
    """
    brief_response = (brief_responses_service.find(
        id=brief_response_id,
        supplier_code=current_user.supplier_code).one_or_none())

    if brief_response:
        if brief_response.withdrawn_at is None:
            status_before_withdrawn = brief_response.status
            brief_response.withdrawn_at = utcnow()
            brief_responses_service.save(brief_response)

            try:
                audit = AuditEvent(
                    audit_type=audit_types.update_brief_response,
                    user=current_user.email_address,
                    data={
                        'briefResponseId': brief_response.id,
                        'withdrawn': True
                    },
                    db_object=brief_response)
                audit_service.save(audit)
            except Exception as e:
                extra_data = {
                    'audit_type': audit_types.update_brief_response,
                    'briefResponseId': brief_response.id
                }
                rollbar.report_exc_info(extra_data=extra_data)

            if status_before_withdrawn == 'submitted':
                brief = briefs.get(id=brief_response.brief_id)
                supplier = suppliers.get_supplier_by_code(
                    brief_response.supplier_code)
                if brief and supplier:
                    if brief.lot.slug == 'specialist':
                        send_specialist_brief_response_withdrawn_email(
                            supplier,
                            brief,
                            brief_response,
                            supplier_user=current_user.name)
                    else:
                        send_brief_response_withdrawn_email(
                            supplier,
                            brief,
                            brief_response,
                            supplier_user=current_user.name)

            publish_tasks.brief_response.delay(
                publish_tasks.compress_brief_response(brief_response),
                'withdrawn',
                user=current_user.email_address)
        else:
            abort(
                'Brief response with brief_response_id "{}" is already withdrawn'
                .format(brief_response_id))
    else:
        not_found(
            'Cannot find brief response with brief_response_id :{} and supplier_code: {}'
            .format(brief_response_id, current_user.supplier_code))

    return jsonify(briefResponses=brief_response.serialize()), 200
Exemplo n.º 30
0
def update_brief(brief_id):
    """Update RFX brief (role=buyer)
    ---
    tags:
        - brief
    definitions:
        RFXBrief:
            type: object
            properties:
                title:
                    type: string
                organisation:
                    type: string
                location:
                    type: array
                    items:
                        type: string
                summary:
                    type: string
                industryBriefing:
                    type: string
                sellerCategory:
                    type: string
                sellers:
                    type: object
                attachments:
                    type: array
                    items:
                        type: string
                requirementsDocument:
                    type: array
                    items:
                        type: string
                responseTemplate:
                    type: array
                    items:
                        type: string
                evaluationType:
                    type: array
                    items:
                        type: string
                proposalType:
                    type: array
                    items:
                        type: string
                evaluationCriteria:
                    type: array
                    items:
                        type: object
                includeWeightings:
                    type: boolean
                closedAt:
                    type: string
                contactNumber:
                    type: string
                startDate:
                    type: string
                contractLength:
                    type: string
                contractExtensions:
                    type: string
                budgetRange:
                    type: string
                workingArrangements:
                    type: string
                securityClearance:
                    type: string
    parameters:
      - name: brief_id
        in: path
        type: number
        required: true
      - name: body
        in: body
        required: true
        schema:
            $ref: '#/definitions/RFXBrief'
    responses:
        200:
            description: Brief updated successfully.
            schema:
                $ref: '#/definitions/RFXBrief'
        400:
            description: Bad request.
        403:
            description: Unauthorised to update RFX brief.
        404:
            description: Brief not found.
        500:
            description: Unexpected error.
    """
    brief = briefs.get(brief_id)

    if not brief:
        not_found("Invalid brief id '{}'".format(brief_id))

    if brief.status != 'draft':
        abort('Cannot edit a {} brief'.format(brief.status))

    if brief.lot.slug not in ['rfx', 'atm']:
        abort('Brief lot not supported for editing')

    if current_user.role == 'buyer':
        brief_user_ids = [user.id for user in brief.users]
        if current_user.id not in brief_user_ids:
            return forbidden('Unauthorised to update brief')

    data = get_json_from_request()

    publish = False
    if 'publish' in data and data['publish']:
        del data['publish']
        publish = True

    if brief.lot.slug == 'rfx':
        # validate the RFX JSON request data
        errors = RFXDataValidator(data).validate(publish=publish)
        if len(errors) > 0:
            abort(', '.join(errors))

    if brief.lot.slug == 'atm':
        # validate the ATM JSON request data
        errors = ATMDataValidator(data).validate(publish=publish)
        if len(errors) > 0:
            abort(', '.join(errors))

    if brief.lot.slug == 'rfx' and 'evaluationType' in data:
        if 'Written proposal' not in data['evaluationType']:
            data['proposalType'] = []
        if 'Response template' not in data['evaluationType']:
            data['responseTemplate'] = []

    if brief.lot.slug == 'rfx' and 'sellers' in data and len(data['sellers']) > 0:
        data['sellerSelector'] = 'someSellers' if len(data['sellers']) > 1 else 'oneSeller'

    data['areaOfExpertise'] = ''
    if brief.lot.slug == 'atm' and 'openTo' in data:
        if data['openTo'] == 'all':
            data['sellerSelector'] = 'allSellers'
            data['sellerCategory'] = ''
        elif data['openTo'] == 'category':
            data['sellerSelector'] = 'someSellers'
            brief_domain = (
                domain_service.get_by_name_or_id(int(data['sellerCategory'])) if data['sellerCategory'] else None
            )
            if brief_domain:
                data['areaOfExpertise'] = brief_domain.name

    previous_status = brief.status
    if publish:
        brief.publish(closed_at=data['closedAt'])
        if 'sellers' in brief.data and data['sellerSelector'] != 'allSellers':
            for seller_code, seller in brief.data['sellers'].iteritems():
                supplier = suppliers.get_supplier_by_code(seller_code)
                if brief.lot.slug == 'rfx':
                    send_seller_invited_to_rfx_email(brief, supplier)
        try:
            brief_url_external = '{}/2/digital-marketplace/opportunities/{}'.format(
                current_app.config['FRONTEND_ADDRESS'],
                brief_id
            )
            _notify_team_brief_published(
                brief.data['title'],
                brief.data['organisation'],
                current_user.name,
                current_user.email_address,
                brief_url_external
            )
        except Exception as e:
            pass

    brief.data = data
    briefs.save_brief(brief)

    if publish:
        brief_url_external = '{}/2/digital-marketplace/opportunities/{}'.format(
            current_app.config['FRONTEND_ADDRESS'],
            brief_id
        )
        publish_tasks.brief.delay(
            publish_tasks.compress_brief(brief),
            'published',
            previous_status=previous_status,
            name=current_user.name,
            email_address=current_user.email_address,
            url=brief_url_external
        )
    try:
        audit_service.log_audit_event(
            audit_type=AuditTypes.update_brief,
            user=current_user.email_address,
            data={
                'briefId': brief.id,
                'briefData': brief.data
            },
            db_object=brief)
    except Exception as e:
        rollbar.report_exc_info()

    return jsonify(brief.serialize(with_users=False))
    def test_edit_requirements_document_updates_requirements_document(self, briefs):
        rfx_brief = brief_service.get(3)
        requirements_document = ['new.pdf']

        brief_edit_business.edit_requirements_document(rfx_brief, requirements_document)
        assert rfx_brief.data['requirementsDocument'] == requirements_document
Exemplo n.º 32
0
def get_brief_responses(brief_id):
    """All brief responses (role=supplier,buyer)
    ---
    tags:
      - brief
    security:
      - basicAuth: []
    parameters:
      - name: brief_id
        in: path
        type: number
        required: true
    definitions:
      BriefResponses:
        properties:
          briefResponses:
            type: array
            items:
              id: BriefResponse
    responses:
      200:
        description: A list of brief responses
        schema:
          id: BriefResponses
      404:
        description: brief_id not found
    """
    brief = briefs.get(brief_id)
    if not brief:
        not_found("Invalid brief id '{}'".format(brief_id))

    if current_user.role == 'buyer':
        brief_user_ids = [user.id for user in brief.users]
        if current_user.id not in brief_user_ids:
            return forbidden("Unauthorised to view brief or brief does not exist")

    supplier_code = getattr(current_user, 'supplier_code', None)
    if current_user.role == 'supplier':
        validation_result = supplier_business.get_supplier_messages(supplier_code, True)
        if len(validation_result.errors) > 0:
            abort(validation_result.errors)
        # strip data from seller view
        if 'sellers' in brief.data:
            brief.data['sellers'] = {}
        if brief.responses_zip_filesize:
            brief.responses_zip_filesize = None
        if 'industryBriefing' in brief.data:
            brief.data['industryBriefing'] = ''
        if 'attachments' in brief.data:
            brief.data['attachments'] = []
        if 'backgroundInformation' in brief.data:
            brief.data['backgroundInformation'] = ''
        if 'outcome' in brief.data:
            brief.data['outcome'] = ''
        if 'endUsers' in brief.data:
            brief.data['endUsers'] = ''
        if 'workAlreadyDone' in brief.data:
            brief.data['workAlreadyDone'] = ''
        if 'timeframeConstraints' in brief.data:
            brief.data['timeframeConstraints'] = ''
        if 'contactNumber' in brief.data:
            brief.data['contactNumber'] = ''

    if current_user.role == 'buyer' and brief.status != 'closed':
        brief_responses = []
    else:
        brief_responses = brief_responses_service.get_brief_responses(brief_id, supplier_code)

    return jsonify(brief=brief.serialize(with_users=False, with_author=False),
                   briefResponses=brief_responses)
Exemplo n.º 33
0
def get_brief_overview(brief_id):
    """Overview (role=buyer)
    ---
    tags:
        - brief
    definitions:
        BriefOverview:
            type: object
            properties:
                sections:
                    type: array
                    items:
                        $ref: '#/definitions/BriefOverviewSections'
                title:
                    type: string
        BriefOverviewSections:
            type: array
            items:
                $ref: '#/definitions/BriefOverviewSection'
        BriefOverviewSection:
            type: object
            properties:
                links:
                    type: array
                    items:
                        $ref: '#/definitions/BriefOverviewSectionLinks'
                title:
                    type: string
        BriefOverviewSectionLinks:
            type: array
            items:
                $ref: '#/definitions/BriefOverviewSectionLink'
        BriefOverviewSectionLink:
            type: object
            properties:
                complete:
                    type: boolean
                path:
                    type: string
                    nullable: true
                text:
                    type: string
    responses:
        200:
            description: Data for the Overview page
            schema:
                $ref: '#/definitions/BriefOverview'
        400:
            description: Lot not supported.
        403:
            description: Unauthorised to view brief.
        404:
            description: brief_id not found
    """
    brief = briefs.get(brief_id)

    if not brief:
        not_found("Invalid brief id '{}'".format(brief_id))

    if current_user.role == 'buyer':
        brief_user_ids = [user.id for user in brief.users]
        if current_user.id not in brief_user_ids:
            return forbidden('Unauthorised to view brief')

    if not (brief.lot.slug == 'digital-professionals' or
            brief.lot.slug == 'training'):
        abort('Lot {} is not supported'.format(brief.lot.slug))

    sections = brief_overview_service.get_sections(brief)

    return jsonify(sections=sections, status=brief.status, title=brief.data['title']), 200
    def test_edit_response_template_updates_response_template(self, briefs):
        rfx_brief = brief_service.get(3)
        response_template = ['new.pdf']

        brief_edit_business.edit_response_template(rfx_brief, response_template)
        assert rfx_brief.data['responseTemplate'] == response_template