def get_agreement_status(supplier, user_info):
    email_address = user_info.get('email_address')

    show_agreement = False
    can_sign_agreement = False
    signed_agreement = False
    can_user_sign_agreement = False
    new_agreement = None
    start_date = pendulum.now('Australia/Canberra').date()

    agreement = get_current_agreement()
    new_agreement = get_new_agreement()
    signed = has_signed_current_agreement(supplier)

    if agreement:
        now = pendulum.now('Australia/Canberra').date()
        start_date = (pendulum.parse(agreement.get('startDate'),
                                     tz='Australia/Canberra').date())
        show_agreement = True
        can_sign_agreement = True
        signed_agreement = True if signed else False

    can_user_sign_agreement = (True if supplier.data.get('email')
                               == email_address else False)

    return {
        'show': show_agreement,
        'canSign': can_sign_agreement,
        'canUserSign': can_user_sign_agreement,
        'signed': signed_agreement,
        'startDate': start_date.strftime('%Y-%m-%d'),
        'currentAgreement': agreement,
        'newAgreement': new_agreement
    }
Example #2
0
def update_application(application_id):
    application_json = get_application_json()

    application = Application.query.options(
        noload('supplier.*')).get(application_id)
    if application is None:
        abort(404, "Application '{}' does not exist".format(application_id))

    if application.status == 'submitted' and application_json.get(
            'status') == 'saved':
        db.session.add(
            AuditEvent(audit_type=AuditTypes.revert_application,
                       user='',
                       data={},
                       db_object=application))
        publish_tasks.application.delay(
            publish_tasks.compress_application(application), 'reverted')

    application.update_from_json(application_json)
    save_application(application)
    errors = ApplicationValidator(application).validate_all()
    agreement = get_current_agreement()

    return (jsonify(application=application.serializable,
                    agreement=agreement.serialize() if agreement else None,
                    application_errors=errors), 200)
Example #3
0
def get_application_by_id(application_id):
    application = (Application.query.filter(
        Application.id == application_id).options(
            joinedload('supplier.domains'),
            joinedload('supplier.domains.assessments'),
            noload('supplier.domains.assessments.briefs')).first_or_404())
    if application.status == 'deleted':
        abort(404)

    agreement = get_current_agreement()

    # Maximum prices are used on the pricing page to encourage value for money
    result = Domain.query.all()
    domains = {'prices': {'maximum': {}}}
    domains['prices']['maximum'] = {
        domain.name: domain.price_maximum
        for domain in result
    }

    errors = ApplicationValidator(application).validate_all()

    return jsonify(application=application.serializable,
                   domains=domains,
                   agreement=agreement.serialize() if agreement else None,
                   application_errors=errors)
Example #4
0
def get_supplier_messages(code, skip_application_check):
    applications = application_service.find(
        supplier_code=code,
        type='edit'
    ).all()

    supplier = suppliers.get_supplier_by_code(code)
    validation_result = SupplierValidator(supplier).validate_all()

    if any([a for a in applications if a.status == 'saved']):
        validation_result.warnings.append({
            'message': 'You have saved updates on your profile. '
                       'You must submit these changes to the Marketplace for review. '
                       'If you did not make any changes, select \'Discard all updates\'.',
            'severity': 'warning',
            'step': 'update',
            'id': 'SB001'
        })

    if not skip_application_check:
        if any([a for a in applications if a.status == 'submitted']):
            del validation_result.warnings[:]
            del validation_result.errors[:]

    if not has_signed_current_agreement(supplier):
        if get_current_agreement():
            message = (
                'Your authorised representative {must accept the new Master Agreement} '
                'before you can apply for opportunities.'
            )
            validation_result.errors.append({
                'message': message,
                'severity': 'error',
                'step': 'representative',
                'id': 'SB002',
                'links': {
                    'must accept the new Master Agreement': '/2/seller-edit/{}/representative'.format(code)
                }
            })
    else:
        new_master_agreement = get_new_agreement()
        if new_master_agreement:
            start_date = new_master_agreement.start_date.in_tz('Australia/Canberra').date()
            message = (
                'From {}, your authorised representative must '
                'accept the new Master Agreement '
                'before you can apply for opportunities.'
            ).format(start_date.strftime('%-d %B %Y'))

            validation_result.warnings.append({
                'message': message,
                'severity': 'warning',
                'step': 'representative',
                'id': 'SB002'
            })

    return validation_result
    def test_seller_has_signed_current_agreement_without_old_signed_agreements(self, master_agreements, supplier, user):
        current_agreement = get_current_agreement()

        supplier.signed_agreements = [
            SignedAgreement(
                agreement_id=current_agreement.id,
                user_id=1,
                signed_at=current_agreement.start_date.add(days=2)
            )
        ]

        signed_current_agreement = has_signed_current_agreement(supplier)

        assert signed_current_agreement is True
