def create_message(session):
    """Creates and sends a message outside of the context of an existing conversation"""
    survey_id = request.args["survey"]
    ru_ref = request.args["ru_ref"]
    party_id = session.get_party_id()
    form = SecureMessagingForm(request.form)
    if request.method == "POST" and form.validate():
        logger.info("Form validation successful", party_id=party_id)
        sent_message = _send_new_message(party_id, survey_id, ru_ref)
        thread_url = (url_for("secure_message_bp.view_conversation",
                              thread_id=sent_message["thread_id"]) +
                      "#latest-message")
        flash(Markup(f"Message sent. <a href={thread_url}>View Message</a>"))
        return redirect(url_for("secure_message_bp.view_conversation_list"))

    else:
        unread_message_count = {
            "unread_message_count":
            conversation_controller.try_message_count_from_session(session)
        }
        return render_template(
            "secure-messages/secure-messages-view.html",
            ru_ref=ru_ref,
            survey_id=survey_id,
            form=form,
            errors=form.errors,
            message={},
            unread_message_count=unread_message_count,
        )
def upload_failed(session):
    case_id = request.args.get('case_id')
    business_party_id = request.args['business_party_id']
    survey_short_name = request.args['survey_short_name']
    party_id = session.get_party_id()
    error_info = request.args.get('error_info', None)

    case_data = case_controller.get_case_data(case_id, party_id, business_party_id, survey_short_name)

    # Select correct error text depending on error_info
    if error_info == "type":
        error_info = {'header': "Error uploading - incorrect file type",
                      'body': 'The spreadsheet must be in .xls or .xlsx format'}
    elif error_info == "charLimit":
        error_info = {'header': "Error uploading - file name too long",
                      'body': 'The file name of your spreadsheet must be '
                              'less than 50 characters long'}
    elif error_info == "size":
        error_info = {'header': "Error uploading - file size too large",
                      'body': 'The spreadsheet must be smaller than 20MB in size'}
    elif error_info == "sizeSmall":
        error_info = {'header': "Error uploading - file size too small",
                      'body': "The spreadsheet must be larger than 6KB in size"}
    else:
        error_info = {'header': "Something went wrong",
                      'body': 'Please try uploading your spreadsheet again'}
    unread_message_count = { 'unread_message_count': conversation_controller.try_message_count_from_session(session) }
    return render_template('surveys/surveys-upload-failure.html', business_info=case_data['business_party'], survey_info=case_data['survey'],
                           collection_exercise_info=case_data['collection_exercise'], error_info=error_info, case_id=case_id,
                           unread_message_count=unread_message_count)
Example #3
0
    def test_get_message_count_from_session(self):
        session = Session.from_party_id("id")
        session.set_unread_message_total(3)
        with app.app_context():
            count = conversation_controller.try_message_count_from_session(
                session)

            self.assertEqual(3, count)
def get_survey_list(session, tag):
    """
    Displays the list of surveys for the respondent by tag.  A tag represents the state the
    survey is in (e.g., todo, history, etc)
    """
    party_id = session.get_party_id()
    business_id = request.args.get('business_party_id')
    survey_id = request.args.get('survey_id')
    already_enrolled = request.args.get('already_enrolled')
    bound_logger = logger.bind(party_id=party_id,
                               business_id=business_id,
                               survey_id=survey_id,
                               already_enrolled=already_enrolled,
                               tag=tag)
    bound_logger.info("Retrieving survey list")

    survey_list = party_controller.get_survey_list_details_for_party(
        party_id, tag, business_party_id=business_id, survey_id=survey_id)

    sorted_survey_list = sorted(
        survey_list,
        key=lambda k: datetime.strptime(k['submit_by'], '%d %b %Y'),
        reverse=True)
    bound_logger.info("Successfully retreived survey list")

    unread_message_count = {
        'unread_message_count':
        conversation_controller.try_message_count_from_session(session)
    }
    if tag == 'todo':
        added_survey = True if business_id and survey_id and not already_enrolled else None
        response = make_response(
            render_template('surveys/surveys-todo.html',
                            sorted_surveys_list=sorted_survey_list,
                            added_survey=added_survey,
                            already_enrolled=already_enrolled,
                            unread_message_count=unread_message_count))

        # Ensure any return to list of surveys (e.g. browser back) round trips the server to display the latest statuses
        response.headers.set("Cache-Control",
                             "no-cache, max-age=0, must-revalidate, no-store")

        return response
    else:
        return render_template('surveys/surveys-history.html',
                               sorted_surveys_list=sorted_survey_list,
                               history=True,
                               unread_message_count=unread_message_count)
