def download_brief_responses(brief_id):
    brief = Brief.query.filter(
        Brief.id == brief_id
    ).first_or_404()
    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")
    if brief.status != 'closed':
        return forbidden("You can only download documents for closed briefs")

    response = ('', 404)
    if brief.lot.slug in ['digital-professionals', 'training', 'rfx', 'atm']:
        try:
            file = s3_download_file(
                'brief-{}-resumes.zip'.format(brief_id),
                os.path.join(brief.framework.slug, 'archives', 'brief-{}'.format(brief_id))
            )
        except botocore.exceptions.ClientError as e:
            rollbar.report_exc_info()
            not_found("Brief documents not found for brief id '{}'".format(brief_id))

        response = Response(file, mimetype='application/zip')
        response.headers['Content-Disposition'] = 'attachment; filename="brief-{}-responses.zip"'.format(brief_id)
    elif brief.lot.slug == 'digital-outcome':
        responses = BriefResponse.query.filter(
            BriefResponse.brief_id == brief_id,
            BriefResponse.withdrawn_at.is_(None)
        ).all()
        csvdata = generate_brief_responses_csv(brief, responses)
        response = Response(csvdata, mimetype='text/csv')
        response.headers['Content-Disposition'] = (
            'attachment; filename="responses-to-requirements-{}.csv"'.format(brief_id))

    return response
Exemple #2
0
def test_csv_rfx(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,[email protected]',
        u'Phone number,1234'
    ]
    assert csvdata.splitlines() == lines
Exemple #3
0
def test_csv_training(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,[email protected]',
        u'Availability date,\u275dNext \u2014 Tuesday\u275e',
        u'Phone number,1234', u'MS Paint,True', u'GIMP,True', u'LISP,True'
    ]
    assert csvdata.splitlines() == lines
def test_csv_rfx(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1',
        u'Email,[email protected]',
        u'Phone number,1234',
        u'ABN,1'
    ]
    assert csvdata.splitlines() == lines
Exemple #5
0
def test_csv_handles_tricky_characters_1(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,[email protected]',
        u'Specialist name,"Bu,tties K,ev\u2019s """',
        u'Availability date,\u275dNext \u2014 Tuesday\u275e', u'Day rate,1.49',
        u'Contact number,123', u'MS Paint,True', u'GIMP,True', u'LISP,True'
    ]
    assert csvdata.splitlines() == lines
Exemple #6
0
def test_csv_handles_tricky_characters_2(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,"te,[email protected]"',
        u"Specialist name,'Pies Kev's",
        u'Availability date,"A week Friday&rdquot;', u'Day rate,3.50',
        u'Contact number,123', u'MS Paint,True', u'GIMP,True', u'LISP,False'
    ]
    assert csvdata.splitlines() == lines
Exemple #7
0
def test_csv_handles_tricky_characters_3(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1',
        u"Email,SUM(1+1)*cmd|' /C calc'!A0",
        u"Specialist name,SUM(1+1)*cmd|' /C calc'!A0",
        u"Availability date,cmd| '/c calc'!A0", u'Day rate,"2+2,"',
        u'Contact number,123', u'MS Paint,True', u'GIMP,True', u'LISP,False'
    ]
    assert csvdata.splitlines() == lines
def test_csv_training(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1',
        u'Email,[email protected]',
        u'Availability Date,\u275dNext \u2014 Tuesday\u275e',
        u'Phone number,1234',
        u'ABN,1',
        u'MS Paint,True',
        u'GIMP,True',
        u'LISP,True'
    ]
    assert csvdata.splitlines() == lines
Exemple #9
0
def test_csv_specialist_hourly_rate(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,[email protected]',
        u'Specialist given name(s),foo', u'Specialist surname,bar',
        u'Availability date,in the future', u'Hourly rate (including GST),11',
        u'Hourly rate (excluding GST),10',
        u'Eligibility to work,Australian citizen',
        u'Previous agency experience,Yes', u'Security clearance,N/A',
        u'Contact number,123', u'ess critiera 1,ess criteria 1 answer',
        u'ess critiera 2,ess criteria 2 answer', u'nth critiera 1,'
    ]
    assert csvdata.splitlines() == lines
def test_csv_handles_tricky_characters_3(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1',
        u"Email,SUM(1+1)*cmd|' /C calc'!A0",
        u"Specialist Name,SUM(1+1)*cmd|' /C calc'!A0",
        u"Availability Date,cmd| '/c calc'!A0",
        u'Day rate,"2+2,"',
        u'ABN,1',
        u'MS Paint,True',
        u'GIMP,True',
        u'LISP,False'
    ]
    assert csvdata.splitlines() == lines
def test_csv_handles_tricky_characters_1(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1',
        u'Email,[email protected]',
        u'Specialist Name,"Bu,tties K,ev\u2019s """',
        u'Availability Date,\u275dNext \u2014 Tuesday\u275e',
        u'Day rate,1.49',
        u'ABN,1',
        u'MS Paint,True',
        u'GIMP,True',
        u'LISP,True'
    ]
    assert csvdata.splitlines() == lines
