class TestDateFormats(object): def setup(self): self.formatter = DateFormatter('Europe/London') def test_timeformat(self): cases = [ (datetime(2012, 11, 10, 9, 8, 7, 6), '09:08:07'), ('2012-11-10T09:08:07.0Z', '09:08:07'), (datetime(2012, 8, 10, 9, 8, 7, 6), '10:08:07'), ('2012-08-12T12:12:12.0Z', '13:12:12'), (datetime(2012, 8, 10, 9, 8, 7, 6, tzinfo=pytz.utc), '10:08:07'), (datetime(2012, 8, 10, 0, 8, 7, 6, tzinfo=pytz.utc), '01:08:07'), ] for dt, formatted_time in cases: assert self.formatter.timeformat(dt) == formatted_time def test_shortdateformat(self): cases = [ (datetime(2012, 11, 10, 9, 8, 7, 6), '10 November'), ('2012-11-10T09:08:07.0Z', '10 November'), (datetime(2012, 8, 10, 9, 8, 7, 6), '10 August'), ('2012-08-10T09:08:07.0Z', '10 August'), (datetime(2012, 8, 10, 9, 8, 7, 6, tzinfo=pytz.utc), '10 August'), ('2016-04-27T23:59:59.0Z', '28 April'), (datetime(2016, 4, 27, 23, 59, 59, 0, tzinfo=pytz.utc), '28 April'), (datetime(2012, 8, 1, 9, 8, 7, 6, tzinfo=pytz.utc), '1 August'), ] for dt, formatted_date in cases: assert self.formatter.shortdateformat(dt) == formatted_date def test_dateformat(self): cases = [ (datetime(2012, 11, 10, 9, 8, 7, 6), 'Saturday 10 November 2012'), ('2012-11-10T09:08:07.0Z', 'Saturday 10 November 2012'), (datetime(2012, 8, 10, 9, 8, 7, 6), 'Friday 10 August 2012'), ('2012-08-10T09:08:07.0Z', 'Friday 10 August 2012'), (datetime(2012, 8, 10, 9, 8, 7, 6, tzinfo=pytz.utc), 'Friday 10 August 2012'), ('2016-04-27T23:59:59.0Z', 'Thursday 28 April 2016'), (datetime(2016, 4, 27, 23, 59, 59, 0), 'Thursday 28 April 2016'), (datetime(2012, 8, 1, 9, 8, 7, 6, tzinfo=pytz.utc), 'Wednesday 1 August 2012'), ] for dt, formatted_date in cases: assert self.formatter.dateformat(dt) == formatted_date def test_datetimeformat(self): cases = [ (datetime(2012, 11, 10, 9, 8, 7, 6), 'Saturday 10 November 2012 at 9AM (in Canberra)'), ('2012-11-10T09:08:07.0Z', 'Saturday 10 November 2012 at 9AM (in Canberra)'), (datetime(2012, 8, 10, 9, 8, 7, 6), 'Friday 10 August 2012 at 10AM (in Canberra)'), ('2012-08-10T09:08:07.0Z', 'Friday 10 August 2012 at 10AM (in Canberra)'), (datetime(2012, 8, 10, 9, 8, 7, 6, tzinfo=pytz.utc), 'Friday 10 August 2012 at 10AM (in Canberra)'), (datetime(2012, 8, 1, 9, 8, 7, 6, tzinfo=pytz.utc), 'Wednesday 1 August 2012 at 10AM (in Canberra)'), ] for dt, formatted_datetime in cases: assert self.formatter.datetimeformat(dt) == formatted_datetime
def framework_agreement(framework_slug): framework = get_framework(data_api_client, framework_slug, allowed_statuses=['standstill', 'live']) supplier_framework = return_supplier_framework_info_if_on_framework_or_abort(data_api_client, framework_slug) if supplier_framework['agreementReturned']: date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) supplier_framework['agreementReturnedAt'] = date_formatter.datetimeformat( date_parse(supplier_framework['agreementReturnedAt']) ) # if there's a frameworkAgreementVersion key, it means we're on G-Cloud 8 or higher if framework.get('frameworkAgreementVersion'): drafts, complete_drafts = get_drafts(data_api_client, framework_slug) lots_with_completed_drafts = [ lot for lot in framework['lots'] if count_drafts_by_lot(complete_drafts, lot['slug']) ] return render_template( 'frameworks/contract_start.html', signature_page_filename=SIGNATURE_PAGE_FILENAME, framework=framework, lots=[{ 'name': lot['name'], 'has_completed_draft': (lot in lots_with_completed_drafts) } for lot in framework['lots']], supplier_framework=supplier_framework, ), 200 return render_template_with_csrf( "frameworks/agreement.html", framework=framework, supplier_framework=supplier_framework, agreement_filename=AGREEMENT_FILENAME )
def send_assessment_requested_notification(assessment, requested_by): TEMPLATE_FILENAME = 'assessment_requested.md' df = DateFormatter(current_app.config['DEADLINES_TZ_NAME']) FRONTEND_ADDRESS = current_app.config['FRONTEND_ADDRESS'] supplier = Supplier.query.get(assessment.supplier_domain.supplier_id) brief = assessment.briefs[0] brief_url = '{}/digital-marketplace/opportunities/{}'.format(FRONTEND_ADDRESS, brief.id) brief_xls_url = '{}/digital-marketplace/opportunities/{}/response'.format(FRONTEND_ADDRESS, brief.id) brief_deadline = df.datetimeformat(brief.applications_closed_at).replace('(', '').replace(')', '') email_addresses = list(set([supplier.contacts[0].email, requested_by])) subject = "{} assessment requested".format(assessment.supplier_domain.domain.name) # prepare copy email_body = render_email_template( TEMPLATE_FILENAME, domain_name=assessment.supplier_domain.domain.name, brief_name=brief.data['title'], brief_url=brief_url, brief_xls_url=brief_xls_url, brief_deadline=brief_deadline ) send_or_handle_error( email_addresses, email_body, subject, current_app.config['DM_GENERIC_NOREPLY_EMAIL'], current_app.config['DM_GENERIC_SUPPORT_NAME'], event_description_for_errors='assessment rejected' )
def get_service_by_id(service_id): try: service = data_api_client.get_service(service_id) if service is None: abort(404, "Service ID '{}' can not be found".format(service_id)) if service['services']['frameworkStatus'] not in ("live", "expired"): abort(404, "Service ID '{}' can not be found".format(service_id)) service_data = service['services'] service_view_data = Service( service_data, content_loader.get_builder('g-cloud-6', 'display_service').filter(service_data)) try: # get supplier data and add contact info to service object supplier = data_api_client.get_supplier( service_data['supplierCode']) supplier_data = supplier['suppliers'] service_view_data.meta.set_contact_attribute( supplier_data['contactInformation'][0].get('contactName'), supplier_data['contactInformation'][0].get('phoneNumber'), supplier_data['contactInformation'][0].get('email')) except HTTPError as e: abort(e.status_code) date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) service_unavailability_information = None status_code = 200 if service['serviceMadeUnavailableAuditEvent'] is not None: service_unavailability_information = { 'date': date_formatter.dateformat( service['serviceMadeUnavailableAuditEvent']['createdAt']), 'type': service['serviceMadeUnavailableAuditEvent']['type'] } # mark the resource as unavailable in the headers status_code = 410 return render_template('service.html', service=service_view_data, service_unavailability_information= service_unavailability_information, lot=service_view_data.lot.lower(), lot_label=get_label_for_lot_param( service_view_data.lot.lower())), status_code except AuthException: abort(500, "Application error") except KeyError: abort(404, "Service ID '%s' can not be found" % service_id) except HTTPError as e: abort(e.status_code)
def list_agreements(framework_slug): framework = data_api_client.get_framework(framework_slug)['frameworks'] supplier_frameworks = data_api_client.find_framework_suppliers( framework_slug, agreement_returned=True)['supplierFrameworks'] date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) for supplier_framework in supplier_frameworks: supplier_framework[ 'agreementReturnedAt'] = date_formatter.datetimeformat( parse_date(supplier_framework['agreementReturnedAt'])) return render_template('view_agreements.html', framework=framework, supplier_frameworks=supplier_frameworks, signed_agreement_prefix=SIGNED_AGREEMENT_PREFIX)
def list_agreements(framework_slug): framework = data_api_client.get_framework(framework_slug)['frameworks'] supplier_frameworks = data_api_client.find_framework_suppliers( framework_slug, agreement_returned=True )['supplierFrameworks'] date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) for supplier_framework in supplier_frameworks: supplier_framework['agreementReturnedAt'] = date_formatter.datetimeformat( parse_date(supplier_framework['agreementReturnedAt'])) return render_template( 'view_agreements.html', framework=framework, supplier_frameworks=supplier_frameworks, signed_agreement_prefix=SIGNED_AGREEMENT_PREFIX )
def list_countersigned_agreement_file(supplier_code, framework_slug): supplier = data_api_client.get_supplier(supplier_code)['supplier'] framework = data_api_client.get_framework(framework_slug)['frameworks'] agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) path = get_agreement_document_path(framework_slug, supplier_code, COUNTERSIGNED_AGREEMENT_FILENAME) countersigned_agreement_document = agreements_bucket.get_key(path) if countersigned_agreement_document: countersigned_agreement = countersigned_agreement_document date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) countersigned_agreement['last_modified'] = date_formatter.datetimeformat(parse_date( countersigned_agreement['last_modified'])) countersigned_agreement = [countersigned_agreement] else: countersigned_agreement = [] return render_template_with_csrf( "suppliers/upload_countersigned_agreement.html", supplier=supplier, framework=framework, countersigned_agreement=countersigned_agreement, countersigned_agreement_filename=COUNTERSIGNED_AGREEMENT_FILENAME )
def list_countersigned_agreement_file(supplier_code, framework_slug): supplier = data_api_client.get_supplier(supplier_code)['supplier'] framework = data_api_client.get_framework(framework_slug)['frameworks'] agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) path = get_agreement_document_path(framework_slug, supplier_code, COUNTERSIGNED_AGREEMENT_FILENAME) countersigned_agreement_document = agreements_bucket.get_key(path) if countersigned_agreement_document: countersigned_agreement = countersigned_agreement_document date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) countersigned_agreement[ 'last_modified'] = date_formatter.datetimeformat( parse_date(countersigned_agreement['last_modified'])) countersigned_agreement = [countersigned_agreement] else: countersigned_agreement = [] return render_template_with_csrf( "suppliers/upload_countersigned_agreement.html", supplier=supplier, framework=framework, countersigned_agreement=countersigned_agreement, countersigned_agreement_filename=COUNTERSIGNED_AGREEMENT_FILENAME)
def framework_agreement(framework_slug): framework = get_framework(data_api_client, framework_slug, allowed_statuses=['standstill', 'live']) supplier_framework = return_supplier_framework_info_if_on_framework_or_abort( data_api_client, framework_slug) if supplier_framework['agreementReturned']: date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) supplier_framework[ 'agreementReturnedAt'] = date_formatter.datetimeformat( date_parse(supplier_framework['agreementReturnedAt'])) # if there's a frameworkAgreementVersion key, it means we're on G-Cloud 8 or higher if framework.get('frameworkAgreementVersion'): drafts, complete_drafts = get_drafts(data_api_client, framework_slug) lots_with_completed_drafts = [ lot for lot in framework['lots'] if count_drafts_by_lot(complete_drafts, lot['slug']) ] return render_template( 'frameworks/contract_start.html', signature_page_filename=SIGNATURE_PAGE_FILENAME, framework=framework, lots=[{ 'name': lot['name'], 'has_completed_draft': (lot in lots_with_completed_drafts) } for lot in framework['lots']], supplier_framework=supplier_framework, ), 200 return render_template_with_csrf("frameworks/agreement.html", framework=framework, supplier_framework=supplier_framework, agreement_filename=AGREEMENT_FILENAME)
def send_assessment_requested_notification(assessment, requested_by): TEMPLATE_FILENAME = 'assessment_requested.md' df = DateFormatter(current_app.config['DEADLINES_TZ_NAME']) FRONTEND_ADDRESS = current_app.config['FRONTEND_ADDRESS'] supplier = Supplier.query.get(assessment.supplier_domain.supplier_id) brief = assessment.briefs[0] brief_url = '{}/digital-marketplace/opportunities/{}'.format(FRONTEND_ADDRESS, brief.id) brief_template_file_details = 'DOCX 11KB' if brief.lot.slug == 'training' else 'XLS 130KB' brief_template_url = ( '{}/static/media/documents/Training_opportunities_questions_for_sellers.docx'.format(FRONTEND_ADDRESS) if brief.lot.slug == 'training' else '{}/digital-marketplace/opportunities/{}/response'.format(FRONTEND_ADDRESS, brief.id)) brief_deadline = df.datetimeformat(brief.applications_closed_at).replace('(', '').replace(')', '') email_addresses = list(set([supplier.contacts[0].email, requested_by])) subject = "{} assessment requested".format(assessment.supplier_domain.domain.name) # prepare copy email_body = render_email_template( TEMPLATE_FILENAME, domain_name=assessment.supplier_domain.domain.name, brief_name=brief.data['title'], brief_url=brief_url, brief_lot=brief.lot.slug, brief_template_file_details=brief_template_file_details, brief_template_url=brief_template_url, brief_deadline=brief_deadline ) send_or_handle_error( email_addresses, email_body, subject, current_app.config['DM_GENERIC_NOREPLY_EMAIL'], current_app.config['DM_GENERIC_SUPPORT_NAME'], event_description_for_errors='assessment rejected' )
def setup(self): self.formatter = DateFormatter('Europe/London')
def get_brief_response_preview_by_id(framework_slug, brief_id): briefs = data_api_client.get_brief(brief_id) brief = briefs.get('briefs') brief_url = url_for('main.index', _external=True) + '{}/opportunities/{}'.format(framework_slug, brief['id']) if brief['status'] not in ['live', 'closed']: if not current_user.is_authenticated or brief['users'][0]['id'] != current_user.id: abort(404, "Opportunity '{}' can not be found".format(brief_id)) hypothetical_dates = brief['dates'].get('hypothetical', None) if hypothetical_dates is None: published_date = brief['dates'].get('published_date', None) closing_time = brief['dates'].get('closing_time', None) else: published_date = hypothetical_dates.get('published_date', None) closing_time = hypothetical_dates.get('closing_time', None) outdata = io.BytesIO() workbook = xlsxwriter.Workbook(outdata) bold_header = workbook.add_format({'bg_color': '#e8f5fa', 'bold': True, 'text_wrap': True}) bold_question = workbook.add_format({'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA", 'bold': True}) bold_red = workbook.add_format({'bold': True, 'font_color': '#fc0d1b', 'text_wrap': True}) italic_header = workbook.add_format({'bg_color': '#e8f5fa', 'italic': True}) italic_lightgrey = workbook.add_format({'italic': True, 'font_color': '#999999'}) italic_darkgrey_question = workbook.add_format({'italic': True, 'font_color': '#666666', 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA"}) darkgrey = workbook.add_format({'font_color': '#666666', 'text_wrap': True}) heading = workbook.add_format({'bold': True, 'font_size': '14', 'text_wrap': True}) header = workbook.add_format({'bg_color': '#e8f5fa'}) cta = workbook.add_format({'bg_color': 'd9ead4', 'align': 'center', 'color': 'blue', 'underline': 1, 'text_wrap': True}) bold_cta = workbook.add_format({'bg_color': 'd9ead4', 'bold': True, 'align': 'center'}) question = workbook.add_format({'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA"}) link = workbook.add_format({'bg_color': '#e8f5fa', 'color': 'blue', 'underline': 1}) right_border_question = workbook.add_format({'right': 1, 'right_color': 'black', 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA"}) sheet = workbook.add_worksheet('Response') sheet.set_column('E:E', 50) sheet.set_column('D:D', 5) sheet.set_column('C:C', 50) sheet.set_column('B:B', 30) sheet.set_column('A:A', 30) sheet.merge_range(0, 0, 0, 2, '', italic_header) sheet.write_url('A1', brief_url) sheet.write_rich_string('A1', italic_header, 'Use this template if you are waiting to be assessed, or want to collaborate ' 'with others, before submitting your response to this brief.\n' 'If you have been assessed and are ready to submit, you will need to ' 'copy and paste your answers from this template into \n', link, brief_url) sheet.write_string('D1', '', right_border_question) df = DateFormatter(current_app.config['DM_TIMEZONE']) sheet.write_string('E1', brief['title'], heading) sheet.write_string('E2', brief['summary'], darkgrey) sheet.write_string('E3', 'For: '+brief['organisation'], darkgrey) sheet.write_string('E4', 'Published: '+df.dateformat(published_date), darkgrey) sheet.write_string('E5', 'Closing date for application: ' + df.datetimeformat(closing_time), bold_red) sheet.write_string('A2', 'Guidance', bold_question) sheet.write_string('B2', 'Question', bold_question) sheet.write_string('C2', 'Answer', bold_question) sheet.write_string('D2', '', right_border_question) sheet.write_string('A3', '') sheet.write_string('B3', 'Essential selection criteria', bold_header) sheet.write_string('D3', '', right_border_question) b_count = 4 e_start = 2 for essential in brief['essentialRequirements']: sheet.write_string('D'+str(b_count), '', right_border_question) if brief['lotSlug'] == 'digital-professionals': sheet.write_string('B'+str(b_count), essential, question) else: sheet.write_string('B'+str(b_count), essential['criteria'], question) sheet.write_string('C'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('B'+str(b_count), 'Desirable selection criteria', bold_header) b_count += 1 for nice in brief['niceToHaveRequirements']: if brief['lotSlug'] == 'digital-professionals': sheet.write_string('B'+str(b_count), nice, question) else: sheet.write_string('B'+str(b_count), nice['criteria'], question) sheet.write_string('C'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) b_count += 1 sheet.merge_range( e_start, 0, b_count - 2, 0, 'Skills and experience\n' 'As a guide to answering the skills and experience criteria, ' 'you could explain:\n' '- What the situation was\n' '- The work the specialist or team completed\n' '- What the results were \n' 'You can reuse examples if you wish. \n' '\n' 'You must have all essential skills and experience ' 'to apply for this opportunity.\n' '150 words max ', italic_darkgrey_question ) sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('B'+str(b_count), '') b_count += 1 if brief['lotSlug'] == 'digital-professionals': sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('B'+str(b_count), "When can you start?", bold_question) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('B'+str(b_count), "What is your daily rate, including GST?", bold_question) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_rich_string('B'+str(b_count), bold_question, "Attach a résumé\n", question, "Use an Open Document Format (ODF) or PDF/A (eg. .pdf, .odt). " "The maximum file size of each document is 5MB. " "You can upload a maximum of 3 candidate CVs.", question) b_count += 1 if brief['lotSlug'] == 'specialist': sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_rich_string( 'B'+str(b_count), bold_question, "When can you start?\n", question, '{} has requested {}'.format(brief['organisation'], df.dateformat(brief['startDate'])), question ) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) preferred_format_for_rates = brief['preferredFormatForRates'] if preferred_format_for_rates == 'dailyRate': sheet.write_string('B'+str(b_count), "What is your daily rate, excluding GST?", bold_question) elif preferred_format_for_rates == 'hourlyRate': sheet.write_string('B'+str(b_count), "What is your hourly rate, excluding GST?", bold_question) b_count += 1 if brief['securityClearance'] == 'mustHave': security_clearance_label = '' if brief['securityClearanceCurrent'] == 'baseline': security_clearance_label = 'baseline' elif brief['securityClearanceCurrent'] == 'nv1': security_clearance_label = 'negative vetting level 1' elif brief['securityClearanceCurrent'] == 'nv2': security_clearance_label = 'negative vetting level 1' elif brief['securityClearanceCurrent'] == 'pv': security_clearance_label = 'positive vetting' sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('C'+str(b_count), 'Yes/No') sheet.write_string( 'B'+str(b_count), "Do you have a {} security clearance?".format(security_clearance_label), bold_question ) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('C'+str(b_count), 'Yes/No') sheet.write_string('B'+str(b_count), "What is your eligibility to work in Australia?", bold_question) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('C'+str(b_count), 'Yes/No') sheet.write_string( 'B'+str(b_count), "Have you previously worked for {}?".format(brief['organisation']), bold_question ) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_rich_string('B'+str(b_count), bold_question, "Attach a résumé\n", question, "Use an Open Document Format (ODF) or PDF/A (eg. .pdf, .odt). " "The maximum file size of each document is 5MB. ", question) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_rich_string('B'+str(b_count), bold_question, "Other documents (optional)\n", question, "Use an Open Document Format (ODF) or PDF/A (eg. .pdf, .odt). " "The maximum file size of each document is 5MB. " "If requested by the buyer, you can upload additional documents", question) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('B'+str(b_count), '', question) b_count += 1 sheet.write_string('A'+str(b_count), "All communication about your application will be sent to this address", italic_darkgrey_question) sheet.write_string('D'+str(b_count), '', right_border_question) sheet.write_string('B'+str(b_count), "Contact email:", bold_question) b_count += 1 sheet.write_string('A'+str(b_count), '') sheet.write_string('B'+str(b_count), '') sheet.write_string('C'+str(b_count), '') sheet.write_string('D'+str(b_count), '') b_count += 1 sheet.write_string('C'+str(b_count), 'Ready to apply?', bold_cta) b_count += 1 sheet.write_url('C'+str(b_count), brief_url, cta, brief_url) workbook.close() return Response( outdata.getvalue(), mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', headers={ "Content-Disposition": "attachment;filename=brief-response-template-{}.xlsx".format(brief['id']), "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" } ), 200
def get_brief_response_preview_by_id(framework_slug, brief_id): briefs = data_api_client.get_brief(brief_id) brief = briefs.get('briefs') brief_url = url_for('main.index', _external=True) + '{}/opportunities/{}'.format(framework_slug, brief['id']) if brief['status'] not in ['live', 'closed']: if not current_user.is_authenticated or brief['users'][0]['id'] != current_user.id: abort(404, "Opportunity '{}' can not be found".format(brief_id)) hypothetical_dates = brief['dates'].get('hypothetical', None) if hypothetical_dates is None: published_date = brief['dates'].get('published_date', None) closing_time = brief['dates'].get('closing_time', None) else: published_date = hypothetical_dates.get('published_date', None) closing_time = hypothetical_dates.get('closing_time', None) outdata = io.BytesIO() workbook = xlsxwriter.Workbook(outdata) bold_header = workbook.add_format({'bg_color': '#e8f5fa', 'bold': True, 'text_wrap': True}) bold_question = workbook.add_format({'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA", 'bold': True}) bold_red = workbook.add_format({'bold': True, 'font_color': '#fc0d1b', 'text_wrap': True}) italic_header = workbook.add_format({'bg_color': '#e8f5fa', 'italic': True}) italic_lightgrey = workbook.add_format({'italic': True, 'font_color': '#999999'}) italic_darkgrey_question = workbook.add_format({'italic': True, 'font_color': '#666666', 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA"}) darkgrey = workbook.add_format({'font_color': '#666666', 'text_wrap': True}) heading = workbook.add_format({'bold': True, 'font_size': '14', 'text_wrap': True}) header = workbook.add_format({'bg_color': '#e8f5fa'}) cta = workbook.add_format({'bg_color': 'd9ead4', 'align': 'center', 'color': 'blue', 'underline': 1, 'text_wrap': True}) bold_cta = workbook.add_format({'bg_color': 'd9ead4', 'bold': True, 'align': 'center'}) question = workbook.add_format({'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA"}) link = workbook.add_format({'bg_color': '#e8f5fa', 'color': 'blue', 'underline': 1}) right_border_question = workbook.add_format({'right': 1, 'right_color': 'black', 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA"}) sheet = workbook.add_worksheet('Response') sheet.set_column('E:E', 50) sheet.set_column('D:D', 5) sheet.set_column('C:C', 50) sheet.set_column('B:B', 30) sheet.set_column('A:A', 30) sheet.merge_range(0, 0, 0, 2, '', italic_header) sheet.write_url('A1', brief_url) sheet.write_rich_string('A1', italic_header, 'Use this template if you are waiting to be assessed, or want to collaborate ' 'with others, before submitting your response to this brief.\n' 'If you have been assessed and are ready to submit, you will need to ' 'copy and paste your answers from this template into \n', link, brief_url) sheet.write_string('D1', '', right_border_question) df = DateFormatter(current_app.config['DM_TIMEZONE']) sheet.write_string('E1', brief['title'], heading) sheet.write_string('E2', brief['summary'], darkgrey) sheet.write_string('E3', 'For: '+brief['organisation'], darkgrey) sheet.write_string('E4', 'Published: '+df.dateformat(published_date), darkgrey) sheet.write_string('E5', 'Closing date for application: ' + df.datetimeformat(closing_time), bold_red) sheet.write_string('A2', 'Guidance', bold_question) sheet.write_string('B2', 'Question', bold_question) sheet.write_string('C2', 'Answer', bold_question) sheet.write_string('D2', '', right_border_question) sheet.write_string('A3', '', header) sheet.write_string('B3', 'Essential skills and experience', bold_header) sheet.write_string('D3', '', right_border_question) e_start = 4 e = 4 for essential in brief['essentialRequirements']: sheet.write_string('B'+str(e), essential, question) sheet.write_string('C'+str(e), '150 words', italic_lightgrey) sheet.write_string('D'+str(e), '', right_border_question) e += 1 sheet.merge_range(e_start-1, 0, e-2, 0, 'Essential skills and experience\n' 'As a guide to answering the skills and experience criteria, ' 'you could explain:\n' '- What the situation was\n' '- The work the specialist or team completed\n' '- What the results were \n' 'You can reuse examples if you wish. \n' '\n' 'You must have all essential skills and experience ' 'to apply for this opportunity.\n' '150 words max ', italic_darkgrey_question) sheet.write_string('A'+str(e), '', header) sheet.write_string('B'+str(e), 'Nice to have skills and experience', bold_header) sheet.write_string('D'+str(e), '', right_border_question) n_start = e+1 n = e+1 for nice in brief['niceToHaveRequirements']: sheet.write_string('B'+str(n), nice, question) sheet.write_string('C'+str(n), '150 words', italic_lightgrey) sheet.write_string('D'+str(n), '', right_border_question) n += 1 sheet.merge_range(n_start-1, 0, n-2, 0, '', question) sheet.write_string('A'+str(n), '', question) sheet.write_string('B'+str(n), '', question) sheet.write_string('D'+str(n), '', right_border_question) sheet.write_string('A'+str(n+1), '', question) sheet.write_string('B'+str(n+1), "When can you start?", bold_question) sheet.write_string('D'+str(n+1), '', right_border_question) if brief['lotSlug'] == 'digital-professionals': sheet.write_string('A'+str(n+2), '', question) sheet.write_string('B'+str(n+2), "What is your daily rate, including GST?", bold_question) sheet.write_string('D'+str(n+2), '', right_border_question) sheet.write_string('A'+str(n+3), '', question) sheet.write_rich_string('B'+str(n+3), bold_question, "Attach a resume ", question, "Use an Open Document Format (ODF) or PDF/A (eg. .pdf, .odt). " "The maximum file size of each document is 5MB. " "You can upload a maximum of 3 candidate CVs.", question) sheet.write_string('D'+str(n+3), '', right_border_question) n = n + 2 sheet.write_string('A'+str(n+2), '', question) sheet.write_string('B'+str(n+2), '', question) sheet.write_string('D'+str(n+2), '', right_border_question) sheet.write_string('A'+str(n+3), "All communication about your application will be sent to this address", italic_darkgrey_question) sheet.write_string('B'+str(n+3), "Contact email:", bold_question) sheet.write_string('D'+str(n+3), '', right_border_question) sheet.write_string('A'+str(n+4), '', question) sheet.write_string('B'+str(n+4), '', question) sheet.write_string('C'+str(n+4), '', question) sheet.write_string('D'+str(n+4), '', right_border_question) sheet.write_string('C'+str(n+5), 'Ready to apply?', bold_cta) sheet.write_url('C'+str(n+6), brief_url, cta, brief_url) workbook.close() return Response( outdata.getvalue(), mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', headers={ "Content-Disposition": "attachment;filename=brief-response-template-{}.xlsx".format(brief['id']), "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" } ), 200
def get_brief_response_preview_by_id(framework_slug, brief_id): briefs = data_api_client.get_brief(brief_id) brief = briefs.get('briefs') application_url = url_for('main.index', _external=True) + "sellers/opportunities/{}/responses/create"\ .format(brief['id']) if brief['status'] not in ['live', 'closed']: if not current_user.is_authenticated or brief['users'][0][ 'id'] != current_user.id: abort(404, "Opportunity '{}' can not be found".format(brief_id)) hypothetical_dates = brief['dates'].get('hypothetical', None) if hypothetical_dates is None: published_date = brief['dates'].get('published_date', None) closing_time = brief['dates'].get('closing_time', None) else: published_date = hypothetical_dates.get('published_date', None) closing_time = hypothetical_dates.get('closing_time', None) outdata = io.BytesIO() workbook = xlsxwriter.Workbook(outdata) bold_header = workbook.add_format({ 'bg_color': '#e8f5fa', 'bold': True, 'text_wrap': True }) bold_question = workbook.add_format({ 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA", 'bold': True }) bold_red = workbook.add_format({ 'bold': True, 'font_color': '#fc0d1b', 'text_wrap': True }) italic_header = workbook.add_format({ 'bg_color': '#e8f5fa', 'italic': True }) italic_lightgrey = workbook.add_format({ 'italic': True, 'font_color': '#999999' }) italic_darkgrey_question = workbook.add_format({ 'italic': True, 'font_color': '#666666', 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA" }) darkgrey = workbook.add_format({ 'font_color': '#666666', 'text_wrap': True }) heading = workbook.add_format({ 'bold': True, 'font_size': '14', 'text_wrap': True }) header = workbook.add_format({'bg_color': '#e8f5fa'}) cta = workbook.add_format({ 'bg_color': 'd9ead4', 'align': 'center', 'color': 'blue', 'underline': 1, 'text_wrap': True }) bold_cta = workbook.add_format({ 'bg_color': 'd9ead4', 'bold': True, 'align': 'center' }) question = workbook.add_format({ 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA" }) link = workbook.add_format({ 'bg_color': '#e8f5fa', 'color': 'blue', 'underline': 1 }) right_border_question = workbook.add_format({ 'right': 1, 'right_color': 'black', 'bg_color': '#f3f3f3', 'valign': 'top', 'text_wrap': True, 'border': 1, 'border_color': "#AAAAAA" }) sheet = workbook.add_worksheet('Response') sheet.set_column('E:E', 50) sheet.set_column('D:D', 5) sheet.set_column('C:C', 50) sheet.set_column('B:B', 30) sheet.set_column('A:A', 30) sheet.merge_range(0, 0, 0, 2, '', italic_header) sheet.write_url('A1', application_url) sheet.write_rich_string( 'A1', italic_header, 'Use this template if you are waiting to be assessed, or want to collaborate ' 'with others, before submitting your response to this brief.\n' 'If you have been assessed and are ready to submit, you will need to ' 'copy and paste your answers from this template into \n', link, application_url) sheet.write_string('D1', '', right_border_question) df = DateFormatter(current_app.config['DM_TIMEZONE']) sheet.write_string('E1', brief['title'], heading) sheet.write_string('E2', brief['summary'], darkgrey) sheet.write_string('E3', 'For: ' + brief['organisation'], darkgrey) sheet.write_string('E4', 'Published: ' + df.dateformat(published_date), darkgrey) sheet.write_string( 'E5', 'Closing date for application: ' + df.datetimeformat(closing_time), bold_red) sheet.write_string('A2', 'Guidance', bold_question) sheet.write_string('B2', 'Question', bold_question) sheet.write_string('C2', 'Answer', bold_question) sheet.write_string('D2', '', right_border_question) sheet.write_string('A3', '', header) sheet.write_string('B3', 'Essential skills and experience', bold_header) sheet.write_string('D3', '', right_border_question) e_start = 4 e = 4 for essential in brief['essentialRequirements']: sheet.write_string('B' + str(e), essential, question) sheet.write_string('C' + str(e), '150 words', italic_lightgrey) sheet.write_string('D' + str(e), '', right_border_question) e += 1 sheet.merge_range( e_start - 1, 0, e - 2, 0, 'Essential skills and experience\n' 'As a guide to answering the skills and experience criteria, ' 'you could explain:\n' '- What the situation was\n' '- The work the specialist or team completed\n' '- What the results were \n' 'You can reuse examples if you wish. \n' '\n' 'You must have all essential skills and experience ' 'to apply for this opportunity.\n' '150 words max ', italic_darkgrey_question) sheet.write_string('A' + str(e), '', header) sheet.write_string('B' + str(e), 'Nice to have skills and experience', bold_header) sheet.write_string('D' + str(e), '', right_border_question) n_start = e + 1 n = e + 1 for nice in brief['niceToHaveRequirements']: sheet.write_string('B' + str(n), nice, question) sheet.write_string('C' + str(n), '150 words', italic_lightgrey) sheet.write_string('D' + str(n), '', right_border_question) n += 1 sheet.merge_range(n_start - 1, 0, n - 2, 0, '', question) sheet.write_string('A' + str(n), '', question) sheet.write_string('B' + str(n), '', question) sheet.write_string('D' + str(n), '', right_border_question) sheet.write_string('A' + str(n + 1), '', question) sheet.write_string('B' + str(n + 1), "When can you start?", bold_question) sheet.write_string('D' + str(n + 1), '', right_border_question) sheet.write_string('A' + str(n + 2), '', question) sheet.write_string('B' + str(n + 2), '', question) sheet.write_string('D' + str(n + 2), '', right_border_question) sheet.write_string( 'A' + str(n + 3), "All communication about your application will be sent to this address", italic_darkgrey_question) sheet.write_string('B' + str(n + 3), "Contact email:", bold_question) sheet.write_string('D' + str(n + 3), '', right_border_question) sheet.write_string('A' + str(n + 4), '', question) sheet.write_string('B' + str(n + 4), '', question) sheet.write_string('C' + str(n + 4), '', question) sheet.write_string('D' + str(n + 4), '', right_border_question) sheet.write_string('C' + str(n + 5), 'Ready to apply?', bold_cta) sheet.write_url('C' + str(n + 6), application_url, cta, application_url) workbook.close() return Response( outdata.getvalue(), mimetype= 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', headers={ "Content-Disposition": "attachment;filename=brief-response-template-{}.xlsx".format( brief['id']), "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }), 200