HH/apps/surveys/ui_views.py
2025-12-24 12:42:31 +03:00

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)