201 lines
5.9 KiB
Python
201 lines
5.9 KiB
Python
"""
|
|
Survey Console UI views - Server-rendered templates for survey management
|
|
"""
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.core.paginator import Paginator
|
|
from django.db.models import Q, Prefetch
|
|
from django.shortcuts import get_object_or_404, render
|
|
|
|
from apps.organizations.models import Department, Hospital
|
|
|
|
from .models import SurveyInstance, SurveyTemplate
|
|
|
|
|
|
@login_required
|
|
def survey_instance_list(request):
|
|
"""
|
|
Survey instances list view with filters.
|
|
|
|
Features:
|
|
- Server-side pagination
|
|
- Filters (status, journey type, hospital, date range)
|
|
- Search by patient MRN
|
|
- Score display
|
|
"""
|
|
# Base queryset with optimizations
|
|
queryset = SurveyInstance.objects.select_related(
|
|
'survey_template',
|
|
'patient',
|
|
'journey_instance__journey_template',
|
|
'journey_stage_instance__stage_template'
|
|
).prefetch_related(
|
|
'responses__question'
|
|
)
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if user.is_px_admin():
|
|
pass # See all
|
|
elif user.is_hospital_admin() and user.hospital:
|
|
queryset = queryset.filter(survey_template__hospital=user.hospital)
|
|
elif user.hospital:
|
|
queryset = queryset.filter(survey_template__hospital=user.hospital)
|
|
else:
|
|
queryset = queryset.none()
|
|
|
|
# Apply filters
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
survey_type = request.GET.get('survey_type')
|
|
if survey_type:
|
|
queryset = queryset.filter(survey_template__survey_type=survey_type)
|
|
|
|
is_negative = request.GET.get('is_negative')
|
|
if is_negative == 'true':
|
|
queryset = queryset.filter(is_negative=True)
|
|
|
|
hospital_filter = request.GET.get('hospital')
|
|
if hospital_filter:
|
|
queryset = queryset.filter(survey_template__hospital_id=hospital_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(patient__mrn__icontains=search_query) |
|
|
Q(patient__first_name__icontains=search_query) |
|
|
Q(patient__last_name__icontains=search_query) |
|
|
Q(encounter_id__icontains=search_query)
|
|
)
|
|
|
|
# Date range
|
|
date_from = request.GET.get('date_from')
|
|
if date_from:
|
|
queryset = queryset.filter(sent_at__gte=date_from)
|
|
|
|
date_to = request.GET.get('date_to')
|
|
if date_to:
|
|
queryset = queryset.filter(sent_at__lte=date_to)
|
|
|
|
# Ordering
|
|
order_by = request.GET.get('order_by', '-created_at')
|
|
queryset = queryset.order_by(order_by)
|
|
|
|
# Pagination
|
|
page_size = int(request.GET.get('page_size', 25))
|
|
paginator = Paginator(queryset, page_size)
|
|
page_number = request.GET.get('page', 1)
|
|
page_obj = paginator.get_page(page_number)
|
|
|
|
# Get filter options
|
|
hospitals = Hospital.objects.filter(status='active')
|
|
if not user.is_px_admin() and user.hospital:
|
|
hospitals = hospitals.filter(id=user.hospital.id)
|
|
|
|
# Statistics
|
|
stats = {
|
|
'total': queryset.count(),
|
|
'sent': queryset.filter(status='sent').count(),
|
|
'completed': queryset.filter(status='completed').count(),
|
|
'negative': queryset.filter(is_negative=True).count(),
|
|
}
|
|
|
|
context = {
|
|
'page_obj': page_obj,
|
|
'surveys': page_obj.object_list,
|
|
'stats': stats,
|
|
'hospitals': hospitals,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'surveys/instance_list.html', context)
|
|
|
|
|
|
@login_required
|
|
def survey_instance_detail(request, pk):
|
|
"""
|
|
Survey instance detail view with responses.
|
|
|
|
Features:
|
|
- Full survey details
|
|
- All responses
|
|
- Score breakdown
|
|
- Related journey/stage info
|
|
"""
|
|
survey = get_object_or_404(
|
|
SurveyInstance.objects.select_related(
|
|
'survey_template',
|
|
'patient',
|
|
'journey_instance__journey_template',
|
|
'journey_stage_instance__stage_template'
|
|
).prefetch_related(
|
|
'responses__question'
|
|
),
|
|
pk=pk
|
|
)
|
|
|
|
# Get responses
|
|
responses = survey.responses.all().order_by('question__order')
|
|
|
|
context = {
|
|
'survey': survey,
|
|
'responses': responses,
|
|
}
|
|
|
|
return render(request, 'surveys/instance_detail.html', context)
|
|
|
|
|
|
@login_required
|
|
def survey_template_list(request):
|
|
"""Survey templates list view"""
|
|
queryset = SurveyTemplate.objects.select_related('hospital').prefetch_related('questions')
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if user.is_px_admin():
|
|
pass
|
|
elif user.hospital:
|
|
queryset = queryset.filter(hospital=user.hospital)
|
|
else:
|
|
queryset = queryset.none()
|
|
|
|
# Apply filters
|
|
survey_type = request.GET.get('survey_type')
|
|
if survey_type:
|
|
queryset = queryset.filter(survey_type=survey_type)
|
|
|
|
hospital_filter = request.GET.get('hospital')
|
|
if hospital_filter:
|
|
queryset = queryset.filter(hospital_id=hospital_filter)
|
|
|
|
is_active = request.GET.get('is_active')
|
|
if is_active == 'true':
|
|
queryset = queryset.filter(is_active=True)
|
|
elif is_active == 'false':
|
|
queryset = queryset.filter(is_active=False)
|
|
|
|
# Ordering
|
|
queryset = queryset.order_by('hospital', 'survey_type', 'name')
|
|
|
|
# Pagination
|
|
page_size = int(request.GET.get('page_size', 25))
|
|
paginator = Paginator(queryset, page_size)
|
|
page_number = request.GET.get('page', 1)
|
|
page_obj = paginator.get_page(page_number)
|
|
|
|
# Get filter options
|
|
hospitals = Hospital.objects.filter(status='active')
|
|
if not user.is_px_admin() and user.hospital:
|
|
hospitals = hospitals.filter(id=user.hospital.id)
|
|
|
|
context = {
|
|
'page_obj': page_obj,
|
|
'templates': page_obj.object_list,
|
|
'hospitals': hospitals,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'surveys/template_list.html', context)
|