7.9 KiB
7.9 KiB
Complaint Escalation Dropdown Implementation
Overview
Modified the escalate complaint modal to show a dropdown for selecting who to escalate to, with the staff's manager pre-selected as the default.
Changes Made
1. Backend - apps/complaints/ui_views.py
Added Logger Import
import logging
logger = logging.getLogger(__name__)
Updated complaint_detail View
Added escalation targets to the context:
# Get escalation targets (for escalate modal dropdown)
escalation_targets = []
default_escalation_target = None
if complaint.hospital:
# Get hospital admins and department managers as escalation targets
escalation_targets = list(User.objects.filter(
is_active=True,
hospital=complaint.hospital
).filter(
models.Q(role='hospital_admin') | models.Q(role='department_manager') | models.Q(role='px_admin')
).select_related('department').order_by('first_name', 'last_name'))
# If complaint has staff with a manager, add manager as default
if complaint.staff and complaint.staff.report_to:
# Try to find the manager's user account
manager_user = None
if complaint.staff.report_to.user:
manager_user = complaint.staff.report_to.user
else:
# Try to find by email
manager_user = User.objects.filter(
email=complaint.staff.report_to.email,
is_active=True
).first()
if manager_user and manager_user not in escalation_targets:
escalation_targets.insert(0, manager_user)
if manager_user:
default_escalation_target = manager_user.id
Added to context:
"escalation_targets": escalation_targets,
"default_escalation_target": default_escalation_target,
Updated complaint_escalate View
Modified to accept and handle the escalate_to parameter:
reason = request.POST.get("reason", "")
escalate_to_id = request.POST.get("escalate_to", "")
# Get the escalation target user
escalate_to_user = None
if escalate_to_id:
escalate_to_user = User.objects.filter(id=escalate_to_id, is_active=True).first()
# If no user selected or user not found, default to staff's manager
if not escalate_to_user and complaint.staff and complaint.staff.report_to:
if complaint.staff.report_to.user:
escalate_to_user = complaint.staff.report_to.user
else:
# Try to find by email
escalate_to_user = User.objects.filter(
email=complaint.staff.report_to.email,
is_active=True
).first()
# Mark as escalated and assign to selected user
complaint.escalated_at = timezone.now()
if escalate_to_user:
complaint.assigned_to = escalate_to_user
complaint.save(update_fields=["escalated_at", "assigned_to"])
Features added:
- Creates detailed escalation message with target user name
- Sends email notification to the escalated user
- Logs audit with escalation details
- Shows success message with the name of the person escalated to
2. Frontend - templates/complaints/complaint_detail.html
Updated Escalate Modal
Before:
- Simple modal with just a reason text area
- No selection of who to escalate to
After:
- Dropdown to select escalation target (required field)
- Shows all hospital admins, department managers, and PX admins
- Manager of the staff is pre-selected by default (marked with [Manager (Default)])
- Shows department and role for each target
- Helpful text explaining the default selection
- Warning if no manager is assigned
Template Code:
<div class="mb-3">
<label class="form-label">{% trans "Escalate To" %} <span class="text-danger">*</span></label>
<select name="escalate_to" class="form-select" required>
{% if escalation_targets %}
<option value="" disabled>{% trans "Select person to escalate to..." %}</option>
{% for target in escalation_targets %}
<option value="{{ target.id }}"
{% if default_escalation_target and target.id == default_escalation_target %}selected{% endif %}>
{{ target.get_full_name }}
{% if target.department %}
({{ target.department.name }})
{% endif %}
{% if target.role %}
- {{ target.get_role_display }}
{% endif %}
{% if complaint.staff and complaint.staff.report_to and complaint.staff.report_to.user and complaint.staff.report_to.user.id == target.id %}
[{% trans "Manager (Default)" %}]
{% endif %}
</option>
{% endfor %}
{% else %}
<option value="" disabled selected>{% trans "No escalation targets available" %}</option>
{% endif %}
</select>
{% if complaint.staff and complaint.staff.report_to %}
<div class="form-text text-muted">
<i class="bi bi-info-circle me-1"></i>
{% trans "Default selected is" %} <strong>{{ complaint.staff.report_to.get_full_name }}</strong> ...
</div>
{% else %}
<div class="form-text text-warning">
<i class="bi bi-exclamation-triangle me-1"></i>
{% trans "No manager assigned to this staff member..." %}
</div>
{% endif %}
</div>
User Flow
Scenario 1: Staff Has Manager Assigned
- Admin opens complaint detail page
- Clicks "Escalate" button
- Modal opens with dropdown pre-selected to staff's manager
- Manager's name shows with "[Manager (Default)]" label
- Admin can either:
- Keep the default (manager) and submit
- Select a different person from the dropdown
- On submit:
- Complaint is assigned to the selected user
- Escalation update is created with details
- Selected user receives email notification
- Admin sees success message with selected person's name
Scenario 2: Staff Has No Manager Assigned
- Admin opens complaint detail page
- Clicks "Escalate" button
- Modal opens with dropdown but no default selection
- Warning message shows: "No manager assigned to this staff member"
- Admin must select a person from the dropdown
- On submit: Same flow as above
Escalation Target Selection
Available Targets Include:
- Staff's Manager (default, if exists) - marked with "[Manager (Default)]"
- Hospital Admins
- Department Managers
- PX Admins
Display Format:
John Smith (Cardiology) - Hospital Admin [Manager (Default)]
Sarah Johnson (Emergency) - Department Manager
Mike Davis (Surgery) - PX Admin
API Changes
POST /complaints/{id}/escalate/
Parameters:
reason(required): Reason for escalationescalate_to(optional): User ID to escalate to (defaults to staff's manager)
Behavior:
- If
escalate_tois provided and valid, escalates to that user - If
escalate_tois not provided or invalid, defaults to staff's manager - If staff has no manager and no target is selected, escalation proceeds without assignment
Files Modified
-
apps/complaints/ui_views.py- Added logging import
- Updated
complaint_detailto pass escalation targets - Updated
complaint_escalateto handle target selection
-
templates/complaints/complaint_detail.html- Updated escalate modal with dropdown
- Added default selection logic
- Added help text and warnings
Testing Checklist
- Open complaint with staff who has manager → Manager pre-selected
- Open complaint with staff who has no manager → No default, warning shown
- Escalate with default manager → Success, manager gets email
- Escalate with different target → Success, selected person gets email
- Escalate without selecting target when no manager → Works without assignment
- Verify escalation appears in complaint timeline
- Verify audit log captures escalation details
- Verify assigned_to field is updated to selected user