def add_logic(request, qset_id, question_id): question = Question.get(id=question_id) batch = QuestionSet.get(id=qset_id) QuestionForm = get_question_form(batch.question_model()) response = None cancel_url = '../' logic_form = LogicForm(question) question_rules_for_batch = {} # question_rules_for_batch[question] = question.rules_for_batch(batch) if request.method == "POST": logic_form = LogicForm(question, data=request.POST) if logic_form.is_valid(): logic_form.save() messages.success(request, 'Logic successfully added.') response = HttpResponseRedirect( reverse('qset_questions_page', args=(batch.pk, ))) breadcrumbs = Question.edit_breadcrumbs(qset=batch) if breadcrumbs: request.breadcrumbs(breadcrumbs) cancel_url = breadcrumbs[-1][1] context = { 'logic_form': logic_form, 'button_label': 'Save', 'question': question, 'USSD_MAX_CHARS': settings.USSD_MAX_CHARS, 'rules_for_batch': question_rules_for_batch, 'questionform': QuestionForm(batch, parent_question=question), 'modal_action': reverse('add_qset_subquestion_page', args=(batch.pk, )), 'class': 'question-form', 'batch_id': qset_id, 'batch': batch, 'cancel_url': cancel_url } return response or render(request, "set_questions/logic.html", context)
def insert(request, prev_quest_id): prev_question = Question.get(pk=prev_quest_id) batch = QuestionSet.get(pk=prev_question.qset.pk) response, context = _render_question_view( request, batch, prev_question=prev_question) context['prev_question'] = prev_question return response or render(request, 'set_questions/new.html', context)
def _remove(request, question_id): question = Question.get(pk=question_id) batch_id = question.qset.id batch = QuestionSet.get(pk=batch_id) redirect_url = reverse('qset_questions_page', args=(batch_id, )) if question.total_answers() > 0: messages.error( request, "Cannot delete question that has been answered at least once.") else: _kill_zombies(batch.zombie_questions()) if question: success_message = "Question successfully deleted." # % ("Sub question" if question.subquestion else "Question")) messages.success(request, success_message) next_question = batch.next_inline(question) previous_inline = question.connecting_flows.filter(validation__isnull=True) if previous_inline.exists() and next_question: QuestionFlow.objects.create( question=previous_inline[0].question, next_question=next_question) elif next_question: # need to delete the previous flow for the next question batch.start_question = next_question batch.save() question.connecting_flows.all().delete() question.flows.all().delete() question.delete() return HttpResponseRedirect(redirect_url)
def manage_loop(request, question_id): question = Question.get(id=question_id) batch = QuestionSet.get(pk=question.qset.pk) cancel_url = '../' existing_loop = getattr(question, 'loop_started', None) looping_form = LoopingForm(question, instance=existing_loop) if request.method == "POST": looping_form = LoopingForm( question, instance=existing_loop, data=request.POST) if looping_form.is_valid(): looping_form.save() messages.success(request, 'Loop Logic successfully added.') return HttpResponseRedirect( reverse( 'qset_questions_page', args=( batch.pk, ))) breadcrumbs = Question.edit_breadcrumbs(qset=batch) if breadcrumbs: request.breadcrumbs(breadcrumbs) cancel_url = breadcrumbs[-1][1] context = { 'loop_form': looping_form, 'button_label': 'Save', 'question': question, 'cancel_url': cancel_url} return render(request, "set_questions/loop.html", context)
def edit(request, question_id): question = Question.get(id=question_id) batch = QuestionSet.get(pk=question.qset.pk) response, context = _render_question_view( request, batch, instance=question) context['page_title '] = 'Edit Question' return response or render(request, 'set_questions/new.html', context)
def manage_loop(request, question_id): question = Question.get(id=question_id) batch = QuestionSet.get(pk=question.qset.pk) cancel_url = '../' existing_loop = getattr(question, 'loop_started', None) looping_form = LoopingForm(question, instance=existing_loop) if request.method == "POST": looping_form = LoopingForm(question, instance=existing_loop, data=request.POST) if looping_form.is_valid(): looping_form.save() messages.success(request, 'Loop Logic successfully added.') return HttpResponseRedirect( reverse('qset_questions_page', args=(batch.pk, ))) breadcrumbs = Question.edit_breadcrumbs(qset=batch) if breadcrumbs: request.breadcrumbs(breadcrumbs) cancel_url = breadcrumbs[-1][1] context = { 'loop_form': looping_form, 'button_label': 'Save', 'question': question, 'cancel_url': cancel_url } return render(request, "set_questions/loop.html", context)
def save(self, *args, **kwargs): next_question = None desc = self._make_desc() if self.cleaned_data['action'] in [ self.ASK_SUBQUESTION, self.SKIP_TO, self.BACK_TO]: next_question = Question.get(pk=self.cleaned_data['next_question']) if self.cleaned_data['action'] == self.REANSWER: next_question = self.question validation = ResponseValidation.objects.create(validation_test=self.cleaned_data['condition']) flow = QuestionFlow.objects.create(question=self.question, validation=validation, next_question=next_question, desc=desc) if self.cleaned_data['action'] == self.ASK_SUBQUESTION: # connect back to next inline question of the main QuestionFlow.objects.create( question=next_question, desc=desc, next_question=self.batch.next_inline( self.question)) if self.cleaned_data['condition'] == 'between': TextArgument.objects.create(validation=validation, position=0, param=self.cleaned_data['min_value']) TextArgument.objects.create(validation=validation, position=1, param=self.cleaned_data['max_value']) else: value = self.cleaned_data.get('value', '') if self.question.answer_type in [ MultiChoiceAnswer.choice_name(), MultiSelectAnswer.choice_name()]: value = self.cleaned_data['option'] TextArgument.objects.create(validation=validation, position=0, param=value) # clean up now, remove all zombie questions self.question.qset.zombie_questions().delete()
def _remove(request, question_id): question = Question.get(pk=question_id) batch_id = question.qset.id batch = QuestionSet.get(pk=batch_id) redirect_url = reverse('qset_questions_page', args=(batch_id, )) if question.total_answers() > 0: messages.error( request, "Cannot delete question that has been answered at least once.") else: _kill_zombies(batch.zombie_questions()) if question: success_message = "Question successfully deleted." # % ("Sub question" if question.subquestion else "Question")) messages.success(request, success_message) next_question = batch.next_inline(question) previous_inline = question.connecting_flows.filter( validation__isnull=True) if previous_inline.exists() and next_question: QuestionFlow.objects.create(question=previous_inline[0].question, next_question=next_question) elif next_question: # need to delete the previous flow for the next question batch.start_question = next_question batch.save() question.connecting_flows.all().delete() question.flows.all().delete() question.delete() return HttpResponseRedirect(redirect_url)
def edit(request, question_id): question = Question.get(id=question_id) batch = QuestionSet.get(pk=question.qset.pk) response, context = _render_question_view(request, batch, instance=question) context['page_title '] = 'Edit Question' return response or render(request, 'set_questions/new.html', context)
def insert(request, prev_quest_id): prev_question = Question.get(pk=prev_quest_id) batch = QuestionSet.get(pk=prev_question.qset.pk) response, context = _render_question_view(request, batch, prev_question=prev_question) context['prev_question'] = prev_question return response or render(request, 'set_questions/new.html', context)
def question_validators(request): values = {} if request.GET.get('id'): for question in QuestionSet.get( id=request.GET.get('id')).all_questions: values['%s' % question.id] = [ validator for validator in question.validator_names()] elif request.GET.get('ques_id'): values = Question.get(id=request.GET.get('ques_id')).validator_names() return HttpResponse(json.dumps(values), content_type='application/json')
def question_validators(request): values = {} if request.GET.get('id'): for question in QuestionSet.get( id=request.GET.get('id')).all_questions: values['%s' % question.id] = [ validator for validator in question.validator_names() ] elif request.GET.get('ques_id'): values = Question.get(id=request.GET.get('ques_id')).validator_names() return HttpResponse(json.dumps(values), content_type='application/json')
def question_options(request): values = {} if request.GET.get('id'): for question in QuestionSet.get( id=request.GET.get('id')).all_questions: values['%s' % question.id] = dict([ (opt.order, opt.text) for opt in question.options.all() ]) elif request.GET.get('ques_id'): values = dict( Question.get(id=request.GET.get('ques_id')).options.values_list( 'order', 'text')) return HttpResponse(json.dumps(values), content_type='application/json')
def question_options(request): values = {} if request.GET.get('id'): for question in QuestionSet.get( id=request.GET.get('id')).all_questions: values['%s' % question.id] = dict( [(opt.order, opt.text) for opt in question.options.all()]) elif request.GET.get('ques_id'): values = dict( Question.get( id=request.GET.get('ques_id')).options.values_list( 'order', 'text')) return HttpResponse(json.dumps(values), content_type='application/json')
def clean_next_question(self): if self.cleaned_data['action'] in [ self.ASK_SUBQUESTION, self.SKIP_TO, self.BACK_TO]: try: int(self.cleaned_data.get('next_question', '')) next_question = Question.get( pk=self.cleaned_data['next_question']) if (hasattr(self.question, 'group') and hasattr(next_question, 'group')) \ and (self.question.group != next_question.group): ValidationError( 'Assigning logic between questions of different groups is not allowed') except BaseException: raise ValidationError( 'Next question is required for Skip or Sub questions') return self.cleaned_data.get('next_question', '')
def _validate_response(self, question, answer, interview=None): if interview is None: interview = self.interview answer_count = Answer.objects.count() questions = self.qset.flow_questions interview.respond(reply=answer, answers_context={}) interview.refresh_from_db() self.assertEquals(Answer.objects.count(), answer_count+1) next_question = question.next_question(answer) # just confirm text value of this answer was saved self.assertTrue(interview.get_answer(question), str(answer)) question = Question.get(id=question.id) # next test is valid if questions.index(question) < len(questions) - 1: self.assertEquals(next_question.id, questions[questions.index(question)+1].id) self.assertEquals(next_question.id, interview.last_question.id)
def clean_next_question(self): if self.cleaned_data['action'] in [ self.ASK_SUBQUESTION, self.SKIP_TO, self.BACK_TO ]: try: int(self.cleaned_data.get('next_question', '')) next_question = Question.get( pk=self.cleaned_data['next_question']) if (hasattr(self.question, 'group') and hasattr(next_question, 'group')) \ and (self.question.group != next_question.group): ValidationError( 'Assigning logic between questions of different groups is not allowed' ) except BaseException: raise ValidationError( 'Next question is required for Skip or Sub questions') return self.cleaned_data.get('next_question', '')
def _validate_response(self, question, answer, interview=None): if interview is None: interview = self.interview answer_count = Answer.objects.count() questions = self.qset.flow_questions interview.respond(reply=answer, answers_context={}) interview.refresh_from_db() self.assertEquals(Answer.objects.count(), answer_count + 1) next_question = question.next_question(answer) # just confirm text value of this answer was saved self.assertTrue(interview.get_answer(question), str(answer)) question = Question.get(id=question.id) # next test is valid if questions.index(question) < len(questions) - 1: self.assertEquals(next_question.id, questions[questions.index(question) + 1].id) self.assertEquals(next_question.id, interview.last_question.id)
def save(self, *args, **kwargs): next_question = None desc = self._make_desc() if self.cleaned_data['action'] in [ self.ASK_SUBQUESTION, self.SKIP_TO, self.BACK_TO ]: next_question = Question.get(pk=self.cleaned_data['next_question']) if self.cleaned_data['action'] == self.REANSWER: next_question = self.question validation = ResponseValidation.objects.create( validation_test=self.cleaned_data['condition']) flow = QuestionFlow.objects.create(question=self.question, validation=validation, next_question=next_question, desc=desc) if self.cleaned_data['action'] == self.ASK_SUBQUESTION: # connect back to next inline question of the main QuestionFlow.objects.create(question=next_question, desc=desc, next_question=self.batch.next_inline( self.question)) if self.cleaned_data['condition'] == 'between': TextArgument.objects.create(validation=validation, position=0, param=self.cleaned_data['min_value']) TextArgument.objects.create(validation=validation, position=1, param=self.cleaned_data['max_value']) else: value = self.cleaned_data.get('value', '') if self.question.answer_type in [ MultiChoiceAnswer.choice_name(), MultiSelectAnswer.choice_name() ]: value = self.cleaned_data['option'] TextArgument.objects.create(validation=validation, position=0, param=value) # clean up now, remove all zombie questions self.question.qset.zombie_questions().delete()
def add_logic(request, qset_id, question_id): question = Question.get(id=question_id) batch = QuestionSet.get(id=qset_id) QuestionForm = get_question_form(batch.question_model()) response = None cancel_url = '../' logic_form = LogicForm(question) question_rules_for_batch = {} # question_rules_for_batch[question] = question.rules_for_batch(batch) if request.method == "POST": logic_form = LogicForm(question, data=request.POST) if logic_form.is_valid(): logic_form.save() messages.success(request, 'Logic successfully added.') response = HttpResponseRedirect( reverse('qset_questions_page', args=(batch.pk, ))) breadcrumbs = Question.edit_breadcrumbs(qset=batch) if breadcrumbs: request.breadcrumbs(breadcrumbs) cancel_url = breadcrumbs[-1][1] context = { 'logic_form': logic_form, 'button_label': 'Save', 'question': question, 'USSD_MAX_CHARS': settings.USSD_MAX_CHARS, 'rules_for_batch': question_rules_for_batch, 'questionform': QuestionForm( batch, parent_question=question), 'modal_action': reverse( 'add_qset_subquestion_page', args=( batch.pk, )), 'class': 'question-form', 'batch_id': qset_id, 'batch': batch, 'cancel_url': cancel_url} return response or render(request, "set_questions/logic.html", context)