def associate_business_and_respondent(self, business_id, respondent_id, session): business = query_business_by_party_uuid(business_id, session) respondent = query_respondent_by_party_uuid(respondent_id, session) br = BusinessRespondent(business=business, respondent=respondent) session.add(br)
def get_party_by_id(sample_unit_type, party_id, session): """ Get a party by its party_id. Need to provide the type of party, otherwise it will return a BadRequest :param sample_unit_type: Type of the party :param party_id: uuid identifier of the party :raises BadRequest: Raised if the sample_unit_type is not recognised :raises NotFound: Raised if the party_id doesn't match one in the database """ if sample_unit_type == Business.UNIT_TYPE: business = query_business_by_party_uuid(party_id, session) if not business: logger.info("Business with id does not exist", business_id=party_id, status=404) raise NotFound("Business with id does not exist") return business.to_party_dict() elif sample_unit_type == Respondent.UNIT_TYPE: respondent = query_respondent_by_party_uuid(party_id, session) if not respondent: logger.info("Respondent with id does not exist", respondent_id=party_id, status=404) raise NotFound("Respondent with id does not exist") return respondent.to_party_dict() else: logger.info("Invalid sample unit type", type=sample_unit_type) raise BadRequest( f"{sample_unit_type} is not a valid value for sampleUnitType. Must be one of ['B', 'BI']" )
def notify_change_account_status(payload, party_id, session): status = payload['status_change'] respondent = query_respondent_by_party_uuid(party_id, session) if not respondent: logger.info("Respondent does not exist") raise NotFound("Respondent does not exist") email_address = respondent.email_address # Unlock respondents account if status == 'ACTIVE': # Checking enrolment status, if PENDING we will change it to ENABLED logger.info('Checking enrolment status', respondent_id=party_id) if respondent.pending_enrolment: enrol_respondent_for_survey(respondent, session) oauth_response = OauthClient().update_account(username=email_address, account_locked='False') try: oauth_response.raise_for_status() except HTTPError: logger.error( "Unexpected response from auth service, unable to unlock account", respondent_id=str(respondent.party_uuid), status=oauth_response.status_code) raise InternalServerError('Failed to unlock respondent account') logger.info('Respondent account updated', respondent_id=party_id) # Lock and notify respondent of account lock elif status == 'SUSPENDED': _is_valid(payload, attribute='email_address') verification_url = PublicWebsite().reset_password_url(email_address) personalisation = { 'RESET_PASSWORD_URL': verification_url, 'FIRST_NAME': respondent.first_name } logger.info('Unlock account via password reset url', url=verification_url, party_id=party_id) try: NotifyGateway(current_app.config).request_to_notify( email=email_address, template_name='notify_account_locked', personalisation=personalisation, reference=party_id) except RasNotifyError: # Note: intentionally suppresses exception logger.error('Error sending request to Notify Gateway', respondent_id=party_id) logger.info('Notification email successfully sent', party_id=party_id) respondent.status = status return {'response': "Ok"}
def change_respondent_enrolment_status(payload, session): """ Change respondent enrolment status for respondent and survey. Takes params from a payload dict :param payload: A dictionary holding the values for the respondent party id being modified """ respondent_id = payload['respondent_id'] respondent = query_respondent_by_party_uuid(respondent_id, session) if not respondent: logger.info("Respondent does not exist", respondent_id=respondent_id) raise NotFound("Respondent does not exist") return _change_respondent_enrolment_status( respondent=respondent, survey_id=payload['survey_id'], business_id=payload['business_id'], status=payload['change_flag'], session=session)
def resend_verification_email_by_uuid(party_uuid, session): """ Check and resend an email verification email using the party id :param party_uuid: the party uuid :param session: database session :return: response """ logger.info('Attempting to resend verification email', party_uuid=party_uuid) respondent = query_respondent_by_party_uuid(party_uuid, session) if not respondent: logger.info(NO_RESPONDENT_FOR_PARTY_ID, party_uuid=party_uuid) raise NotFound(NO_RESPONDENT_FOR_PARTY_ID) response = _resend_verification_email(respondent) logger.info('Verification email successfully resent', party_uuid=party_uuid) return response
def change_respondent_details(respondent_data, respondent_id, session): """ Completely replaces current respondent details with the data provided :param respondent_data: A dict containing all the respondent details :param respondent_id: :param session: A db session :return: None on success """ respondent = query_respondent_by_party_uuid(respondent_id, session) if not respondent: logger.info("Respondent with party id does not exist", respondent_id=respondent_id) raise NotFound("Respondent id does not exist") # This function updates the name and number of a respondent update_respondent_details(respondent_data, respondent_id, session) if 'new_email_address' in respondent_data: # This function only changes the respondents email address change_respondent(respondent_data)
def get_respondent_by_id(respondent_id, session): """ Get a Respondent by its Party ID. Returns a single Party :param respondent_id: ID of Respondent to return :type respondent_id: str :return: An object representing a respondent, if it exists. :rtype: Respondent """ try: uuid.UUID(respondent_id) except ValueError: logger.info("respondent_id value is not a valid UUID", respondent_id=respondent_id) raise BadRequest( f"'{respondent_id}' is not a valid UUID format for property 'id'") respondent = query_respondent_by_party_uuid(respondent_id, session) if not respondent: logger.info("Respondent with party id does not exist", respondent_id=respondent_id) raise NotFound("Respondent with party id does not exist") return respondent.to_respondent_dict()
def _change_respondent_enrolment_status(respondent, survey_id, business_id, status, session): logger.info("Attempting to change respondent enrolment", respondent_id=respondent.party_uuid, survey_id=survey_id, business_id=business_id, status=status) respondent = query_respondent_by_party_uuid(respondent.party_uuid, session) if not respondent: logger.info("Respondent does not exist", respondent_id=respondent.party_uuid) raise NotFound("Respondent does not exist") enrolment = query_enrolment_by_survey_business_respondent( respondent_id=respondent.id, business_id=business_id, survey_id=survey_id, session=session) enrolment.status = status session.commit( ) # Needs to be committed before call to case as that may look up party # If no enrolments are remaining for business/survey # then send NO_ACTIVE_ENROLMENTS case event enrolment_count = count_enrolment_by_survey_business( business_id, survey_id, session) if not enrolment_count: logger.info("Informing case service of no active enrolments", survey_id=survey_id, business_id=business_id, respondent_id=respondent.party_uuid) post_case_event(case_id=get_case_id_for_business_survey( survey_id, business_id), category='NO_ACTIVE_ENROLMENTS', desc='No active enrolments remaining for case')
def add_new_survey_for_respondent(payload, tran, session): """ Add a survey for an existing respondent :param payload: json containing party_id and enrolment_code :param tran: :param session: database session """ logger.info("Enrolling existing respondent in survey") respondent_party_id = payload['party_id'] enrolment_code = payload['enrolment_code'] iac = request_iac(enrolment_code) if not iac.get('active'): logger.info("Inactive enrolment code") raise BadRequest("Enrolment code is not active") respondent = query_respondent_by_party_uuid(respondent_party_id, session) case_context = request_case(enrolment_code) case_id = case_context['id'] business_id = case_context['partyId'] collection_exercise_id = case_context['caseGroup']['collectionExerciseId'] collection_exercise = request_collection_exercise(collection_exercise_id) survey_id = collection_exercise['surveyId'] business_respondent = query_business_respondent_by_respondent_id_and_business_id( business_id, respondent.id, session) if not business_respondent: # Associate respondent with new business business = query_business_by_party_uuid(business_id, session) if not business: logger.error("Could not find business", business_id=business_id, case_id=case_id, collection_exercise_id=collection_exercise_id) raise InternalServerError( "Could not locate business when creating business association") business_respondent = BusinessRespondent(business=business, respondent=respondent) enrolment = Enrolment(business_respondent=business_respondent, survey_id=survey_id, status=EnrolmentStatus.ENABLED) session.add(enrolment) session.commit() disable_iac(enrolment_code, case_id) if count_enrolment_by_survey_business(survey_id, business_id, session) == 0: logger.info("Informing case of respondent enrolled", survey_id=survey_id, business_id=business_id, respondent_id=respondent.party_uuid) post_case_event(case_id=case_id, category="RESPONDENT_ENROLED", desc="Respondent enroled") # This ensures the log message is only written once the DB transaction is committed tran.on_success(lambda: logger.info( 'Respondent has enroled to survey for business', business=business_id))