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
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)
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
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
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
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
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
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
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
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
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
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
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)
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