HH/COMPLAINT_ESCALATION_DROPDOWN_IMPLEMENTATION.md
2026-02-22 08:35:53 +03:00

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

  1. Admin opens complaint detail page
  2. Clicks "Escalate" button
  3. Modal opens with dropdown pre-selected to staff's manager
  4. Manager's name shows with "[Manager (Default)]" label
  5. Admin can either:
    • Keep the default (manager) and submit
    • Select a different person from the dropdown
  6. 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

  1. Admin opens complaint detail page
  2. Clicks "Escalate" button
  3. Modal opens with dropdown but no default selection
  4. Warning message shows: "No manager assigned to this staff member"
  5. Admin must select a person from the dropdown
  6. 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 escalation
  • escalate_to (optional): User ID to escalate to (defaults to staff's manager)

Behavior:

  • If escalate_to is provided and valid, escalates to that user
  • If escalate_to is 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

  1. apps/complaints/ui_views.py

    • Added logging import
    • Updated complaint_detail to pass escalation targets
    • Updated complaint_escalate to handle target selection
  2. 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