165 lines
6.0 KiB
Python
165 lines
6.0 KiB
Python
"""
|
|
Explanation request UI views for complaints.
|
|
"""
|
|
|
|
from django.contrib import messages
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.http import HttpResponseForbidden
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
from django.utils import timezone
|
|
from django.utils.translation import gettext as _
|
|
from django.views.decorators.http import require_http_methods
|
|
|
|
from apps.core.services import AuditService
|
|
from apps.notifications.services import NotificationService
|
|
from apps.organizations.models import Staff
|
|
|
|
from .models import Complaint, ComplaintExplanation, ComplaintStatus
|
|
from .services.complaint_service import ComplaintService, ComplaintServiceError
|
|
|
|
|
|
@login_required
|
|
@require_http_methods(["GET", "POST"])
|
|
def request_explanation_form(request, pk):
|
|
"""
|
|
Form to request explanations from involved staff members.
|
|
|
|
Shows all involved staff with their managers and departments.
|
|
All staff and managers are selected by default.
|
|
"""
|
|
complaint = get_object_or_404(
|
|
Complaint.objects.prefetch_related(
|
|
"involved_staff__staff__department",
|
|
"involved_staff__staff__report_to",
|
|
),
|
|
pk=pk,
|
|
)
|
|
|
|
# Check permissions
|
|
user = request.user
|
|
can_request = (
|
|
user.is_px_admin()
|
|
or user.is_hospital_admin()
|
|
or (user.is_department_manager() and complaint.department == user.department)
|
|
or (complaint.hospital == user.hospital)
|
|
)
|
|
|
|
if not can_request:
|
|
return HttpResponseForbidden(_("You don't have permission to request explanations."))
|
|
|
|
# Check complaint is in active status
|
|
if not complaint.is_active_status:
|
|
messages.error(
|
|
request,
|
|
_(
|
|
"Cannot request explanation for complaint with status '{}'. Complaint must be Open, In Progress, or Partially Resolved."
|
|
).format(complaint.get_status_display()),
|
|
)
|
|
return redirect("complaints:complaint_detail", pk=complaint.pk)
|
|
|
|
# Get all involved staff with their managers
|
|
involved_staff = complaint.involved_staff.select_related("staff", "staff__department", "staff__report_to").all()
|
|
|
|
if not involved_staff.exists():
|
|
messages.error(request, _("No staff members are involved in this complaint."))
|
|
return redirect("complaints:complaint_detail", pk=complaint.pk)
|
|
|
|
# Build list of recipients (staff + managers)
|
|
recipients = []
|
|
manager_ids = set()
|
|
|
|
for staff_inv in involved_staff:
|
|
staff = staff_inv.staff
|
|
manager = staff.report_to
|
|
|
|
recipient = {
|
|
"staff_inv": staff_inv,
|
|
"staff": staff,
|
|
"staff_id": str(staff.id),
|
|
"staff_name": staff.get_full_name(),
|
|
"staff_email": staff.email or (staff.user.email if staff.user else None),
|
|
"department": staff.department.name if staff.department else "-",
|
|
"role": staff_inv.get_role_display(),
|
|
"manager": manager,
|
|
"manager_id": str(manager.id) if manager else None,
|
|
"manager_name": manager.get_full_name() if manager else None,
|
|
"manager_email": manager.email if manager else None,
|
|
}
|
|
recipients.append(recipient)
|
|
|
|
# Track unique managers
|
|
if manager and manager.id not in manager_ids:
|
|
manager_ids.add(manager.id)
|
|
|
|
if request.method == "POST":
|
|
# Get selected staff and managers
|
|
selected_staff_ids = request.POST.getlist("selected_staff")
|
|
selected_manager_ids = request.POST.getlist("selected_managers")
|
|
request_message = request.POST.get("request_message", "").strip()
|
|
|
|
if not selected_staff_ids:
|
|
messages.error(request, _("Please select at least one staff member."))
|
|
return render(
|
|
request,
|
|
"complaints/request_explanation_form.html",
|
|
{
|
|
"complaint": complaint,
|
|
"recipients": recipients,
|
|
"manager_ids": manager_ids,
|
|
},
|
|
)
|
|
|
|
# Send explanation requests
|
|
from django.contrib.sites.shortcuts import get_current_site
|
|
|
|
site = get_current_site(request)
|
|
results = ComplaintService.request_explanation(
|
|
complaint,
|
|
recipients,
|
|
selected_staff_ids,
|
|
selected_manager_ids,
|
|
request_message,
|
|
request.user,
|
|
site.domain,
|
|
request=request,
|
|
)
|
|
|
|
# Check results and show appropriate message
|
|
if results["staff_count"] == 0 and results["manager_count"] == 0:
|
|
if results["skipped_no_email"] > 0:
|
|
messages.warning(
|
|
request,
|
|
_(
|
|
"No explanation requests were sent. {} staff member(s) do not have email addresses. Please update staff records with email addresses before sending explanation requests."
|
|
).format(results["skipped_no_email"]),
|
|
)
|
|
else:
|
|
messages.warning(
|
|
request, _("No explanation requests were sent. Please check staff email configuration.")
|
|
)
|
|
elif results["staff_count"] == 0 and results["manager_count"] > 0:
|
|
messages.warning(
|
|
request,
|
|
_(
|
|
"Only manager notifications were sent ({}). Staff explanation requests could not be sent due to missing email addresses."
|
|
).format(results["manager_count"]),
|
|
)
|
|
else:
|
|
messages.success(
|
|
request,
|
|
_("Explanation requests sent successfully! Staff: {}, Managers notified: {}.").format(
|
|
results["staff_count"], results["manager_count"]
|
|
),
|
|
)
|
|
return redirect("complaints:complaint_detail", pk=complaint.pk)
|
|
|
|
return render(
|
|
request,
|
|
"complaints/request_explanation_form.html",
|
|
{
|
|
"complaint": complaint,
|
|
"recipients": recipients,
|
|
"manager_ids": manager_ids,
|
|
},
|
|
)
|