233 lines
6.9 KiB
Python
233 lines
6.9 KiB
Python
"""
|
|
Journey Console UI views - Server-rendered templates for journey monitoring
|
|
"""
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.core.paginator import Paginator
|
|
from django.db.models import Q, Count, Prefetch
|
|
from django.shortcuts import get_object_or_404, render
|
|
from django.utils import timezone
|
|
|
|
from apps.organizations.models import Department, Hospital
|
|
|
|
from .models import (
|
|
PatientJourneyInstance,
|
|
PatientJourneyStageInstance,
|
|
PatientJourneyTemplate,
|
|
StageStatus,
|
|
)
|
|
|
|
|
|
@login_required
|
|
def journey_instance_list(request):
|
|
"""
|
|
Journey instances list view with filters.
|
|
|
|
Features:
|
|
- Server-side pagination
|
|
- Filters (journey type, status, hospital, department, date range)
|
|
- Search by encounter ID, patient MRN
|
|
- Completion percentage display
|
|
"""
|
|
# Base queryset with optimizations
|
|
queryset = PatientJourneyInstance.objects.select_related(
|
|
'journey_template',
|
|
'patient',
|
|
'hospital',
|
|
'department'
|
|
).prefetch_related(
|
|
'stage_instances__stage_template',
|
|
'stage_instances__staff',
|
|
'stage_instances__survey_instance'
|
|
)
|
|
|
|
# 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(hospital=user.hospital)
|
|
elif user.is_department_manager() and user.department:
|
|
queryset = queryset.filter(department=user.department)
|
|
elif user.hospital:
|
|
queryset = queryset.filter(hospital=user.hospital)
|
|
else:
|
|
queryset = queryset.none()
|
|
|
|
# Apply filters
|
|
journey_type = request.GET.get('journey_type')
|
|
if journey_type:
|
|
queryset = queryset.filter(journey_template__journey_type=journey_type)
|
|
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
hospital_filter = request.GET.get('hospital')
|
|
if hospital_filter:
|
|
queryset = queryset.filter(hospital_id=hospital_filter)
|
|
|
|
department_filter = request.GET.get('department')
|
|
if department_filter:
|
|
queryset = queryset.filter(department_id=department_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(encounter_id__icontains=search_query) |
|
|
Q(patient__mrn__icontains=search_query) |
|
|
Q(patient__first_name__icontains=search_query) |
|
|
Q(patient__last_name__icontains=search_query)
|
|
)
|
|
|
|
# Date range
|
|
date_from = request.GET.get('date_from')
|
|
if date_from:
|
|
queryset = queryset.filter(started_at__gte=date_from)
|
|
|
|
date_to = request.GET.get('date_to')
|
|
if date_to:
|
|
queryset = queryset.filter(started_at__lte=date_to)
|
|
|
|
# Ordering
|
|
order_by = request.GET.get('order_by', '-started_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)
|
|
|
|
departments = Department.objects.filter(status='active')
|
|
if not user.is_px_admin() and user.hospital:
|
|
departments = departments.filter(hospital=user.hospital)
|
|
|
|
# Statistics
|
|
stats = {
|
|
'total': queryset.count(),
|
|
'active': queryset.filter(status='active').count(),
|
|
'completed': queryset.filter(status='completed').count(),
|
|
}
|
|
|
|
context = {
|
|
'page_obj': page_obj,
|
|
'journeys': page_obj.object_list,
|
|
'stats': stats,
|
|
'hospitals': hospitals,
|
|
'departments': departments,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'journeys/instance_list.html', context)
|
|
|
|
|
|
@login_required
|
|
def journey_instance_detail(request, pk):
|
|
"""
|
|
Journey instance detail view with stage progress.
|
|
|
|
Features:
|
|
- Stage progress stepper
|
|
- Each stage shows status, timestamp, physician, survey
|
|
- Event history timeline
|
|
- Completion percentage
|
|
"""
|
|
journey = get_object_or_404(
|
|
PatientJourneyInstance.objects.select_related(
|
|
'journey_template',
|
|
'patient',
|
|
'hospital',
|
|
'department'
|
|
).prefetch_related(
|
|
'stage_instances__stage_template',
|
|
'stage_instances__staff',
|
|
'stage_instances__department',
|
|
'stage_instances__survey_instance',
|
|
'stage_instances__completed_by_event'
|
|
),
|
|
pk=pk
|
|
)
|
|
|
|
# Get stages in order
|
|
stages = journey.stage_instances.all().order_by('stage_template__order')
|
|
|
|
# Get completion percentage
|
|
completion_percentage = journey.get_completion_percentage()
|
|
|
|
context = {
|
|
'journey': journey,
|
|
'stages': stages,
|
|
'completion_percentage': completion_percentage,
|
|
}
|
|
|
|
return render(request, 'journeys/instance_detail.html', context)
|
|
|
|
|
|
@login_required
|
|
def journey_template_list(request):
|
|
"""
|
|
Journey templates list view.
|
|
|
|
Simple list of templates with basic info.
|
|
Template builder is complex and can be added later.
|
|
"""
|
|
# Base queryset
|
|
queryset = PatientJourneyTemplate.objects.select_related(
|
|
'hospital'
|
|
).prefetch_related(
|
|
'stages'
|
|
)
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if user.is_px_admin():
|
|
pass # See all
|
|
elif user.hospital:
|
|
queryset = queryset.filter(hospital=user.hospital)
|
|
else:
|
|
queryset = queryset.none()
|
|
|
|
# Apply filters
|
|
journey_type = request.GET.get('journey_type')
|
|
if journey_type:
|
|
queryset = queryset.filter(journey_type=journey_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', 'journey_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, 'journeys/template_list.html', context)
|