def test_csv_handles_tricky_characters_2(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1',
        u'Email,"te,[email protected]"',
        u"Specialist Name,'Pies Kev's",
        u'Availability Date,"A week Friday&rdquot;',
        u'Day rate,3.50',
        u'ABN,1',
        u'MS Paint,True',
        u'GIMP,True',
        u'LISP,False'
    ]
    assert csvdata.splitlines() == lines
def test_csv_handles_tricky_characters_2(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,"te,[email protected]"',
        u"Specialist given name(s),Kev's", u"Specialist surname,'Pies",
        u'Availability date,"A week Friday&rdquot;',
        u'Day rate (including GST),3.50', u'Day rate (excluding GST),',
        u'Previous agency experience,', u'Security clearance,N/A',
        u'Contact number,123', u'TEST,x', u'TEST 2,y', u'LISP,',
        u'Victoria Labour hire licence,',
        u'Victoria Labour hire licence expiry,',
        u'Queensland Labour hire licence,',
        u'Queensland Labour hire licence expiry,'
    ]
    assert csvdata.splitlines() == lines
def test_csv_handles_tricky_characters_1(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,[email protected]',
        u'Specialist given name(s),"Bu,tties"',
        u'Specialist surname,"K,ev\u2019s """',
        u'Availability date,\u275dNext \u2014 Tuesday\u275e',
        u'Day rate (including GST),1.49', u'Day rate (excluding GST),',
        u'Previous agency experience,', u'Security clearance,N/A',
        u'Contact number,123', u'TEST,x', u'TEST 2,y', u'LISP,',
        u'Victoria Labour hire licence,',
        u'Victoria Labour hire licence expiry,',
        u'Queensland Labour hire licence,',
        u'Queensland Labour hire licence expiry,'
    ]
    assert csvdata.splitlines() == lines
def test_csv_handles_tricky_characters_3(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1',
        u"Email,SUM(1+1)*cmd|' /C calc'!A0",
        u"Specialist given name(s),SUM(1+1)*cmd|'",
        u"Specialist surname,/C calc'!A0",
        u"Availability date,cmd| '/c calc'!A0",
        u'Day rate (including GST),"2+2,"', u'Day rate (excluding GST),',
        u'Previous agency experience,', u'Security clearance,N/A',
        u'Contact number,123', u'TEST,x', u'TEST 2,y', u'LISP,',
        u'Victoria Labour hire licence,',
        u'Victoria Labour hire licence expiry,',
        u'Queensland Labour hire licence,',
        u'Queensland Labour hire licence expiry,'
    ]
    assert csvdata.splitlines() == lines
def test_csv_specialist_daily_rate(app, briefs, brief_responses):
    csvdata = generate_brief_responses_csv(briefs[0], brief_responses)
    lines = [
        u'Seller name,Test Supplier1', u'ABN,1', u'Email,[email protected]',
        u'Specialist given name(s),foo', u'Specialist surname,bar',
        u'Availability date,in the future', u'Day rate (including GST),11',
        u'Day rate (excluding GST),10',
        u'Eligibility to work,Australian citizen',
        u'Previous agency experience,Yes',
        u'Holds a negative vetting level 1 security clearance,Yes',
        u'Contact number,123', u'ess critiera 1,ess criteria 1 answer',
        u'ess critiera 2,ess criteria 2 answer',
        u'Victoria Labour hire licence,',
        u'Victoria Labour hire licence expiry,',
        u'Queensland Labour hire licence,',
        u'Queensland Labour hire licence expiry,'
    ]
    assert csvdata.splitlines() == lines
