Skip to content

Commit

Permalink
Move code to models and storage
Browse files Browse the repository at this point in the history
  • Loading branch information
MagdaN committed Jul 20, 2022
1 parent 3fa4293 commit b7930cb
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 87 deletions.
57 changes: 7 additions & 50 deletions legal_advice_builder/mixins.py
Expand Up @@ -9,73 +9,29 @@
from .models import Answer
from .models import Question
from .signals import answer_created
from .utils import get_answer_from_list


class GenrateFormWizardMixin:

def get_initial_dict(self):
return {}

def _get_dict_entry_for_question(self, question):
initial_dict = self.get_initial_dict()
questionaire = question.questionaire
if questionaire.short_title and question.short_title:
questionaire_dict = initial_dict.get(questionaire.short_title)
if questionaire_dict:
return questionaire_dict.get(question.short_title)

def get_initial_data(self, question):
question_data = self._get_dict_entry_for_question(question)
if question_data and 'initial' in question_data:
text_types = [question.TEXT, question.SINGLE_LINE]
single_option_types = [question.SINGLE_OPTION, question.YES_NO]
if question.field_type in text_types:
return {'text': question_data.get('initial')}
elif question.field_type in single_option_types:
return {'option': question_data.get('initial')}
elif question.field_type == question.MULTIPLE_OPTIONS:
return {'option': question_data.get('initial')}
elif question.field_type == question.DATE:
return {'date': question_data.get('initial')}

def get_initial_options(self, question):
question_data = self._get_dict_entry_for_question(question)
if question_data and 'options' in question_data:
return question_data.get('options')
return question.options

def render_next(self, question, answers, initial_data=None):
self.storage.set_data({
'current_questionaire': question.questionaire.id,
'current_question': question.id,
'answers': answers
})
initial_options = self.get_initial_options(question)
initial_dict = self.get_initial_dict()
initial_options = question.get_initial_options(initial_dict)
if not initial_data:
initial_data = self.get_initial_data(question)
initial_data = question.get_initial_data(initial_dict)
form = self.get_form(question=question,
initial_data=initial_data,
options=initial_options)
return self.render_form(form)

def get_current_question(self):
question_id = self.storage.get_data().get('current_question')
return Question.objects.get(id=question_id)

def get_answer_for_question(self, question_short_title, questionaire_short_title=None):
filters = {
'short_title': question_short_title
}
if questionaire_short_title:
filters['questionaire__short_title'] = questionaire_short_title
questions = Question.objects.filter(**filters)
questions = Question.objects.get_questions_by_short_titles(question_short_title, questionaire_short_title)
if questions:
answers = self.storage.get_data().get('answers')
question = questions.first()
answers = self.storage.get_data().get('answers')
if answers:
return get_answer_from_list(answers, question)
return self.storage.get_answer_for_questions(questions.first())
return ""

def get_form(self, question=None, data=None, initial_data=None, options=None):
Expand All @@ -94,7 +50,8 @@ def render_form(self, form=None, **kwargs):
return self.render_to_response(context)

def validate_form_and_get_next(self, question=None, answers=None, data=None):
initial_options = self.get_initial_options(question)
initial_dict = self.get_initial_dict()
initial_options = question.get_initial_options(initial_dict)
question_form = self.get_form(question=question,
data=self.request.POST,
options=initial_options)
Expand Down
58 changes: 49 additions & 9 deletions legal_advice_builder/models/question.py
@@ -1,6 +1,18 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from treebeard.mp_tree import MP_Node
from treebeard.mp_tree import MP_NodeManager


class QuestionManager(MP_NodeManager):

def get_questions_by_short_titles(self, question_short_title, questionaire_short_title):
filters = {
'short_title': question_short_title
}
if questionaire_short_title:
filters['questionaire__short_title'] = questionaire_short_title
return self.filter(**filters)


class Question(MP_Node):
Expand Down Expand Up @@ -48,13 +60,10 @@ class Question(MP_Node):
next_question = models.ForeignKey('legal_advice_builder.Question', null=True, blank=True,
on_delete=models.SET_NULL)
is_last = models.BooleanField(default=False)
objects = QuestionManager()

@property
def conditions(self):
return self.question_condition

def is_option_question(self):
return self.field_type in [self.SINGLE_OPTION, self.YES_NO, self.MULTIPLE_OPTIONS]
def __str__(self):
return self.text