Example #5
0
def access_survey(session):
    party_id = session.get_party_id()
    case_id = request.args["case_id"]
    business_party_id = request.args["business_party_id"]
    survey_short_name = request.args["survey_short_name"]
    collection_instrument_type = request.args["ci_type"]

    if collection_instrument_type == "EQ":
        logger.info("Attempting to redirect to EQ",
                    party_id=party_id,
                    case_id=case_id)
        case = case_controller.get_case_by_case_id(case_id)
        collection_exercise = collection_exercise_controller.get_collection_exercise(
            case["caseGroup"]["collectionExerciseId"])
        eq_version = collection_exercise["eqVersion"]
        return redirect(
            case_controller.get_eq_url(eq_version, case, collection_exercise,
                                       party_id, business_party_id,
                                       survey_short_name))

    logger.info("Retrieving case data", party_id=party_id, case_id=case_id)
    case_data = case_controller.get_case_data(case_id, party_id,
                                              business_party_id,
                                              survey_short_name)
    referer_header = request.headers.get("referer", {})

    logger.info("Successfully retrieved case data",
                party_id=party_id,
                case_id=case_id)
    unread_message_count = {
        "unread_message_count":
        conversation_controller.try_message_count_from_session(session)
    }
    return render_template(
        "surveys/surveys-access.html",
        case_id=case_id,
        collection_instrument_id=case_data["collection_instrument"]["id"],
        collection_instrument_size=case_data["collection_instrument"]["len"],
        survey_info=case_data["survey"],
        collection_exercise_info=case_data["collection_exercise"],
        business_info=case_data["business_party"],
        referer_header=referer_header,
        unread_message_count=unread_message_count,
    )
def upload_failed(session):
    case_id = request.args.get("case_id")
    business_party_id = request.args["business_party_id"]
    survey_short_name = request.args["survey_short_name"]
    party_id = session.get_party_id()
    error_info = request.args.get("error_info", None)

    case_data = case_controller.get_case_data(case_id, party_id, business_party_id, survey_short_name)

    # Select correct error text depending on error_info
    if error_info == "type":
        error_info = {
            "header": "Error uploading - incorrect file type",
            "body": "The spreadsheet must be in .xls or .xlsx format",
        }
    elif error_info == "charLimit":
        error_info = {
            "header": "Error uploading - file name too long",
            "body": "The file name of your spreadsheet must be " "less than 50 characters long",
        }
    elif error_info == "size":
        error_info = {
            "header": "Error uploading - file size too large",
            "body": "The spreadsheet must be smaller than 20MB in size",
        }
    elif error_info == "sizeSmall":
        error_info = {
            "header": "Error uploading - file size too small",
            "body": "The spreadsheet must be larger than 6KB in size",
        }
    else:
        error_info = {"header": "Something went wrong", "body": "Please try uploading your spreadsheet again"}
    unread_message_count = {"unread_message_count": conversation_controller.try_message_count_from_session(session)}
    return render_template(
        "surveys/surveys-upload-failure.html",
        business_info=case_data["business_party"],
        survey_info=case_data["survey"],
        collection_exercise_info=case_data["collection_exercise"],
        error_info=error_info,
        case_id=case_id,
        unread_message_count=unread_message_count,
    )
def view_conversation_list(session):
    party_id = session.get_party_id()
    logger.info('Getting conversation list', party_id=party_id)
    is_closed = request.args.get('is_closed', default='false')
    params = {'is_closed': is_closed}

    conversation = get_conversation_list(params=params)

    try:
        refined_conversation = [refine(message) for message in conversation]
    except KeyError:
        logger.error('A key error occurred', party_id=party_id)
        raise
    logger.info('Retrieving and refining conversation successful',
                party_id=party_id)
    unread_message_count = {
        'unread_message_count': try_message_count_from_session(session)
    }
    return render_template('secure-messages/conversation-list.html',
                           messages=refined_conversation,
                           is_closed=strtobool(is_closed),
                           unread_message_count=unread_message_count)
Example #8
0
    def test_get_message_count_from_api_when_expired(self, headers):
        headers.return_value = {'Authorization': "token"}
        session = Session.from_party_id("id")
        decoded = session.get_decoded_jwt()
        decoded['unread_message_count']['refresh_in'] = (
            datetime.fromtimestamp(
                decoded['unread_message_count']['refresh_in']) -
            timedelta(seconds=301)).timestamp()
        encoded = jwt.encode(decoded)
        session.encoded_jwt_token = encoded
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET,
                     url_get_conversation_count,
                     json=message_count,
                     status=200,
                     headers={'Authorisation': 'token'},
                     content_type='application/json')
            with app.app_context():
                count = conversation_controller.try_message_count_from_session(
                    session)

                self.assertEqual(3, count)
