agdar/documents/views.py
2025-11-02 14:35:35 +03:00

325 lines
10 KiB
Python

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.utils.translation import gettext_lazy as _
from django.core.paginator import Paginator
from django.db.models import Q
from django.utils import timezone
from .models import DocumentTemplate, ClinicalNote, NoteAddendum, NoteAuditLog
from .forms import DocumentTemplateForm, ClinicalNoteForm, NoteAddendumForm, NoteSearchForm
# Template Views
@login_required
def template_list(request):
"""List all document templates."""
templates = DocumentTemplate.objects.all()
# Filter by category if provided
category = request.GET.get('category')
if category:
templates = templates.filter(category=category)
# Filter by active status
is_active = request.GET.get('is_active')
if is_active:
templates = templates.filter(is_active=is_active == 'true')
paginator = Paginator(templates, 20)
page_number = request.GET.get('page')
templates = paginator.get_page(page_number)
context = {
'templates': templates,
'categories': DocumentTemplate.CATEGORY_CHOICES,
}
return render(request, 'documents/template_list.html', context)
@login_required
def template_detail(request, pk):
"""View template details."""
template = get_object_or_404(DocumentTemplate, pk=pk)
context = {
'template': template,
}
return render(request, 'documents/template_detail.html', context)
@login_required
def template_create(request):
"""Create a new document template."""
if request.method == 'POST':
form = DocumentTemplateForm(request.POST)
if form.is_valid():
template = form.save(commit=False)
template.created_by = request.user
template.save()
messages.success(request, _('Template created successfully.'))
return redirect('documents:template-detail', pk=template.pk)
else:
form = DocumentTemplateForm()
context = {
'form': form,
'title': _('Create Template'),
}
return render(request, 'documents/template_form.html', context)
@login_required
def template_update(request, pk):
"""Update an existing document template."""
template = get_object_or_404(DocumentTemplate, pk=pk)
if request.method == 'POST':
form = DocumentTemplateForm(request.POST, instance=template)
if form.is_valid():
form.save()
messages.success(request, _('Template updated successfully.'))
return redirect('documents:template-detail', pk=template.pk)
else:
form = DocumentTemplateForm(instance=template)
context = {
'form': form,
'template': template,
'title': _('Update Template'),
}
return render(request, 'documents/template_form.html', context)
@login_required
def template_delete(request, pk):
"""Delete a document template."""
template = get_object_or_404(DocumentTemplate, pk=pk)
if request.method == 'POST':
template.delete()
messages.success(request, _('Template deleted successfully.'))
return redirect('documents:template-list')
context = {
'template': template,
}
return render(request, 'documents/template_confirm_delete.html', context)
# Clinical Note Views
@login_required
def note_list(request):
"""List all clinical notes with search and filtering."""
notes = ClinicalNote.objects.select_related('patient', 'author', 'template')
# Apply search form filters
form = NoteSearchForm(request.GET)
if form.is_valid():
if form.cleaned_data.get('patient'):
patient_query = form.cleaned_data['patient']
notes = notes.filter(
Q(patient__first_name__icontains=patient_query) |
Q(patient__last_name__icontains=patient_query) |
Q(patient__patient_id__icontains=patient_query)
)
if form.cleaned_data.get('status'):
notes = notes.filter(status=form.cleaned_data['status'])
if form.cleaned_data.get('date_from'):
notes = notes.filter(created_at__gte=form.cleaned_data['date_from'])
if form.cleaned_data.get('date_to'):
notes = notes.filter(created_at__lte=form.cleaned_data['date_to'])
if form.cleaned_data.get('author'):
author_query = form.cleaned_data['author']
notes = notes.filter(
Q(author__first_name__icontains=author_query) |
Q(author__last_name__icontains=author_query)
)
paginator = Paginator(notes, 20)
page_number = request.GET.get('page')
notes = paginator.get_page(page_number)
context = {
'notes': notes,
'search_form': form,
}
return render(request, 'documents/note_list.html', context)
@login_required
def note_detail(request, pk):
"""View clinical note details."""
note = get_object_or_404(
ClinicalNote.objects.select_related('patient', 'author', 'template', 'finalized_by'),
pk=pk
)
# Log the view action
NoteAuditLog.objects.create(
note=note,
action='viewed',
user=request.user,
ip_address=request.META.get('REMOTE_ADDR')
)
addendums = note.addendums.select_related('author').all()
context = {
'note': note,
'addendums': addendums,
}
return render(request, 'documents/note_detail.html', context)
@login_required
def note_create(request):
"""Create a new clinical note."""
if request.method == 'POST':
form = ClinicalNoteForm(request.POST, user=request.user)
if form.is_valid():
note = form.save()
# Log the creation
NoteAuditLog.objects.create(
note=note,
action='created',
user=request.user,
ip_address=request.META.get('REMOTE_ADDR')
)
messages.success(request, _('Clinical note created successfully.'))
return redirect('documents:note-detail', pk=note.pk)
else:
form = ClinicalNoteForm(user=request.user)
context = {
'form': form,
'title': _('Create Clinical Note'),
}
return render(request, 'documents/note_form.html', context)
@login_required
def note_update(request, pk):
"""Update an existing clinical note."""
note = get_object_or_404(ClinicalNote, pk=pk)
# Only allow editing of draft notes
if note.status != 'draft':
messages.error(request, _('Only draft notes can be edited. Use addendum for finalized notes.'))
return redirect('documents:note-detail', pk=note.pk)
if request.method == 'POST':
form = ClinicalNoteForm(request.POST, instance=note, user=request.user)
if form.is_valid():
old_content = note.content
note = form.save()
# Log the update
NoteAuditLog.objects.create(
note=note,
action='updated',
user=request.user,
ip_address=request.META.get('REMOTE_ADDR'),
changes={'old_content': old_content, 'new_content': note.content}
)
messages.success(request, _('Clinical note updated successfully.'))
return redirect('documents:note-detail', pk=note.pk)
else:
form = ClinicalNoteForm(instance=note, user=request.user)
context = {
'form': form,
'note': note,
'title': _('Update Clinical Note'),
}
return render(request, 'documents/note_form.html', context)
@login_required
def note_finalize(request, pk):
"""Finalize a clinical note."""
note = get_object_or_404(ClinicalNote, pk=pk)
if note.status != 'draft':
messages.error(request, _('Only draft notes can be finalized.'))
return redirect('documents:note-detail', pk=note.pk)
if request.method == 'POST':
note.status = 'final'
note.finalized_at = timezone.now()
note.finalized_by = request.user
note.save()
# Log the finalization
NoteAuditLog.objects.create(
note=note,
action='finalized',
user=request.user,
ip_address=request.META.get('REMOTE_ADDR')
)
messages.success(request, _('Clinical note finalized successfully.'))
return redirect('documents:note-detail', pk=note.pk)
context = {
'note': note,
}
return render(request, 'documents/note_confirm_finalize.html', context)
@login_required
def note_addendum(request, pk):
"""Add an addendum to a finalized clinical note."""
note = get_object_or_404(ClinicalNote, pk=pk)
if note.status != 'final':
messages.error(request, _('Addendums can only be added to finalized notes.'))
return redirect('documents:note-detail', pk=note.pk)
if request.method == 'POST':
form = NoteAddendumForm(request.POST, user=request.user, note=note)
if form.is_valid():
addendum = form.save()
# Update note status to amended
note.status = 'amended'
note.save()
# Log the addendum
NoteAuditLog.objects.create(
note=note,
action='amended',
user=request.user,
ip_address=request.META.get('REMOTE_ADDR'),
changes={'addendum_id': addendum.id, 'reason': addendum.reason}
)
messages.success(request, _('Addendum added successfully.'))
return redirect('documents:note-detail', pk=note.pk)
else:
form = NoteAddendumForm(user=request.user, note=note)
context = {
'form': form,
'note': note,
}
return render(request, 'documents/note_addendum.html', context)
@login_required
def note_audit(request, pk):
"""View audit trail for a clinical note."""
note = get_object_or_404(ClinicalNote, pk=pk)
audit_logs = note.audit_logs.select_related('user').all()
context = {
'note': note,
'audit_logs': audit_logs,
}
return render(request, 'documents/note_audit.html', context)