def save(self, *args, **kwargs):
if self.field_type == self.YES_NO:
Expand All @@ -64,6 +73,40 @@ def save(self, *args, **kwargs):
}
super().save(*args, **kwargs)

@property
def conditions(self):
return self.question_condition

def is_option_question(self):
return self.field_type in [self.SINGLE_OPTION, self.YES_NO, self.MULTIPLE_OPTIONS]

def _get_dict_entry_for_question(self, initial_dict):
questionaire = self.questionaire
if questionaire.short_title and self.short_title:
questionaire_dict = initial_dict.get(questionaire.short_title)
if questionaire_dict:
return questionaire_dict.get(self.short_title)

def get_initial_options(self, initial_dict):
question_data = self._get_dict_entry_for_question(initial_dict)
if question_data and 'options' in question_data:
return question_data.get('options')
return self.options

def get_initial_data(self, initial_dict):
question_data = self._get_dict_entry_for_question(initial_dict)
if question_data and 'initial' in question_data:
text_types = [self.TEXT, self.SINGLE_LINE]
single_option_types = [self.SINGLE_OPTION, self.YES_NO]
if self.field_type in text_types:
return {'text': question_data.get('initial')}
elif self.field_type in single_option_types:
return {'option': question_data.get('initial')}
elif self.field_type == self.MULTIPLE_OPTIONS:
return {'option': question_data.get('initial')}
elif self.field_type == self.DATE:
return {'date': question_data.get('initial')}

def prepare_for_delete(self):
if self.is_root():
child = self.get_children().first()
Expand Down Expand Up @@ -215,6 +258,3 @@ def get_dict_key(self, option=None, text=None, date=None):
elif date:
value = date
return '{}_{}'.format(qn_key, question_key), value

def __str__(self):
return self.text
18 changes: 18 additions & 0 deletions legal_advice_builder/storage.py
Expand Up @@ -2,6 +2,9 @@

from django.core.serializers.json import DjangoJSONEncoder

from .models import Question
from .utils import get_answer_from_list


class SessionStorage:
current_questionaire = 'questionaire_id'
Expand Down Expand Up @@ -33,3 +36,18 @@ def set_data(self, value):

def reset(self):
self.init_data()

def get_answer_for_questions(self, question_id):
answers = self.get_data().get('answers')
if answers:
return get_answer_from_list(answers, question_id)
return ""

def get_current_question(self):
try:
return Question.objects.get(id=self.get_data().get('current_question'))
except Question.DoesNotExist:
return None

def has_previuos_question(self):
return not len(self.get_data().get('answers', [])) == 0
54 changes: 54 additions & 0 deletions legal_advice_builder/tests/test_wizard_views.py
@@ -1,3 +1,4 @@
import datetime
import json

import pytest
Expand Down Expand Up @@ -588,3 +589,56 @@ def get_lawcase(self):
request.session.save()
resp = TestWizardView.as_view()(request)
assert resp.context_data.get('view').storage.get_data().get('answers')[0].get('date') == '2021-10-10'


@pytest.mark.django_db
def test_form_wizard_get_answer_for_question(rf, law_case_factory, questionaire_factory):

class TestWizardView(FormWizardView):

def get_lawcase(self):
return LawCase.objects.all().first()

lc = law_case_factory()
qn = questionaire_factory(law_case=lc)
q1 = Question.add_root(**get_date_question(
questionaire=qn
))
q1.short_title = 'short'
q1.save()
date_string = '2021-10-10'
data = {'question': q1.id, 'date': date_string}
request = rf.post('/', data)
middleware = SessionMiddleware(dummy_get_response)
middleware.process_request(request)
praefix = 'legal_advice_builder_{}'.format(lc.id)
request.session[praefix] = json.dumps({
'current_question': q1.id,
'answers': []
}, cls=DjangoJSONEncoder)
request.session.save()
resp = TestWizardView.as_view()(request)
date = datetime.datetime.strptime(date_string, '%Y-%m-%d').date()
assert resp.context_data.get('view').get_answer_for_question('short') == date


@pytest.mark.django_db
def test_form_wizard_get_previous_question(rf, law_case_factory, questionaire_factory):

class TestWizardView(FormWizardView):

def get_lawcase(self):
return LawCase.objects.all().first()

lc = law_case_factory()
qn = questionaire_factory(law_case=lc)
Question.add_root(**get_date_question(
questionaire=qn
))

