475 lines
16 KiB
Python
475 lines
16 KiB
Python
from django.contrib.auth.decorators import login_required
|
|
from django.core.paginator import Paginator
|
|
from django.db.models import Q
|
|
from django.shortcuts import render, redirect, get_object_or_404
|
|
from django.contrib import messages
|
|
|
|
from .models import Department, Hospital, Organization, Patient, Staff
|
|
from .forms import StaffForm
|
|
|
|
|
|
@login_required
|
|
def hospital_list(request):
|
|
"""Hospitals list view"""
|
|
queryset = Hospital.objects.all()
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin() and user.hospital:
|
|
queryset = queryset.filter(id=user.hospital.id)
|
|
|
|
# Apply filters
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(name__icontains=search_query) |
|
|
Q(name_ar__icontains=search_query) |
|
|
Q(code__icontains=search_query)
|
|
)
|
|
|
|
# Ordering
|
|
queryset = queryset.order_by('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)
|
|
|
|
context = {
|
|
'page_obj': page_obj,
|
|
'hospitals': page_obj.object_list,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'organizations/hospital_list.html', context)
|
|
|
|
|
|
@login_required
|
|
def department_list(request):
|
|
"""Departments list view"""
|
|
queryset = Department.objects.select_related('hospital', 'manager')
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin() and user.hospital:
|
|
queryset = queryset.filter(hospital=user.hospital)
|
|
|
|
# Apply filters
|
|
hospital_filter = request.GET.get('hospital')
|
|
if hospital_filter:
|
|
queryset = queryset.filter(hospital_id=hospital_filter)
|
|
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(name__icontains=search_query) |
|
|
Q(name_ar__icontains=search_query) |
|
|
Q(code__icontains=search_query)
|
|
)
|
|
|
|
# Ordering
|
|
queryset = queryset.order_by('hospital', '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 hospitals for filter
|
|
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,
|
|
'departments': page_obj.object_list,
|
|
'hospitals': hospitals,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'organizations/department_list.html', context)
|
|
|
|
|
|
@login_required
|
|
def staff_list(request):
|
|
"""Staff list view"""
|
|
queryset = Staff.objects.select_related('hospital', 'department', 'user')
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin() and user.hospital:
|
|
queryset = queryset.filter(hospital=user.hospital)
|
|
|
|
# Apply filters
|
|
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)
|
|
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
staff_type_filter = request.GET.get('staff_type')
|
|
if staff_type_filter:
|
|
queryset = queryset.filter(staff_type=staff_type_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(first_name__icontains=search_query) |
|
|
Q(last_name__icontains=search_query) |
|
|
Q(employee_id__icontains=search_query) |
|
|
Q(license_number__icontains=search_query) |
|
|
Q(specialization__icontains=search_query) |
|
|
Q(job_title__icontains=search_query)
|
|
)
|
|
|
|
# Ordering
|
|
queryset = queryset.order_by('last_name', 'first_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 hospitals for filter
|
|
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,
|
|
'staff': page_obj.object_list,
|
|
'hospitals': hospitals,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'organizations/staff_list.html', context)
|
|
|
|
|
|
@login_required
|
|
def organization_list(request):
|
|
"""Organizations list view"""
|
|
queryset = Organization.objects.all()
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin() and user.hospital and user.hospital.organization:
|
|
queryset = queryset.filter(id=user.hospital.organization.id)
|
|
|
|
# Apply filters
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
city_filter = request.GET.get('city')
|
|
if city_filter:
|
|
queryset = queryset.filter(city__icontains=city_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(name__icontains=search_query) |
|
|
Q(name_ar__icontains=search_query) |
|
|
Q(code__icontains=search_query) |
|
|
Q(license_number__icontains=search_query)
|
|
)
|
|
|
|
# Ordering
|
|
queryset = queryset.order_by('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)
|
|
|
|
context = {
|
|
'page_obj': page_obj,
|
|
'organizations': page_obj.object_list,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'organizations/organization_list.html', context)
|
|
|
|
|
|
@login_required
|
|
def organization_detail(request, pk):
|
|
"""Organization detail view"""
|
|
organization = Organization.objects.get(pk=pk)
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin():
|
|
if user.hospital and user.hospital.organization:
|
|
if organization.id != user.hospital.organization.id:
|
|
# User doesn't have access to this organization
|
|
from django.http import HttpResponseForbidden
|
|
return HttpResponseForbidden("You don't have permission to view this organization")
|
|
else:
|
|
from django.http import HttpResponseForbidden
|
|
return HttpResponseForbidden("You don't have permission to view this organization")
|
|
|
|
hospitals = organization.hospitals.all()
|
|
|
|
context = {
|
|
'organization': organization,
|
|
'hospitals': hospitals,
|
|
}
|
|
|
|
return render(request, 'organizations/organization_detail.html', context)
|
|
|
|
|
|
@login_required
|
|
def organization_create(request):
|
|
"""Create organization view"""
|
|
# Only PX Admins can create organizations
|
|
user = request.user
|
|
if not user.is_px_admin():
|
|
from django.http import HttpResponseForbidden
|
|
return HttpResponseForbidden("Only PX Admins can create organizations")
|
|
|
|
if request.method == 'POST':
|
|
name = request.POST.get('name')
|
|
name_ar = request.POST.get('name_ar')
|
|
code = request.POST.get('code')
|
|
address = request.POST.get('address', '')
|
|
city = request.POST.get('city', '')
|
|
phone = request.POST.get('phone', '')
|
|
email = request.POST.get('email', '')
|
|
website = request.POST.get('website', '')
|
|
license_number = request.POST.get('license_number', '')
|
|
status = request.POST.get('status', 'active')
|
|
|
|
if name and code:
|
|
organization = Organization.objects.create(
|
|
name=name,
|
|
name_ar=name_ar or name,
|
|
code=code,
|
|
address=address,
|
|
city=city,
|
|
phone=phone,
|
|
email=email,
|
|
website=website,
|
|
license_number=license_number,
|
|
status=status
|
|
)
|
|
|
|
# Redirect to organization detail
|
|
from django.shortcuts import redirect
|
|
return redirect('organizations:organization_detail', pk=organization.id)
|
|
|
|
return render(request, 'organizations/organization_form.html')
|
|
|
|
|
|
@login_required
|
|
def patient_list(request):
|
|
"""Patients list view"""
|
|
queryset = Patient.objects.select_related('primary_hospital')
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin() and user.hospital:
|
|
queryset = queryset.filter(primary_hospital=user.hospital)
|
|
|
|
# Apply filters
|
|
hospital_filter = request.GET.get('hospital')
|
|
if hospital_filter:
|
|
queryset = queryset.filter(primary_hospital_id=hospital_filter)
|
|
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
queryset = queryset.filter(status=status_filter)
|
|
|
|
# Search
|
|
search_query = request.GET.get('search')
|
|
if search_query:
|
|
queryset = queryset.filter(
|
|
Q(mrn__icontains=search_query) |
|
|
Q(first_name__icontains=search_query) |
|
|
Q(last_name__icontains=search_query) |
|
|
Q(national_id__icontains=search_query) |
|
|
Q(phone__icontains=search_query)
|
|
)
|
|
|
|
# Ordering
|
|
queryset = queryset.order_by('last_name', 'first_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 hospitals for filter
|
|
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,
|
|
'patients': page_obj.object_list,
|
|
'hospitals': hospitals,
|
|
'filters': request.GET,
|
|
}
|
|
|
|
return render(request, 'organizations/patient_list.html', context)
|
|
|
|
|
|
@login_required
|
|
def staff_detail(request, pk):
|
|
"""Staff detail view"""
|
|
staff = get_object_or_404(Staff.objects.select_related('user', 'hospital', 'department'), pk=pk)
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin() and staff.hospital != user.hospital:
|
|
from django.http import HttpResponseForbidden
|
|
return HttpResponseForbidden("You don't have permission to view this staff member")
|
|
|
|
context = {
|
|
'staff': staff,
|
|
}
|
|
|
|
return render(request, 'organizations/staff_detail.html', context)
|
|
|
|
|
|
@login_required
|
|
def staff_create(request):
|
|
"""Create staff view"""
|
|
# Only PX Admins and Hospital Admins can create staff
|
|
user = request.user
|
|
if not user.is_px_admin() and not user.is_hospital_admin():
|
|
from django.http import HttpResponseForbidden
|
|
return HttpResponseForbidden("You don't have permission to create staff")
|
|
|
|
if request.method == 'POST':
|
|
form = StaffForm(request.POST)
|
|
if form.is_valid():
|
|
staff = form.save(commit=False)
|
|
|
|
# Handle user account creation
|
|
create_user = request.POST.get('create_user') == 'on'
|
|
if create_user and not staff.user and staff.email:
|
|
from .services import StaffService
|
|
try:
|
|
role = StaffService.get_staff_type_role(staff.staff_type)
|
|
user_account = StaffService.create_user_for_staff(
|
|
staff,
|
|
role=role,
|
|
request=request
|
|
)
|
|
# Generate password for email
|
|
password = StaffService.generate_password()
|
|
user_account.set_password(password)
|
|
user_account.save()
|
|
try:
|
|
StaffService.send_credentials_email(staff, password, request)
|
|
messages.success(request, 'Staff member created and credentials email sent successfully.')
|
|
except Exception as e:
|
|
messages.warning(request, f'Staff member created but email sending failed: {str(e)}')
|
|
except Exception as e:
|
|
messages.error(request, f'Staff member created but user account creation failed: {str(e)}')
|
|
|
|
staff.save()
|
|
|
|
# Send invitation email if requested
|
|
if create_user and staff.user and request.POST.get('send_email') != 'false':
|
|
from .services import StaffService
|
|
try:
|
|
password = StaffService.generate_password()
|
|
staff.user.set_password(password)
|
|
staff.user.save()
|
|
StaffService.send_credentials_email(staff, password, request)
|
|
messages.success(request, 'Credentials email sent successfully.')
|
|
except Exception as e:
|
|
messages.warning(request, f'Email sending failed: {str(e)}')
|
|
|
|
messages.success(request, 'Staff member created successfully.')
|
|
return redirect('organizations:staff_detail', pk=staff.id)
|
|
else:
|
|
form = StaffForm(user=request.user)
|
|
|
|
context = {
|
|
'form': form,
|
|
}
|
|
|
|
return render(request, 'organizations/staff_form.html', context)
|
|
|
|
|
|
@login_required
|
|
def staff_update(request, pk):
|
|
"""Update staff view"""
|
|
staff = get_object_or_404(Staff.objects.select_related('user'), pk=pk)
|
|
|
|
# Apply RBAC filters
|
|
user = request.user
|
|
if not user.is_px_admin() and not user.is_hospital_admin():
|
|
from django.http import HttpResponseForbidden
|
|
return HttpResponseForbidden("You don't have permission to update this staff member")
|
|
|
|
if user.is_hospital_admin() and staff.hospital != user.hospital:
|
|
from django.http import HttpResponseForbidden
|
|
return HttpResponseForbidden("You don't have permission to update this staff member")
|
|
|
|
if request.method == 'POST':
|
|
form = StaffForm(request.POST, instance=staff)
|
|
if form.is_valid():
|
|
staff = form.save(commit=False)
|
|
|
|
# Handle user account creation
|
|
create_user = request.POST.get('create_user') == 'on'
|
|
if create_user and not staff.user and staff.email:
|
|
from .services import StaffService
|
|
try:
|
|
role = StaffService.get_staff_type_role(staff.staff_type)
|
|
user_account = StaffService.create_user_for_staff(
|
|
staff,
|
|
role=role,
|
|
request=request
|
|
)
|
|
# Generate password for email
|
|
password = StaffService.generate_password()
|
|
user_account.set_password(password)
|
|
user_account.save()
|
|
try:
|
|
StaffService.send_credentials_email(staff, password, request)
|
|
messages.success(request, 'User account created and credentials email sent.')
|
|
except Exception as e:
|
|
messages.warning(request, f'User account created but email sending failed: {str(e)}')
|
|
except Exception as e:
|
|
messages.error(request, f'User account creation failed: {str(e)}')
|
|
|
|
staff.save()
|
|
|
|
messages.success(request, 'Staff member updated successfully.')
|
|
return redirect('organizations:staff_detail', pk=staff.id)
|
|
else:
|
|
form = StaffForm(instance=staff, user=request.user)
|
|
|
|
context = {
|
|
'form': form,
|
|
'staff': staff,
|
|
}
|
|
|
|
return render(request, 'organizations/staff_form.html', context)
|