def validate_all_answers(self): answers = get_answers(current_user) for location in self.navigator.get_location_path(answers): is_valid = self.validate(location, get_answers(current_user)) if not is_valid: logger.debug("Failed validation with current location %s", location) return False, location return True, None
def get_summary(eq_id, form_type, period_id, collection_id): navigator = g.questionnaire_manager.navigator latest_location = navigator.get_latest_location(get_answers(current_user), get_completed_blocks(current_user)) if latest_location is 'summary': return render_page('summary', True) return redirect_to_questionnaire_page(eq_id, form_type, period_id, collection_id, latest_location)
def post_questionnaire(eq_id, form_type, period_id, collection_id, location): valid = g.questionnaire_manager.process_incoming_answers(location, request.form) if not valid: return render_page(location, False) navigator = g.questionnaire_manager.navigator next_location = navigator.get_next_location(get_answers(current_user), location) metadata = get_metadata(current_user) logger.info("Redirecting user to next location %s with tx_id=%s", next_location, metadata["tx_id"]) return redirect_to_questionnaire_page(eq_id, form_type, period_id, collection_id, next_location)
def _build_summary(questionnaire_schema): q_manager = g.questionnaire_manager answers = get_answers(current_user) path = q_manager.navigator.get_routing_path(answers) sections = [] for group in questionnaire_schema['groups']: for block in group['blocks']: if block['id'] in path: sections.extend([Section(block['id'], section, answers) for section in block['sections']]) return sections
def submit_answers(eq_id, form_type, period_id, collection_id): answers = get_answers(current_user) # check that all the answers we have are valid before submitting the data is_valid, invalid_location = g.questionnaire_manager.validate_all_answers() if is_valid: submitter = SubmitterFactory.get_submitter() submitter.send_answers(get_metadata(current_user), g.questionnaire_manager.get_schema(), answers) return redirect_to_questionnaire_page(eq_id, form_type, period_id, collection_id, 'thank-you') else: return redirect_to_questionnaire_page(eq_id, form_type, period_id, collection_id, invalid_location)
def validate_all_answers(self): navigator = PathFinder(self._json, get_answer_store(current_user), get_metadata(current_user)) for location in navigator.get_location_path(): answers = get_answers(current_user) is_valid = self.validate(location, answers) if not is_valid: logger.debug("Failed validation with current location %s", str(location)) return False, location return True, None
def _build_answers(questionnaire_manager, schema): """ Get the answer values for all aliased elements and make them available for piping. Where answers are not available, use an empty string """ aliases = schema.aliases values = {} for alias, item_id in aliases.items(): value = get_answers(current_user).get(item_id) if value is None: value = "" # Empty string values[alias] = value return values
def get_rendering_context(self, location, is_valid=True): if is_valid: if location == 'summary': return self.get_summary_rendering_context() else: # apply page answers? self.build_state(location, get_answers(current_user)) if self.state: self._plumbing_preprocessing() self._conditional_display(self.state) # look up the preprocessor and then build the view data return build_questionnaire_model(self._json, self.state)
def build_block_state(self, location, answers): # Build the state from the answers self.block_state = None if self._schema.item_exists(location.block_id): metadata = get_metadata(current_user) block = self._schema.get_item_by_id(location.block_id) if not isinstance(block, Block): raise QuestionnaireException self.block_state = block.construct_state() for answer in self.get_state_answers(location.block_id): answer.group_id = location.group_id answer.group_instance = location.group_instance self.block_state.update_state(answers) self.block_state.set_skipped(get_answers(current_user), metadata)
def _conditional_display(self, item): # Process any conditional display rules if item.schema_item: item.skipped = False if hasattr(item.schema_item, 'skip_condition') and item.schema_item.skip_condition: rule = item.schema_item.skip_condition.__dict__ rule['when'] = rule['when'].__dict__ answer = get_answers(current_user).get(rule['when']['id']) item.skipped = evaluate_rule(rule, answer) for child in item.children: self._conditional_display(child)
def validate(self, location, post_data): answers = get_answers(current_user) if location in self.navigator.get_location_path(answers): self.build_state(location, post_data) if self.state: self._conditional_display(self.state) is_valid = self.state.schema_item.validate(self.state) # Todo, this doesn't feel right, validation is casting the user values to their type. return is_valid else: # Item has node, but is not in schema: must be introduction, thank you or summary return True else: # Not a validation location, so can't be valid return False
def login(): """ Initial url processing - expects a token parameter and then will authenticate this token. Once authenticated it will be placed in the users session :return: a 302 redirect to the next location for the user """ # logging in again clears any session state if session: session.clear() authenticator = Authenticator() logger.debug("Attempting token authentication") authenticator.jwt_login(request) logger.debug("Token authenticated - linking to session") metadata = get_metadata(current_user) eq_id = metadata["eq_id"] collection_id = metadata["collection_exercise_sid"] form_type = metadata["form_type"] period_id = metadata["period_id"] logger.debug("Requested questionnaire %s for form type %s", eq_id, form_type) if not eq_id or not form_type: logger.error("Missing EQ id %s or form type %s in JWT", eq_id, form_type) raise NotFound json, schema = get_schema() questionnaire_manager = QuestionnaireManager(schema, json=json) navigator = questionnaire_manager.navigator current_location = navigator.get_latest_location(get_answers(current_user), get_completed_blocks(current_user)) return redirect('/questionnaire/' + eq_id + '/' + form_type + '/' + period_id + '/' + collection_id + '/' + current_location)
def render_page(location, is_valid): context = g.questionnaire_manager.get_rendering_context(location, is_valid) template = TemplateRegistry.get_template_name(location) navigator = g.questionnaire_manager.navigator previous_location = navigator.get_previous_location(get_answers(current_user), location) return render_template(template, context, previous_location)