request = rf.get('/')
middleware = SessionMiddleware(dummy_get_response)
middleware.process_request(request)
request.session.save()
resp = TestWizardView.as_view()(request)
assert not resp.context_data.get('view').storage.has_previuos_question()
58 changes: 30 additions & 28 deletions legal_advice_builder/views.py
Expand Up @@ -5,10 +5,10 @@
from .forms import RenderedDocumentForm
from .forms import WizardForm
from .mixins import GenerateEditableDocumentMixin
from .mixins import GenerateHTMLDownloadMixin
from .mixins import GeneratePDFDownloadMixin
from .mixins import GenerateWordDownloadMixin
from .mixins import GenrateFormWizardMixin
from .mixins import GenerateHTMLDownloadMixin
from .models import Answer
from .models import Question
from .storage import SessionStorage
Expand All @@ -26,43 +26,30 @@ class FormWizardView(TemplateView,
wizard_form_class = WizardForm
document_form_class = RenderedDocumentForm

def get_lawcase(self):
raise NotImplementedError

def get_prefix(self):
return 'legal_advice_builder_{}'.format(self.get_lawcase().id)

def dispatch(self, request, *args, **kwargs):
self.prefix = self.get_prefix()
self.storage = SessionStorage(
self.prefix, request
self.get_prefix(), request
)
self.law_case = self.get_lawcase()
self.allow_download = self.law_case.allow_download
self.save_answers_enabled = self.law_case.save_answers
self.answer = None
if request.POST.get('answer_id'):
self.answer = Answer.objects.get(id=request.POST.get('answer_id'))
try:
self.answer = Answer.objects.get(id=request.POST.get('answer_id'))
except Answer.DoesNotExist:
pass
return super().dispatch(request, *args, **kwargs)

def get(self, request, *args, **kwargs):
self.storage.reset()
questionaire = self.get_lawcase().get_first_questionaire()
questionaire = self.law_case.get_first_questionaire()
question = questionaire.get_first_question()
return self.render_next(question, [])

def render_previous_question(self, answers, question):
try:
previous_question = self.storage.get_data().get('answers')[-1]
next_question = Question.objects.get(id=previous_question.get('question'))
del answers[-1]
return self.render_next(next_question, answers, initial_data=previous_question)
except IndexError:
return self.render_next(question, answers)

def post(self, *args, **kwargs):
answers = self.storage.get_data().get('answers')
question = self.get_current_question()
question = self.storage.get_current_question()
download = self.request.POST.get('download')
next_question = self.request.POST.get('next')
to_previous_question = self.request.POST.get('previous-question')
Expand Down Expand Up @@ -99,8 +86,26 @@ def post(self, *args, **kwargs):
answers=answers,
data=self.request.POST)

def get_lawcase(self):
raise NotImplementedError

def get_prefix(self):
return 'legal_advice_builder_{}'.format(self.get_lawcase().id)

def get_initial_dict(self):
return {}

def render_previous_question(self, answers, question):
try:
previous_question = self.storage.get_data().get('answers')[-1]
next_question = Question.objects.get(id=previous_question.get('question'))
del answers[-1]
return self.render_next(next_question, answers, initial_data=previous_question)
except IndexError:
return self.render_next(question, answers)

def get_progress(self):
question = self.get_current_question()
question = self.storage.get_current_question()
questions = question.questionaire.questions
question_count = questions.count()
question_ids = questions.values_list('id', flat=True)
Expand All @@ -116,24 +121,21 @@ def get_progress(self):

return question_count, answers_count, percentage

def has_previuos_question(self):
return not len(self.storage.get_data().get('answers', [])) == 0

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
qcount, acount, perc = self.get_progress()
context.update({
'allow_download': self.allow_download,
'save_answers_enabled': self.save_answers,
'law_case': self.get_lawcase(),
'question': self.get_current_question(),
'question': self.storage.get_current_question(),
'current_step': self.law_case.get_index_of_questionaire(
self.get_current_question().questionaire),
self.storage.get_current_question().questionaire),
'step_count': self.law_case.questionaire_count(),
'progess': perc,
'answer_count': acount,
'question_count': qcount,
'has_previous_question': self.has_previuos_question()
'has_previous_question': self.storage.has_previuos_question()
})
return context

Expand Down

0 comments on commit b7930cb

Please sign in to comment.