Example #6
0
def send_notify_auth_rep_email(supplier_code):
    from app.api.services import (
        audit_service,
        audit_types,
        suppliers,
        key_values_service
    )

    supplier = suppliers.get_supplier_by_code(supplier_code)
    to_address = supplier.data.get('email', '').encode('utf-8')

    agreement = get_new_agreement()
    if agreement is None:
        agreement = get_current_agreement()

    start_date = pendulum.now('Australia/Canberra').date()
    if agreement:
        start_date = agreement.start_date.in_tz('Australia/Canberra')

    # prepare copy
    email_body = render_email_template(
        'seller_edit_notify_auth_rep.md',
        ma_start_date=start_date.strftime('%-d %B %Y'),
        supplier_name=supplier.name,
        supplier_code=supplier.code,
        auth_rep_name=escape_markdown(supplier.data.get('representative', '')),
        frontend_url=current_app.config['FRONTEND_ADDRESS']
    )

    subject = "Accept the Master Agreement for the Digital Marketplace"

    send_or_handle_error(
        to_address,
        email_body,
        subject,
        current_app.config['DM_GENERIC_NOREPLY_EMAIL'],
        current_app.config['DM_GENERIC_SUPPORT_NAME'],
        event_description_for_errors='notify auth rep email'
    )

    audit_service.log_audit_event(
        audit_type=audit_types.notify_auth_rep_accept_master_agreement,
        user='',
        data={
            "to_address": to_address,
            "email_body": email_body,
            "subject": subject
        },
        db_object=supplier)
    def test_seller_has_signed_current_agreement_with_old_signed_agreements(self, master_agreements, supplier, user):
        old_agreements = get_old_agreements()
        current_agreement = get_current_agreement()
        past_and_present_agreements = [agreement for agreement in old_agreements]
        past_and_present_agreements.append(current_agreement)

        supplier.signed_agreements = [
            SignedAgreement(
                agreement_id=agreement.id,
                user_id=1,
                signed_at=agreement.start_date.add(days=2)
            )
            for agreement in past_and_present_agreements
        ]

        signed_current_agreement = has_signed_current_agreement(supplier)

        assert signed_current_agreement is True
def accept_agreement(user_info):
    supplier_code = user_info.get('supplier_code')
    email_address = user_info.get('email_address')
    user_id = user_info.get('user_id')

    supplier = suppliers.get_supplier_by_code(supplier_code)
    mandatory_supplier_checks(supplier)

    if email_address != supplier.data.get('email'):
        raise UnauthorisedError('Unauthorised to accept agreement')

    agreement = get_current_agreement()
    if agreement is None:
        raise NotFoundError('Current master agreement not found')

    already_signed = signed_agreement_service.first(
        agreement_id=agreement.id, supplier_code=supplier_code)
    if already_signed:
        raise ValidationError('Already signed agreement')

    signed_agreement = SignedAgreement(
        agreement_id=agreement.id,
        user_id=user_id,
        signed_at=pendulum.now('Australia/Canberra'),
        supplier_code=supplier_code)
    signed_agreement_service.save(signed_agreement)

    publish_tasks.supplier.delay(publish_tasks.compress_supplier(supplier),
                                 'accepted_agreement',
                                 updated_by=email_address)

    audit_service.log_audit_event(
        audit_type=audit_types.accepted_master_agreement,
        user=email_address,
        data={
            'supplierCode': supplier.code,
            'supplierData': supplier.data
        },
        db_object=supplier)
Example #9
0
def submit_application(application_id):
    current_time = pendulum.now('UTC').to_iso8601_string(extended=True)

    application = Application.query.get(application_id)
    if application is None:
        abort(404, "Application '{}' does not exist".format(application_id))

    if application.status == 'submitted':
        abort(400, 'Application is already submitted')

    errors = ApplicationValidator(application).validate_all()
    if errors:
        abort(400, 'Application has errors')

    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['user_id'])
    user_id = json_payload['user_id']

    user = User.query.get(user_id)

    if application.type != 'edit':
        if user.application_id != application.id:
            abort(400, 'User is not authorized to submit application')
    else:
        if user.supplier_code != application.supplier_code:
            abort(
                400,
                'User supplier code does not match application supplier code')

    agreement = get_current_agreement()
    if agreement is None:
        abort(404, 'Current master agreement not found')

    db.session.add(
        AuditEvent(audit_type=AuditTypes.submit_application,
                   user=user_id,
                   data={},
                   db_object=application))

    application.submit_for_approval()

    application.update_from_json({'submitted_at': current_time})

    signed_agreement = None
    if application.type != 'edit':
        # only create signed agreements on initial applications
        signed_agreement = SignedAgreement()
        signed_agreement.user_id = user_id
        signed_agreement.agreement_id = agreement.id
        signed_agreement.signed_at = current_time
        signed_agreement.application_id = application_id

        db.session.add(signed_agreement)

        if application.supplier_code:
            send_submitted_existing_seller_notification(application.id)
        else:
            send_submitted_new_seller_notification(application.id)

    db.session.commit()
    publish_tasks.application.delay(
        publish_tasks.compress_application(application), 'submitted')
    return jsonify(application=application.serializable,
                   signed_agreement=signed_agreement)
Example #10
0
    def test_current_agreement_is_in_the_present(self, master_agreements):
        current_agreement = get_current_agreement()
        now = pendulum.now('utc')

        assert current_agreement.start_date <= now
        assert current_agreement.end_date >= now