def access_survey(session):
    party_id = session.get_party_id()
    case_id = request.args['case_id']
    business_party_id = request.args['business_party_id']
    survey_short_name = request.args['survey_short_name']
    collection_instrument_type = request.args['ci_type']

    if collection_instrument_type == 'EQ':
        logger.info('Attempting to redirect to EQ',
                    party_id=party_id,
                    case_id=case_id)
        return redirect(
            case_controller.get_eq_url(case_id, party_id, business_party_id,
                                       survey_short_name))

    logger.info('Retrieving case data', party_id=party_id, case_id=case_id)
    referer_header = request.headers.get('referer', {})

    case_data = case_controller.get_case_data(case_id, party_id,
                                              business_party_id,
                                              survey_short_name)

    logger.info('Successfully retrieved case data',
                party_id=party_id,
                case_id=case_id)
    unread_message_count = {
        'unread_message_count':
        conversation_controller.try_message_count_from_session(session)
    }
    return render_template(
        'surveys/surveys-access.html',
        case_id=case_id,
        collection_instrument_id=case_data['collection_instrument']['id'],
        collection_instrument_size=case_data['collection_instrument']['len'],
        survey_info=case_data['survey'],
        collection_exercise_info=case_data['collection_exercise'],
        business_info=case_data['business_party'],
        referer_header=referer_header,
        unread_message_count=unread_message_count)
Example #10
0
def view_conversation_list(session):
    party_id = session.get_party_id()
    logger.info("Getting conversation list", party_id=party_id)
    is_closed = request.args.get("is_closed", default="false")
    params = {"is_closed": is_closed}

    conversation = get_conversation_list(params=params)

    try:
        refined_conversation = [refine(message) for message in conversation]
    except KeyError:
        logger.error("A key error occurred", party_id=party_id)
        raise
    logger.info("Retrieving and refining conversation successful",
                party_id=party_id)
    unread_message_count = {
        "unread_message_count": try_message_count_from_session(session)
    }
    return render_template(
        "secure-messages/conversation-list.html",
        messages=refined_conversation,
        is_closed=strtobool(is_closed),
        unread_message_count=unread_message_count,
    )
Example #11
0
def upload_survey(session):
    party_id = session.get_party_id()
    case_id = request.args["case_id"]
    business_party_id = request.args["business_party_id"]
    survey_short_name = request.args["survey_short_name"]
    logger.info("Attempting to upload collection instrument",
                case_id=case_id,
                party_id=party_id)

    if request.content_length > app.config["MAX_UPLOAD_LENGTH"]:
        return redirect(
            url_for(
                "surveys_bp.upload_failed",
                _external=True,
                case_id=case_id,
                business_party_id=business_party_id,
                survey_short_name=survey_short_name,
                error_info="size",
            ))

    # Check if respondent has permission to upload for this case
    survey = survey_controller.get_survey_by_short_name(survey_short_name)
    if not party_controller.is_respondent_enrolled(party_id, business_party_id,
                                                   survey):
        raise NoSurveyPermission(party_id, case_id)

    case = case_controller.get_case_by_case_id(case_id)

    case_group = case.get("caseGroup")
    collection_exercise_id = case_group.get("collectionExerciseId")
    business_party = party_controller.get_party_by_business_id(
        case_group["partyId"],
        app.config["PARTY_URL"],
        app.config["BASIC_AUTH"],
        collection_exercise_id=collection_exercise_id,
        verbose=True,
    )

    # Get the uploaded file
    upload_file = request.files["file"]

    try:
        # Upload the file to the collection instrument service
        collection_instrument_controller.upload_collection_instrument(
            upload_file, case, business_party, party_id, survey)
    except CiUploadError as ex:
        error_type = determine_error_type(ex)
        if not error_type:
            logger.error(
                "Unexpected error message returned from collection instrument service",
                error_message=ex.error_message,
                party_id=party_id,
                case_id=case_id,
            )
            error_type = "unexpected"
        return redirect(
            url_for(
                "surveys_bp.upload_failed",
                _external=True,
                case_id=case_id,
                business_party_id=business_party_id,
                survey_short_name=survey_short_name,
                error_info=error_type,
            ))

    logger.info("Successfully uploaded collection instrument",
                party_id=party_id,
                case_id=case_id)
    unread_message_count = {
        "unread_message_count":
        conversation_controller.try_message_count_from_session(session)
    }
    return render_template(
        "surveys/surveys-upload-success.html",
        upload_filename=upload_file.filename,
        unread_message_count=unread_message_count,
    )
