HH/apps/journeys/ui_views.py
Marwan Alwali 867f60fed7 update
2026-01-08 20:56:18 +03:00

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)