Exemple #17
0
def create_responses_zip(brief_id):
    brief = briefs.find(id=brief_id).one_or_none()

    if not brief:
        raise CreateResponsesZipException(
            'Failed to load brief for id {}'.format(brief_id))

    responses = brief_responses_service.get_responses_to_zip(
        brief_id, brief.lot.slug)

    if not responses:
        raise CreateResponsesZipException(
            'There were no respones for brief id {}'.format(brief_id))

    if brief.lot.slug not in [
            'digital-professionals', 'training', 'rfx', 'training2', 'atm',
            'specialist'
    ]:
        raise CreateResponsesZipException(
            'Brief id {} is not a compatible lot'.format(brief_id))

    print 'Generating zip for brief id: {}'.format(brief_id)

    BUCKET_NAME = getenv('S3_BUCKET_NAME')
    s3 = boto3.resource('s3',
                        region_name=getenv('AWS_REGION'),
                        aws_access_key_id=getenv('AWS_ACCESS_KEY_ID'),
                        aws_secret_access_key=getenv('AWS_SECRET_ACCESS_KEY'),
                        endpoint_url=getenv('AWS_S3_URL'))
    bucket = s3.Bucket(BUCKET_NAME)

    files = []
    attachments = brief_responses_service.get_all_attachments(brief_id)
    for attachment in attachments:
        if attachment['file_name'].startswith(
                'digital-marketplace') and '/' in attachment['file_name']:
            key = attachment['file_name']
            zip_file_name = attachment['file_name'].split('/')[-1]
        else:
            key = 'digital-marketplace/documents/brief-{}/supplier-{}/{}'.format(
                brief_id, attachment['supplier_code'], attachment['file_name'])
            zip_file_name = attachment['file_name']
        files.append({
            'key':
            key,
            'zip_name':
            'opportunity-{}-documents/{}/{}'.format(
                brief_id, secure_filename(attachment['supplier_name']),
                zip_file_name)
        })

    with tempfile.TemporaryFile() as archive:
        with zipfile.ZipFile(archive,
                             mode='w',
                             compression=zipfile.ZIP_DEFLATED) as zf:
            for file in files:
                s3file = file['key']
                with BytesIO() as s3_stream:
                    try:
                        bucket.download_fileobj(s3file, s3_stream)
                        zf.writestr(file['zip_name'], s3_stream.getvalue())
                    except botocore.exceptions.ClientError as e:
                        raise CreateResponsesZipException(
                            'The file "{}" failed to download'.format(s3file))
                    finally:
                        s3_stream.close()

            csvdata = generate_brief_responses_csv(brief, responses)
            csv_file_name = (
                'opportunity-{}-raw.csv'.format(brief_id)
                if brief.lot.slug == 'digital-professionals' else
                'responses-to-requirements-{}.csv'.format(brief_id))
            zf.writestr(csv_file_name, csvdata.encode('utf-8'))

            if brief.lot.slug == 'digital-professionals':
                compliance_check_template = template_env.get_template(
                    'compliance-check.html')
                compliance_check_html = render_template(
                    compliance_check_template,
                    brief=brief,
                    responses=responses)
                zf.writestr('compliance-check-{}.html'.format(brief_id),
                            compliance_check_html.encode('utf-8'))

                candidates = prepare_specialist_responses(brief, responses)

                response_criteria_template = template_env.get_template(
                    'response-criteria.html')
                response_criteria_html = render_template(
                    response_criteria_template,
                    brief=brief,
                    candidates=candidates)
                zf.writestr('responses-{}.html'.format(brief_id),
                            response_criteria_html.encode('utf-8'))
            elif brief.lot.slug == 'specialist':
                compliance_check_template = template_env.get_template(
                    'compliance-check-specialist.html')
                supplier_labour_hire = {}
                for response in responses:
                    labour_hire = []
                    for state, state_value in response.supplier.data.get(
                            'labourHire', {}).iteritems():
                        if state_value.get(
                                'licenceNumber') and state_value.get('expiry'):
                            state_value['state'] = state.upper()
                            state_value['expiry'] = (pendulum.parse(
                                state_value['expiry']).format(
                                    'DD MMMM YYYY', formatter='alternative'))
                            labour_hire.append(state_value)
                    supplier_labour_hire[response.supplier.code] = labour_hire

                compliance_check_html = render_template(
                    compliance_check_template,
                    brief=brief,
                    supplier_labour_hire=supplier_labour_hire,
                    responses=responses)
                zf.writestr('Compliance check ({}).html'.format(brief_id),
                            compliance_check_html.encode('utf-8'))

                response_criteria_template = template_env.get_template(
                    'response-criteria-specialist.html')

                candidates = []
                for response in responses:
                    data = response.data
                    candidates.append({
                        'essential_requirement_responses':
                        data.get('essentialRequirements', {}),
                        'nice_to_have_requirement_responses':
                        data.get('niceToHaveRequirements', {}),
                        'name':
                        '{} {}'.format(data.get('specialistGivenNames', ''),
                                       data.get('specialistSurname', '')),
                        'seller':
                        response.supplier.name
                    })

                response_criteria_html = render_template(
                    response_criteria_template,
                    brief=brief,
                    candidates=candidates,
                    essential_requirements=brief.data.get(
                        'essentialRequirements', {}),
                    nice_to_have_requirements=brief.data.get(
                        'niceToHaveRequirements', {}))

                zf.writestr('Responses ({}).html'.format(brief_id),
                            response_criteria_html.encode('utf-8'))

        archive.seek(0)

        try:
            brief.responses_zip_filesize = len(archive.read())
            archive.seek(0)
            db.session.add(brief)
            db.session.commit()
        except Exception as e:
            raise CreateResponsesZipException(str(e))

        try:
            bucket.upload_fileobj(
                archive,
                'digital-marketplace/archives/brief-{}/brief-{}-resumes.zip'.
                format(brief_id, brief_id))
        except botocore.exceptions.ClientError as e:
            raise CreateResponsesZipException(
                'The responses archive for brief id "{}" failed to upload'.
                format(brief_id))