HH/COMPLAINT_FORM_FIX_SUMMARY.md

183 lines
6.1 KiB
Markdown

# Complaint Form Fix Summary
## Issue
The complaint form at `/complaints/new/` was failing with a TypeError due to incorrect usage of `QuerySet.none()`.
## Root Causes
1. **TypeError**: `QuerySet.none()` was being called as a class method instead of an instance method
2. **FieldError**: The form was trying to order by `name` field, but Location/MainSection/SubSection models use `name_en` for the display name
3. **Missing Fields**: The ComplaintForm was missing new fields added to the Complaint model
## Changes Made
### 1. Fixed `apps/complaints/forms.py`
#### PublicComplaintForm (Line 178)
**Before:**
```python
queryset=models.QuerySet.none(),
```
**After:**
```python
queryset=Department.objects.none(),
```
#### Initialize Cascading Dropdown Querysets
**Problem:** The `main_section` and `subsection` fields had `queryset=None` initially, causing:
```
'NoneType' object has no attribute '_prefetch_related_lookups'
```
**Solution:** Added initialization in `__init__` method for both ComplaintForm and PublicComplaintForm:
```python
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
from apps.organizations.models import Location, MainSection, SubSection
# Initialize cascading dropdowns with empty querysets
self.fields['main_section'].queryset = MainSection.objects.none()
self.fields['subsection'].queryset = SubSection.objects.none()
# Load all locations (no filtering needed)
self.fields['location'].queryset = Location.objects.all().order_by('name_en')
```
#### Added ComplaintType Import
```python
from apps.complaints.models import (
Complaint,
ComplaintCategory,
ComplaintSource,
ComplaintStatus,
ComplaintType, # Added
Inquiry,
ComplaintSLAConfig,
EscalationRule,
ComplaintThreshold,
)
```
#### Updated ComplaintForm with New Fields
Added the following fields to ComplaintForm class:
- `complaint_type` - Feedback type selection (Complaint/Appreciation)
- `relation_to_patient` - Patient or Relative
- `patient_name` - Name of patient involved
- `national_id` - Saudi National ID or Iqama number
- `incident_date` - Date when incident occurred
- `staff_name` - Staff member involved (if known)
- `expected_result` - Expected resolution from complainant
#### Fixed Field Ordering
Changed all `.order_by('name')` to `.order_by('name_en')` for Location, MainSection, and SubSection querysets to match the actual field names in the models.
### 2. Updated `templates/complaints/complaint_form.html`
#### New Sections Added:
1. **Feedback Type Selection**
- Visual cards for Complaint vs Appreciation selection
- Interactive JavaScript handlers for selection
2. **Patient Information Section**
- Relation to Patient dropdown
- Patient Name field
- National ID/Iqama field
- Incident Date field
- Encounter ID field (optional)
3. **Organization & Location Section**
- Hospital dropdown
- Department dropdown
- Location hierarchy (Location → Main Section → Subsection)
- Staff dropdown (optional)
- Staff Name field (optional)
4. **Complaint Details Section**
- Description field
- Expected Result field
5. **Enhanced JavaScript**
- Complaint type card selection handlers
- Hospital change handler (reloads form)
- Location change handler (loads sections via AJAX)
- Main Section change handler (loads subsections via AJAX)
- Department change handler (loads staff via AJAX)
- Form validation
6. **Updated Sidebar**
- AI Classification information
- SLA Information display
- Action buttons
## Model Fields Reference
### Location Hierarchy Models
```python
# Location model
name_en = models.CharField(max_length=200) # Display name
name_ar = models.CharField(max_length=200, blank=True)
# MainSection model
name_en = models.CharField(max_length=200) # Display name
name_ar = models.CharField(max_length=200, blank=True)
# SubSection model
name_en = models.CharField(max_length=200) # Display name
name_ar = models.CharField(max_length=200, blank=True)
```
### Complaint Model New Fields
```python
complaint_type = models.CharField(max_length=20, choices=ComplaintType.choices)
relation_to_patient = models.CharField(max_length=20)
patient_name = models.CharField(max_length=200)
national_id = models.CharField(max_length=20)
incident_date = models.DateField()
staff_name = models.CharField(max_length=200, blank=True)
expected_result = models.TextField(blank=True)
location = models.ForeignKey('organizations.Location')
main_section = models.ForeignKey('organizations.MainSection')
subsection = models.ForeignKey('organizations.SubSection')
```
## Verification
✅ Form imports successfully without errors
✅ All new fields are properly defined
✅ Field ordering uses correct field names (`name_en`)
✅ Template includes all new form sections
✅ JavaScript handlers implemented for cascading dropdowns
✅ Internationalization support maintained (i18n)
## Testing Checklist
- [ ] Form loads without errors at `/complaints/new/`
- [ ] Location dropdown loads all locations
- [ ] Selecting location loads sections via AJAX
- [ ] Selecting section loads subsections via AJAX
- [ ] Complaint type selection works visually
- [ ] Form validation works for all required fields
- [ ] Form submission creates complaint with all new fields
- [ ] Patient information fields display correctly
- [ ] Staff dropdown loads when department is selected
## Notes
1. **AJAX Endpoints**: The form relies on these AJAX endpoints:
- `/organizations/ajax/main-sections/?location_id={id}`
- `/organizations/ajax/subsections/?location_id={id}&main_section_id={id}`
- `/complaints/ajax/physicians/?department_id={id}`
2. **Location Hierarchy**: The form implements a 3-level cascading dropdown system:
- Level 1: Location (e.g., Riyadh, Jeddah)
- Level 2: Main Section (e.g., Clinical, Administrative)
- Level 3: Subsection (e.g., Outpatient, Inpatient)
3. **Complaint Type**: The form supports both Complaint and Appreciation types with a visual card-based selection interface.
4. **i18n Support**: All labels and placeholders use Django's translation system (`_("text")`) for multilingual support.
## Date Completed
February 4, 2026