Source code for apps.questionnaire.views

# -*- coding: utf-8 -*-
"""
This module contains the views for displaying filled in
questionnaires and the start and finish questionnaire views.

The questionnaire fillin process is handled by the
:class:`apps.questionnaire.wizards.QuestionnaireWizard` view.

:subtitle:`Class and function definitions:`
"""
from datetime import date
from dateutil.relativedelta import relativedelta
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404

from apps.healthperson.patient.models import Patient
from apps.questionnaire.models import QuestionnaireRequest,\
    AVAILABLE_URGENT_QUESTIONNAIRE_LIST, RequestStep,\
    AVAILABLE_CONTROL_QUESTIONNAIRE_LIST
from apps.questionnaire.qohc.models import QOHCQuestionnaire
from django.views.generic.base import TemplateView, View
from django.utils.decorators import method_decorator


# ## ADD QUESTIONNAIRE REQUEST ####
[docs]def insert_new_questionnaire_request_for_patient(patient): """ Adds a new questionnaire request for a patient including the requeststeps Args: - patient: the patient to add the questionnaire_request for Returns: The created questionnaire_request """ questionnaire_list = None for l in AVAILABLE_CONTROL_QUESTIONNAIRE_LIST: if l[0] == patient.diagnose: questionnaire_list = l[1] # questionnaire_list questionnaire_request = QuestionnaireRequest(patient=patient) questionnaire_request.deadline = date.today() + relativedelta(weeks=+1) questionnaire_request.deadline_nr = 1 questionnaire_request.patient_diagnose = patient.diagnose questionnaire_request.practitioner = patient.current_practitioner # Added for auditing questionnaire_request.changed_by_user = patient.user questionnaire_request.save() # add steps of request. # Check if we need to add the QOHC questionnaire (=only asked once a year) do_add_QOHC = True try: QOHC_questionnaire = QOHCQuestionnaire.objects.filter( request_step__questionnairerequest__patient=patient).latest( 'request_step__questionnairerequest__finished_on') except QOHCQuestionnaire.DoesNotExist: QOHC_questionnaire = None # QOHC needs to be filled in once a year, # check if a year has passed since the last one. if QOHC_questionnaire: if (((QOHC_questionnaire.finished_on + relativedelta(years=+1)) > date.today())): do_add_QOHC = False # add steps of request # if not in exclude_questionnaires list.. step = 1 for questionnaire in questionnaire_list: do_add = True if questionnaire == 'QOHCQuestionnaire': do_add = do_add_QOHC elif patient.excluded_questionnaires: if questionnaire in patient.excluded_questionnaires: do_add = False if do_add: questionnaire_request_step = RequestStep() questionnaire_request_step.questionnairerequest =\ questionnaire_request questionnaire_request_step.step_nr = step questionnaire_request_step.model = questionnaire step = step + 1 questionnaire_request_step.save() return questionnaire_request
[docs]class PatientView(View): """Basic patient view which checks if the user has logged in and automatically sets the patient on the view""" @method_decorator(login_required) def dispatch(self, *args, **kwargs): self.set_patient(**kwargs) return super(PatientView, self).dispatch(*args, **kwargs)
[docs] def set_patient(self, **kwargs): """ Sets the patient on the view """ self.patient_session_id = kwargs.get('patient_session_id', None) # TODO: generate a custom error if self.patient_session_id not in self.request.session: raise Http404 healthperson_ptr_id = self.request.session[self.patient_session_id][8:] self.patient = get_object_or_404( Patient, healthperson_ptr_id=healthperson_ptr_id)
[docs]class PatientTemplateView(PatientView, TemplateView): """ Templateview baseclass view """ pass
[docs]class PatientQuestionnaireTemplateView(PatientView, TemplateView): """ Base view for all questionnaire views that use templateview. Sets the questionnaire_request on the view """ def get_context_data(self, **kwargs): context = super( PatientQuestionnaireTemplateView, self).get_context_data(**kwargs) questionnaire_request_id = kwargs.get('questionnaire_request_id', None) self.questionnaire_request = get_object_or_404( QuestionnaireRequest, id=questionnaire_request_id) return context
[docs]class BaseOverviewTemplateView(PatientTemplateView): """ Base view for overview views that show the details pages for filled in questionnaires Automatically adds the context. """
[docs] def get_questionnaires_for(self, selected_model_class, selected_questionnaire_request): """ Retrieve the questionnaires coupled to the selected_questionnaire_request for the selected_model_class Args: - selected_model_class: the model_class to find the questionnaire\ for - selected_questionnaire_request: the questionnaire_request which\ should be coupled to the questionnaires. Returns: [The selected questionnaire, list of questionnaires] """ # get the selected one based on the questionnaire_step qr_selected = selected_questionnaire_request select_disease_activity_questionnare =\ selected_model_class.objects.get( request_step__questionnairerequest=qr_selected) # Get all disease_activity_questionnares =\ selected_model_class.objects.filter( request_step__questionnairerequest__patient=self.patient, request_step__questionnairerequest__finished_on__isnull=False) return [select_disease_activity_questionnare, disease_activity_questionnares]
[docs] def get_context(self): """ Creates the context based on the questionnaire request and model_display_name adding various information. Returns: The context dict """ questionnaire_requests = QuestionnaireRequest.objects.filter( patient=self.patient, finished_on__isnull=False).order_by('-finished_on') # default if 'qr' in self.request.GET: try: selected_questionnaire_request =\ QuestionnaireRequest.objects.get( patient=self.patient, finished_on__isnull=False, id=int(self.request.GET['qr'])) except QuestionnaireRequest.DoesNotExist: selected_questionnaire_request = None else: if questionnaire_requests.count() > 0: selected_questionnaire_request = questionnaire_requests[0] else: selected_questionnaire_request = None # Get the 'model_display_name' questionnaires and set the # selected one.. select_disease_activity_questionnare = None disease_activity_questionnares = [] selected_model_class = None if selected_questionnaire_request: questionnaire_all_steps =\ selected_questionnaire_request.requeststep_set.all().order_by( 'step_nr') selected_model_class = None # Loop through the steps to find the questionnaire that # matches with 'model_display_name' for questionnaire_step in questionnaire_all_steps: questionnaire_model_class = questionnaire_step.model_class if ((questionnaire_model_class.display_name == self.model_display_name)): selected_model_class = questionnaire_model_class # Get the selected questionnaire based on the selected_model_class # And the list of questionnaires for the plot of the values if selected_model_class: # get the selected one based on the questionnaire_step [select_disease_activity_questionnare, disease_activity_questionnares] = self.get_questionnaires_for( selected_model_class, selected_questionnaire_request) return {'patient': self.patient, 'questionnaire_requests': questionnaire_requests, 'selected_questionnaire_request': selected_questionnaire_request, 'select_disease_activity_questionnaire': select_disease_activity_questionnare, 'disease_activity_questionnaires': disease_activity_questionnares, 'models1': selected_model_class}
def get_context_data(self, **kwargs): context = super(BaseOverviewTemplateView, self).get_context_data(**kwargs) context.update(self.get_context()) return context
[docs]class DiseaseActivityOverview(BaseOverviewTemplateView): """Shows the disease activity overview page""" template_name = 'questionnaire/disease_activity.html' model_display_name = 'Ziekteactiviteit'
[docs]class QualityOfLifeOverview(BaseOverviewTemplateView): """Shows the quality of life overview page""" template_name = 'questionnaire/quality_of_life.html' model_display_name = 'Kwaliteit van leven'
[docs]class HealthcareQualityOverview(BaseOverviewTemplateView): """Shows the healthcare quality overview page""" template_name = 'questionnaire/healthcare_quality.html' model_display_name = 'Kwaliteit van zorg'
[docs]class QuestionnaireStartControle(PatientView): """ Start page for normal (non urgent) controls. The view checks if there is a partially filled in control and let's the user finish it or redirects the user to the first step of the questionnaires fillin procedure. """ def post(self, request, *args, **kwargs): self.set_patient(**kwargs) unfinished_questionnaire_requests =\ QuestionnaireRequest.objects.filter( patient=self.patient, urgent=False, finished_on__isnull=True) unfinished_questionnaire_requests[0].delete() return HttpResponseRedirect(reverse('index')) def get(self, request, *args, **kwargs): self.set_patient(**kwargs) unfinished_questionnaire_requests =\ QuestionnaireRequest.objects.filter( patient=self.patient, urgent=False, finished_on__isnull=True) add_new_questionnaire = False if len(unfinished_questionnaire_requests) > 1: # remove all unfinished_questionnaire_requests.delete() add_new_questionnaire = True elif len(unfinished_questionnaire_requests) == 1: # Check if unfinished questionnare is still # the correct one for the diagnose, # else remove it. if ((unfinished_questionnaire_requests[0].patient_diagnose != self.patient.diagnose)): unfinished_questionnaire_requests[0].delete() add_new_questionnaire = True elif unfinished_questionnaire_requests[0].saved_finish_later: questionnaire_request = unfinished_questionnaire_requests[0] fill_in_url = reverse( 'questionnaire_fillin', args=[self.patient_session_id, questionnaire_request.id]) if questionnaire_request.last_filled_in_form_step: # add extra parameters for start position step =\ int(questionnaire_request.last_filled_in_form_step) + 1 fill_in_url = "%s?step=%s" % (fill_in_url, step) context = {'fill_in_url': fill_in_url} return render_to_response( 'questionnaire/already_filled_in.html', context) else: # check if it is already time to fill in the controle.. if self.patient.next_questionnaire_date: if self.patient.next_questionnaire_date > date.today(): # Not fill in now.. context = {'patient': self.patient} return render_to_response( 'questionnaire/wait_till_next_questionnaire.html', context) add_new_questionnaire = True if add_new_questionnaire: questionnaire_request =\ insert_new_questionnaire_request_for_patient(self.patient) else: questionnaire_request = unfinished_questionnaire_requests[0] # if questionnaire_request.wizarddatabasestorage_set.count() > 0: # print('SAVED DATA!! please check') # #import ipdb; ipdb.set_trace() return HttpResponseRedirect( reverse( 'questionnaire_fillin', args=[self.patient_session_id, questionnaire_request.id]))
[docs]class QuestionnaireStartUrgent(PatientView): """ Start page for urgen controls. The view checks if there is a partially filled in control and let's the user finish it or redirects the user to the first step of the questionnaires fillin procedure. """ def post(self, request, *args, **kwargs): unfinished_urgent_questionnaire_requests =\ QuestionnaireRequest.objects.filter(patient=self.patient, finished_on__isnull=True, urgent=True) unfinished_urgent_questionnaire_requests[0].delete() return HttpResponseRedirect(reverse('index')) def get(self, request, *args, **kwargs): unfinished_urgent_questionnaire_requests =\ QuestionnaireRequest.objects.filter(patient=self.patient, finished_on__isnull=True, urgent=True) # check if saved to complete later on, if so redirect if len(unfinished_urgent_questionnaire_requests) > 1: # remove all unfinished_urgent_questionnaire_requests.delete() add_new_questionnaire = True elif len(unfinished_urgent_questionnaire_requests) == 1: # Check if unfinished questionnare is still # the correct one for the diagnose, # else remove it. if ((unfinished_urgent_questionnaire_requests[0]. patient_diagnose != self.patient.diagnose)): unfinished_urgent_questionnaire_requests[0].delete() add_new_questionnaire = True elif ((unfinished_urgent_questionnaire_requests[0]. saved_finish_later)): questionnaire_request =\ unfinished_urgent_questionnaire_requests[0] fill_in_url = reverse( 'questionnaire_fillin', args=[self.patient_session_id, questionnaire_request.id]) if questionnaire_request.last_filled_in_form_step: # add extra parameters for start position step =\ int(questionnaire_request.last_filled_in_form_step) + 1 fill_in_url = "%s?step=%s" % (fill_in_url, step) context = {'fill_in_url': fill_in_url, 'urgent': True} return render_to_response( 'questionnaire/already_filled_in.html', context) else: # else remove unfinished_urgent_questionnaire_requests[0].delete() add_new_questionnaire = True else: add_new_questionnaire = True # Check if not an unhandled request.. unhandled_urgent_questionnaire_requests =\ QuestionnaireRequest.objects.filter(patient=self.patient, finished_on__isnull=False, handled_on__isnull=True, urgent=True) if len(unhandled_urgent_questionnaire_requests) > 0: context = {'urgent': True} return render_to_response( 'questionnaire/unhandled_urgent.html', context) if add_new_questionnaire: # Should now be redirected or previous one is removed. # add new request with the correct steps included. questionnaire_list = None for item in AVAILABLE_URGENT_QUESTIONNAIRE_LIST: if item[0] == self.patient.diagnose: questionnaire_list = item[1] # add questionnaire_request questionnaire_request = QuestionnaireRequest(patient=self.patient) questionnaire_request.urgent = True # already set to true so this does not need to be # set after the questionnaire has finished. questionnaire_request.appointment_needed = True questionnaire_request.patient_diagnose = self.patient.diagnose questionnaire_request.practitioner =\ self.patient.current_practitioner questionnaire_request.changed_by_user = self.request.user questionnaire_request.save() # add steps for this questionnaire request. step_nr = 1 for questionnaire in questionnaire_list: request_step = RequestStep() request_step.questionnairerequest = questionnaire_request request_step.step_nr = step_nr request_step.model = questionnaire request_step.save() step_nr = step_nr + 1 # redirect to the fillin page return HttpResponseRedirect( reverse( 'questionnaire_fillin', args=[self.patient_session_id, questionnaire_request.id]))
[docs]class QuestionnaireFinishedView(PatientQuestionnaireTemplateView): """ Shows a succesfully finished all questionnaires view. Is both used for urgent and non urgent controls. """ template_name = 'questionnaire/finish.html' def get_context_data(self, **kwargs): context = super( QuestionnaireFinishedView, self).get_context_data(**kwargs) # Get the current questionnaire step questionnaire_all_steps =\ self.questionnaire_request.requeststep_set.all().order_by( 'step_nr') # add all questionnaire step names, which are used # for displaying the menu(list) on the left questionnaire_step_names = [] for questionnaire_step in questionnaire_all_steps: questionnaire_step_names.append( questionnaire_step.model_class.display_name ) questionnaire_step_names.append('Afsluiting') context.update({ 'is_next_step': False, 'previous_step_url': None, 'patient': self.patient, 'questionnaire_request': self.questionnaire_request, 'current_step_name': 'Afsluiting', 'questionnaire_step_names': questionnaire_step_names, 'startquestionnaire': None}) return context
[docs]class QuestionnaireRequestRemove(PatientView): """ View which allows to remove a questionnaire request. Used when canceling the control. """ def dispatch(self, *args, **kwargs): questionnaire_request_id = kwargs.get( 'questionnaire_request_id', None) self.questionnaire_request = get_object_or_404( QuestionnaireRequest, id=questionnaire_request_id) return super( QuestionnaireRequestRemove, self).dispatch(*args, **kwargs) def post(self, request, *args, **kwargs): self.questionnaire_request.delete() return HttpResponse('succes')