Example #12
0
def get_survey_list(session, tag):
    """
    Displays the list of surveys for the respondent by tag.  A tag represents the state the
    survey is in (e.g., todo, history, etc)
    """
    flask_session.pop("help_survey_ref", None)
    flask_session.pop("help_ru_ref", None)
    party_id = session.get_party_id()
    business_id = request.args.get("business_party_id")
    survey_id = request.args.get("survey_id")
    already_enrolled = request.args.get("already_enrolled")
    logger.info(
        "Retrieving survey list",
        party_id=party_id,
        business_id=business_id,
        survey_id=survey_id,
        already_enrolled=already_enrolled,
        tag=tag,
    )

    # This logic is added to make sure a user is provided an option to delete an account if there is no
    # active enrolment which is ENABLED
    respondent = party_controller.get_respondent_party_by_id(party_id)
    delete_option_allowed = is_delete_account_respondent_allowed(respondent)

    survey_list = party_controller.get_survey_list_details_for_party(
        respondent, tag, business_party_id=business_id, survey_id=survey_id)
    sorted_survey_list = sorted(
        survey_list,
        key=lambda k: datetime.strptime(k["submit_by"], "%d %b %Y"),
        reverse=True)
    logger.info(
        "Successfully retrieved survey list",
        party_id=party_id,
        business_id=business_id,
        survey_id=survey_id,
        already_enrolled=already_enrolled,
        tag=tag,
    )

    unread_message_count = {
        "unread_message_count":
        conversation_controller.try_message_count_from_session(session)
    }
    if tag == "todo":
        added_survey = True if business_id and survey_id and not already_enrolled else None
        response = make_response(
            render_template(
                "surveys/surveys-todo.html",
                sorted_surveys_list=sorted_survey_list,
                added_survey=added_survey,
                already_enrolled=already_enrolled,
                unread_message_count=unread_message_count,
                delete_option_allowed=delete_option_allowed,
            ))

        # Ensure any return to list of surveys (e.g. browser back) round trips the server to display the latest statuses
        response.headers.set("Cache-Control",
                             "no-cache, max-age=0, must-revalidate, no-store")

        return response
    else:
        return render_template(
            "surveys/surveys-history.html",
            sorted_surveys_list=sorted_survey_list,
            history=True,
            unread_message_count=unread_message_count,
        )
def upload_survey(session):
    party_id = session.get_party_id()
    case_id = request.args['case_id']
    business_party_id = request.args['business_party_id']
    survey_short_name = request.args['survey_short_name']
    logger.info('Attempting to upload collection instrument',
                case_id=case_id,
                party_id=party_id)

    if request.content_length > app.config['MAX_UPLOAD_LENGTH']:
        return redirect(
            url_for('surveys_bp.upload_failed',
                    _external=True,
                    case_id=case_id,
                    business_party_id=business_party_id,
                    survey_short_name=survey_short_name,
                    error_info='size'))

    # Check if respondent has permission to upload for this case
    party_controller.is_respondent_enrolled(party_id, business_party_id,
                                            survey_short_name)

    # Get the uploaded file
    upload_file = request.files['file']
    upload_filename = upload_file.filename
    upload_file = {
        'file': (upload_filename, upload_file.stream, upload_file.mimetype, {
            'Expires': 0
        })
    }

    try:
        # Upload the file to the collection instrument service
        collection_instrument_controller.upload_collection_instrument(
            upload_file, case_id, party_id)
    except CiUploadError as ex:
        if ".xlsx format" in ex.error_message:
            error_info = "type"
        elif "50 characters" in ex.error_message:
            error_info = "charLimit"
        elif "File too large" in ex.error_message:
            error_info = 'size'
        elif "File too small" in ex.error_message:
            error_info = 'sizeSmall'
        else:
            logger.error(
                'Unexpected error message returned from collection instrument service',
                status=ex.status_code,
                error_message=ex.error_message,
                party_id=party_id,
                case_id=case_id)
            error_info = "unexpected"
        return redirect(
            url_for('surveys_bp.upload_failed',
                    _external=True,
                    case_id=case_id,
                    business_party_id=business_party_id,
                    survey_short_name=survey_short_name,
                    error_info=error_info))

    logger.info('Successfully uploaded collection instrument',
                party_id=party_id,
                case_id=case_id)
    unread_message_count = {
        'unread_message_count':
        conversation_controller.try_message_count_from_session(session)
    }
    return render_template('surveys/surveys-upload-success.html',
                           upload_filename=upload_filename,
                           unread_message_count=unread_message_count)