183 lines
6.1 KiB
Markdown
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 |