HH/apps/references/views.py

271 lines
9.1 KiB
Python

"""
References views - View functions for Reference Section
"""
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.http import JsonResponse, Http404, FileResponse
from django.shortcuts import get_object_or_404, redirect
from django.utils import timezone
from apps.core.mixins import TenantRequiredMixin
from apps.references.models import ReferenceFolder, ReferenceDocument, ReferenceDocumentAccess
from apps.references.forms import ReferenceFolderForm, ReferenceDocumentForm
@login_required
def folder_list(request):
"""API endpoint to list folders for the current hospital"""
# Get current hospital - use tenant_hospital for PX admins, user.hospital for regular users
hospital = getattr(request, 'tenant_hospital', None) or request.user.hospital
if not hospital:
return JsonResponse({'error': 'No hospital assigned'}, status=400)
parent_id = request.GET.get('parent')
folders = ReferenceFolder.objects.filter(
hospital=hospital,
is_active=True,
is_deleted=False
)
if parent_id:
try:
parent = ReferenceFolder.objects.get(id=parent_id, hospital=hospital)
folders = folders.filter(parent=parent)
except ReferenceFolder.DoesNotExist:
folders = folders.filter(parent=None)
else:
folders = folders.filter(parent=None)
# Filter by access
folders = [f for f in folders if f.has_access(request.user)]
data = [
{
'id': str(folder.id),
'name': folder.name,
'name_ar': folder.name_ar,
'description': folder.description,
'description_ar': folder.description_ar,
'icon': folder.icon,
'color': folder.color,
'document_count': folder.get_document_count(),
'order': folder.order
}
for folder in folders
]
return JsonResponse({'folders': data})
@login_required
def folder_detail(request, pk):
"""API endpoint to get folder details"""
# Get current hospital - use tenant_hospital for PX admins, user.hospital for regular users
hospital = getattr(request, 'tenant_hospital', None) or request.user.hospital
if not hospital:
return JsonResponse({'error': 'No hospital assigned'}, status=400)
folder = get_object_or_404(ReferenceFolder, pk=pk, hospital=hospital, is_deleted=False)
if not folder.has_access(request.user):
raise PermissionDenied()
data = {
'id': str(folder.id),
'name': folder.name,
'name_ar': folder.name_ar,
'description': folder.description,
'description_ar': folder.description_ar,
'icon': folder.icon,
'color': folder.color,
'document_count': folder.get_document_count(),
'full_path': folder.get_full_path()
}
return JsonResponse({'folder': data})
@login_required
def document_list(request):
"""API endpoint to list documents with filtering"""
# Get current hospital - use tenant_hospital for PX admins, user.hospital for regular users
hospital = getattr(request, 'tenant_hospital', None) or request.user.hospital
if not hospital:
return JsonResponse({'error': 'No hospital assigned'}, status=400)
documents = ReferenceDocument.objects.filter(
hospital=hospital,
is_published=True,
is_deleted=False
)
# Filter by folder
folder_id = request.GET.get('folder')
if folder_id:
try:
folder = ReferenceFolder.objects.get(id=folder_id, hospital=hospital)
documents = documents.filter(folder=folder)
except ReferenceFolder.DoesNotExist:
pass
# Filter by file type
file_type = request.GET.get('file_type')
if file_type:
documents = documents.filter(file_type__iexact=file_type)
# Search
search = request.GET.get('search')
if search:
from django.db.models import Q
documents = documents.filter(
Q(title__icontains=search) |
Q(title_ar__icontains=search) |
Q(description__icontains=search) |
Q(description_ar__icontains=search) |
Q(tags__icontains=search)
)
# Filter by tags
tags = request.GET.get('tags')
if tags:
tag_list = [tag.strip() for tag in tags.split(',')]
for tag in tag_list:
documents = documents.filter(tags__icontains=tag)
# Filter by access
documents = [d for d in documents if d.has_access(request.user)]
data = [
{
'id': str(doc.id),
'title': doc.title,
'title_ar': doc.title_ar,
'description': doc.description,
'description_ar': doc.description_ar,
'filename': doc.filename,
'file_type': doc.file_type,
'file_size': doc.file_size,
'file_size_display': doc.get_file_size_display(),
'version': doc.version,
'is_latest_version': doc.is_latest_version,
'download_count': doc.download_count,
'tags': doc.tags,
'folder_id': str(doc.folder.id) if doc.folder else None,
'folder_name': doc.folder.name if doc.folder else None,
'created_at': doc.created_at.isoformat(),
'last_accessed_at': doc.last_accessed_at.isoformat() if doc.last_accessed_at else None
}
for doc in documents
]
return JsonResponse({'documents': data})
@login_required
def document_detail(request, pk):
"""API endpoint to get document details"""
# Get current hospital - use tenant_hospital for PX admins, user.hospital for regular users
hospital = getattr(request, 'tenant_hospital', None) or request.user.hospital
if not hospital:
return JsonResponse({'error': 'No hospital assigned'}, status=400)
document = get_object_or_404(ReferenceDocument, pk=pk, hospital=hospital, is_deleted=False)
if not document.has_access(request.user):
raise PermissionDenied()
data = {
'id': str(document.id),
'title': document.title,
'title_ar': document.title_ar,
'description': document.description,
'description_ar': document.description_ar,
'filename': document.filename,
'file_type': document.file_type,
'file_size': document.file_size,
'file_size_display': document.get_file_size_display(),
'version': document.version,
'is_latest_version': document.is_latest_version,
'download_count': document.download_count,
'tags': document.tags,
'folder_id': str(document.folder.id) if document.folder else None,
'folder_name': document.folder.name if document.folder else None,
'created_at': document.created_at.isoformat(),
'last_accessed_at': document.last_accessed_at.isoformat() if document.last_accessed_at else None,
'uploaded_by': {
'email': document.uploaded_by.email,
'full_name': document.uploaded_by.get_full_name()
} if document.uploaded_by else None
}
return JsonResponse({'document': data})
@login_required
def document_download(request, pk):
"""
Handle document download with access logging
"""
# Get current hospital - use tenant_hospital for PX admins, user.hospital for regular users
hospital = getattr(request, 'tenant_hospital', None) or request.user.hospital
if not hospital:
raise Http404("No hospital assigned")
document = get_object_or_404(ReferenceDocument, pk=pk, hospital=hospital, is_deleted=False)
if not document.has_access(request.user):
raise PermissionDenied()
# Increment download count
document.increment_download_count()
# Log the access
ReferenceDocumentAccess.objects.create(
document=document,
user=request.user,
action='download',
ip_address=request.META.get('REMOTE_ADDR'),
user_agent=request.META.get('HTTP_USER_AGENT', '')
)
# Return file response
if document.file:
return FileResponse(
document.file,
as_attachment=True,
filename=document.filename
)
raise Http404("File not found")
@login_required
def document_version_history(request, pk):
"""API endpoint to get version history of a document"""
# Get current hospital - use tenant_hospital for PX admins, user.hospital for regular users
hospital = getattr(request, 'tenant_hospital', None) or request.user.hospital
if not hospital:
return JsonResponse({'error': 'No hospital assigned'}, status=400)
document = get_object_or_404(ReferenceDocument, pk=pk, hospital=hospital, is_deleted=False)
if not document.has_access(request.user):
raise PermissionDenied()
versions = document.get_version_history()
data = [
{
'id': str(ver.id),
'version': ver.version,
'is_latest_version': ver.is_latest_version,
'filename': ver.filename,
'file_size': ver.file_size,
'file_size_display': ver.get_file_size_display(),
'created_at': ver.created_at.isoformat()
}
for ver in versions
]
return JsonResponse({'versions': data})