271 lines
9.1 KiB
Python
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})
|