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.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 send_to_department_form(request, pk): complaint = get_object_or_404( Complaint.objects.prefetch_related( "involved_staff__staff__department", "involved_staff__staff__report_to", "involved_departments__department__respondent", "involved_departments__department__manager", ), pk=pk, ) 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.")) 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) involved_staff = complaint.involved_staff.select_related( "staff", "staff__department", "staff__report_to" ).all() department_groups = {} ungrouped_staff = [] # Build department groups from involved_departments first involved_departments = complaint.involved_departments.select_related( "department__respondent", "department__manager" ).all() for dept_inv in involved_departments: dept = dept_inv.department if not dept or not dept.respondent: continue dept_key = str(dept.id) if dept_key not in department_groups: champion = dept.respondent champion_email = champion.email or (champion.user.email if champion.user else None) dept_manager = dept.manager department_groups[dept_key] = { "department_id": dept_key, "department_name": dept.get_localized_name(), "champion": champion, "champion_id": str(champion.id), "champion_name": champion.get_full_name(), "champion_email": champion_email, "dept_manager": dept_manager, "dept_manager_id": str(dept_manager.id) if dept_manager else None, "dept_manager_name": dept_manager.get_full_name() if dept_manager else None, "dept_manager_email": dept_manager.email if dept_manager else None, "staff_list": [], } # Add involved staff to their department groups for staff_inv in involved_staff: staff = staff_inv.staff dept = staff.department entry = { "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), "role": staff_inv.get_role_display(), } if dept and dept.respondent: dept_key = str(dept.id) if dept_key in department_groups: department_groups[dept_key]["staff_list"].append(entry) else: # This shouldn't happen if we built department_groups from involved_departments, # but handle as fallback champion = dept.respondent champion_email = champion.email or (champion.user.email if champion.user else None) dept_manager = dept.manager department_groups[dept_key] = { "department_id": dept_key, "department_name": dept.get_localized_name(), "champion": champion, "champion_id": str(champion.id), "champion_name": champion.get_full_name(), "champion_email": champion_email, "dept_manager": dept_manager, "dept_manager_id": str(dept_manager.id) if dept_manager else None, "dept_manager_name": dept_manager.get_full_name() if dept_manager else None, "dept_manager_email": dept_manager.email if dept_manager else None, "staff_list": [entry], } else: ungrouped_staff.append(entry) # Only show error if there are NO departments with champions AND no staff if not department_groups and not involved_staff.exists(): messages.error(request, _("No staff members or departments are involved in this complaint.")) return redirect("complaints:complaint_detail", pk=complaint.pk) if request.method == "POST": action = request.POST.get("action", "send") selected_dept_ids = request.POST.getlist("selected_departments") request_message = request.POST.get("request_message", "").strip() if not selected_dept_ids: messages.error(request, _("Please select at least one department.")) return render( request, "complaints/send_to_department_form.html", { "complaint": complaint, "department_groups": department_groups, "ungrouped_staff": ungrouped_staff, }, ) if action == "preview": preview_depts = [] for dept_id in selected_dept_ids: dept_info = department_groups.get(dept_id) if dept_info: preview_depts.append(dept_info) return render( request, "complaints/send_to_department_preview.html", { "complaint": complaint, "preview_depts": preview_depts, "selected_dept_ids": selected_dept_ids, "request_message": request_message, }, ) from django.contrib.sites.shortcuts import get_current_site site = get_current_site(request) results = ComplaintService.send_to_department( complaint, department_groups, selected_dept_ids, request_message, request.user, site.domain, request=request, ) if results["champion_count"] == 0 and results["manager_count"] == 0: if results["skipped_no_email"] > 0: messages.warning( request, _( "No explanation requests were sent. {} department(s) have champions without email addresses." ).format(results["skipped_no_email"]), ) else: messages.warning( request, _("No explanation requests were sent. Please check department champion configuration.") ) elif results["champion_count"] == 0 and results["manager_count"] > 0: messages.warning( request, _( "Only department manager notifications were sent ({}). Champion explanation requests could not be sent." ).format(results["manager_count"]), ) else: messages.success( request, _("Explanation requests sent! Champions: {}, Department managers notified: {}.").format( results["champion_count"], results["manager_count"] ), ) return redirect("complaints:complaint_detail", pk=complaint.pk) return render( request, "complaints/send_to_department_form.html", { "complaint": complaint, "department_groups": department_groups, "ungrouped_staff": ungrouped_staff, }, )