381 lines
12 KiB
Markdown
381 lines
12 KiB
Markdown
# Complaint to Appreciation Conversion Feature
|
|
|
|
## Overview
|
|
|
|
The Complaint to Appreciation Conversion feature allows PX staff to convert appreciation-type complaints into formal Appreciation records. This feature helps capture positive patient feedback and recognize staff members for excellent service.
|
|
|
|
## Feature Summary
|
|
|
|
- **Target Audience**: PX Admins and Hospital Admins
|
|
- **Complaint Type**: Only works for complaints marked as type "appreciation"
|
|
- **Purpose**: Convert positive feedback into a formal Appreciation record
|
|
- **Integration**: Links appreciation back to original complaint
|
|
- **Automation**: Optional auto-close of complaint after conversion
|
|
|
|
## How It Works
|
|
|
|
### 1. When to Use
|
|
|
|
The "Convert to Appreciation" button appears in the Quick Actions sidebar when:
|
|
- The complaint type is "appreciation" (not "complaint")
|
|
- The complaint has NOT already been converted to an appreciation
|
|
|
|
### 2. Conversion Process
|
|
|
|
1. **Click Button**: User clicks "Convert to Appreciation" button in Quick Actions sidebar
|
|
2. **Open Modal**: A modal opens with pre-filled fields
|
|
3. **Configure Options**:
|
|
- **Recipient**: Select staff member or physician (defaults to assigned staff if available)
|
|
- **Category**: Select appreciation category (defaults to "Patient Feedback Appreciation")
|
|
- **Message (English)**: Editable text pre-filled from complaint description
|
|
- **Message (Arabic)**: Editable text pre-filled from complaint short_description_ar
|
|
- **Visibility**: Choose who can see the appreciation
|
|
- **Sender**: Choose anonymous or patient as sender
|
|
- **Close Complaint**: Checkbox to auto-close complaint after conversion
|
|
|
|
4. **Submit**: Click "Convert" button to create appreciation
|
|
5. **Result**:
|
|
- Appreciation record is created
|
|
- Notification is sent to recipient
|
|
- Complaint metadata is updated with appreciation link
|
|
- Timeline entry is created for conversion
|
|
- Optionally, complaint is closed
|
|
- User is redirected to appreciation detail page
|
|
|
|
## Data Flow
|
|
|
|
### From Complaint to Appreciation
|
|
|
|
| Complaint Field | Appreciation Field | Notes |
|
|
|----------------|-------------------|-------|
|
|
| `description` | `message_en` | Can be edited in modal |
|
|
| `short_description_ar` | `message_ar` | Can be edited in modal |
|
|
| `hospital` | `hospital` | Auto-mapped |
|
|
| `department` | `department` | Auto-mapped |
|
|
| `patient` | `sender` | Only if patient user account exists and not anonymous |
|
|
| `staff` | `recipient` | Default recipient (can be changed) |
|
|
|
|
### Metadata Linkages
|
|
|
|
**Complaint Metadata** (stored in `complaint.metadata`):
|
|
```json
|
|
{
|
|
"appreciation_id": "uuid-of-created-appreciation",
|
|
"converted_to_appreciation": true,
|
|
"converted_to_appreciation_at": "2026-01-16T00:30:00Z",
|
|
"converted_by": "uuid-of-user"
|
|
}
|
|
```
|
|
|
|
**Appreciation Metadata** (stored in `appreciation.metadata`):
|
|
```json
|
|
{
|
|
"source_complaint_id": "uuid-of-original-complaint",
|
|
"source_complaint_title": "Original complaint title",
|
|
"converted_from_complaint": true,
|
|
"converted_by": "uuid-of-user",
|
|
"converted_at": "2026-01-16T00:30:00Z"
|
|
}
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### POST /complaints/api/complaints/{id}/convert_to_appreciation/
|
|
|
|
Converts a complaint to an appreciation record.
|
|
|
|
**Request Body**:
|
|
```json
|
|
{
|
|
"recipient_type": "user", // or "physician"
|
|
"recipient_id": "uuid",
|
|
"category_id": "uuid",
|
|
"message_en": "English message text",
|
|
"message_ar": "Arabic message text",
|
|
"visibility": "private", // "private", "department", "hospital", "public"
|
|
"is_anonymous": true,
|
|
"close_complaint": false
|
|
}
|
|
```
|
|
|
|
**Response** (201 Created):
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Complaint successfully converted to appreciation",
|
|
"appreciation_id": "uuid-of-created-appreciation",
|
|
"appreciation_url": "https://domain.com/appreciations/{uuid}/",
|
|
"complaint_closed": false
|
|
}
|
|
```
|
|
|
|
**Error Responses**:
|
|
- 400 Bad Request:
|
|
- "Only appreciation-type complaints can be converted to appreciations"
|
|
- "This complaint has already been converted to an appreciation"
|
|
- "Recipient user not found"
|
|
- "Recipient physician not found"
|
|
- "Appreciation category not found"
|
|
- 404 Not Found:
|
|
- "Recipient not found"
|
|
- "Appreciation category not found"
|
|
|
|
## User Interface
|
|
|
|
### Button Visibility
|
|
|
|
The "Convert to Appreciation" button shows:
|
|
```html
|
|
{% if complaint.complaint_type == 'appreciation' and not complaint.metadata.appreciation_id %}
|
|
<!-- Show conversion button -->
|
|
{% elif complaint.metadata.appreciation_id %}
|
|
<!-- Show "Converted to Appreciation" alert with link -->
|
|
{% endif %}
|
|
```
|
|
|
|
### After Conversion
|
|
|
|
After a successful conversion, the complaint detail page shows:
|
|
1. **Converted Alert**: Green alert box in Quick Actions
|
|
2. **Appreciation Link**: Direct link to the created appreciation
|
|
3. **Timeline Entry**: New note in timeline showing conversion details
|
|
4. **Complaint Status**: Optionally changed to "closed"
|
|
|
|
### Modal Fields
|
|
|
|
1. **Recipient Selection**:
|
|
- Type dropdown: "Staff Member" or "Physician"
|
|
- Dynamic list of available recipients
|
|
- Defaults to assigned staff member
|
|
|
|
2. **Category Selection**:
|
|
- Dropdown of all AppreciationCategory records
|
|
- Defaults to "Patient Feedback Appreciation" (code: `patient_feedback`)
|
|
|
|
3. **Messages**:
|
|
- English message (required)
|
|
- Arabic message (optional)
|
|
- Pre-filled from complaint description
|
|
|
|
4. **Visibility**:
|
|
- Private: sender and recipient only
|
|
- Department: visible to department members
|
|
- Hospital: visible to all hospital staff
|
|
- Public: can be displayed publicly
|
|
|
|
5. **Sender**:
|
|
- Anonymous: hide patient identity (default)
|
|
- Patient: show patient as sender
|
|
|
|
6. **Close Complaint**:
|
|
- Checkbox option
|
|
- If checked, complaint status changes to "closed"
|
|
- Adds status update entry to timeline
|
|
|
|
## Timeline Updates
|
|
|
|
### Conversion Entry
|
|
|
|
When a complaint is converted to appreciation, a timeline entry is created:
|
|
```python
|
|
ComplaintUpdate.objects.create(
|
|
complaint=complaint,
|
|
update_type='note',
|
|
message=f"Converted to appreciation (Appreciation #{appreciation.id})",
|
|
created_by=request.user,
|
|
metadata={
|
|
'appreciation_id': str(appreciation.id),
|
|
'converted_from_complaint': True,
|
|
'close_complaint': close_complaint
|
|
}
|
|
)
|
|
```
|
|
|
|
### Status Change Entry (if closing)
|
|
|
|
If the complaint is closed during conversion, a separate status change entry is created:
|
|
```python
|
|
ComplaintUpdate.objects.create(
|
|
complaint=complaint,
|
|
update_type='status_change',
|
|
message="Complaint closed after converting to appreciation",
|
|
created_by=request.user,
|
|
old_status='open',
|
|
new_status='closed'
|
|
)
|
|
```
|
|
|
|
## Audit Logging
|
|
|
|
All conversion actions are logged via AuditService:
|
|
```python
|
|
AuditService.log_from_request(
|
|
event_type='complaint_converted_to_appreciation',
|
|
description=f"Complaint converted to appreciation: {appreciation.message_en[:100]}",
|
|
request=request,
|
|
content_object=complaint,
|
|
metadata={
|
|
'appreciation_id': str(appreciation.id),
|
|
'close_complaint': close_complaint,
|
|
'is_anonymous': is_anonymous
|
|
}
|
|
)
|
|
```
|
|
|
|
## Default Category
|
|
|
|
The "Patient Feedback Appreciation" category is created automatically by running:
|
|
```bash
|
|
python manage.py create_patient_feedback_category
|
|
```
|
|
|
|
This category has:
|
|
- **Code**: `patient_feedback`
|
|
- **Name (EN)**: "Patient Feedback Appreciation"
|
|
- **Name (AR)**: "تقدير ملاحظات المرضى"
|
|
- **Hospital**: None (system-wide)
|
|
- **Icon**: `bi-heart`
|
|
- **Color**: `#388e3c` (green)
|
|
- **Order**: 100
|
|
|
|
## JavaScript Functions
|
|
|
|
### loadAppreciationCategories()
|
|
|
|
Loads appreciation categories from API and populates the category dropdown. Selects "Patient Feedback Appreciation" by default.
|
|
|
|
### loadAppreciationRecipients()
|
|
|
|
Loads recipient options based on recipient type:
|
|
- "user": Loads hospital staff
|
|
- "physician": Loads physicians from hospital
|
|
|
|
### convertToAppreciation()
|
|
|
|
Validates form data and submits conversion request to API:
|
|
- Validates required fields
|
|
- Shows loading state
|
|
- Handles success/error responses
|
|
- Redirects to appreciation detail page on success
|
|
|
|
## Use Cases
|
|
|
|
### Use Case 1: Quick Conversion
|
|
|
|
1. Patient submits positive feedback about Dr. Ahmed
|
|
2. Complaint is created with type "appreciation"
|
|
3. PX Admin reviews the complaint
|
|
4. PX Admin clicks "Convert to Appreciation"
|
|
5. Default settings are acceptable, checkbox checked to close complaint
|
|
6. Click "Convert"
|
|
7. Appreciation is created and sent to Dr. Ahmed
|
|
8. Complaint is closed
|
|
9. PX Admin is redirected to appreciation detail page
|
|
|
|
### Use Case 2: Customized Conversion
|
|
|
|
1. Patient submits positive feedback about Nurse Fatima
|
|
2. Complaint is created with type "appreciation"
|
|
3. PX Admin reviews and wants to customize the message
|
|
4. PX Admin clicks "Convert to Appreciation"
|
|
5. Changes recipient to different staff member
|
|
6. Edits English and Arabic messages for better phrasing
|
|
7. Changes visibility to "hospital" to showcase the appreciation
|
|
8. Keeps "Anonymous" sender option
|
|
7. Leaves "Close complaint" unchecked
|
|
8. Click "Convert"
|
|
9. Appreciation is created with custom settings
|
|
10. Complaint remains open for further processing
|
|
11. PX Admin is redirected to appreciation detail page
|
|
|
|
## Permissions
|
|
|
|
Only users with edit permissions on the complaint can convert it to appreciation:
|
|
- PX Admins
|
|
- Hospital Admins
|
|
- Department Managers (for their department)
|
|
|
|
## Error Handling
|
|
|
|
### Validation Errors
|
|
|
|
- **Not an appreciation complaint**: Clear error message explaining only appreciation-type complaints can be converted
|
|
- **Already converted**: Prevents duplicate conversions, shows appreciation link
|
|
- **Invalid recipient**: Validates recipient exists and is accessible
|
|
- **Invalid category**: Validates category ID is valid
|
|
- **Missing message**: Validates English message is provided
|
|
|
|
### Network Errors
|
|
|
|
- Failed API calls show alert with error details
|
|
- Button is re-enabled for retry
|
|
- No data loss on error
|
|
|
|
## Future Enhancements
|
|
|
|
Potential improvements for the feature:
|
|
|
|
1. **Bulk Conversion**: Convert multiple appreciation-type complaints at once
|
|
2. **Auto-Conversion**: Automatically convert appreciation-type complaints after N days
|
|
3. **Email Preview**: Preview appreciation email before sending
|
|
4. **Recipient Recommendations**: AI-suggested recipients based on complaint content
|
|
5. **Template Messages**: Pre-configured message templates for common scenarios
|
|
6. **Conversion History**: Track all conversion attempts with reasons
|
|
7. **Undo Conversion**: Ability to reverse a conversion (delete appreciation, restore complaint)
|
|
|
|
## Testing
|
|
|
|
### Test Scenarios
|
|
|
|
1. **Basic Conversion**:
|
|
- Create appreciation-type complaint
|
|
- Click convert button
|
|
- Accept defaults
|
|
- Verify appreciation created
|
|
- Verify complaint metadata updated
|
|
|
|
2. **Custom Conversion**:
|
|
- Edit all fields
|
|
- Change recipient
|
|
- Edit messages
|
|
- Verify custom values saved
|
|
|
|
3. **Close Complaint**:
|
|
- Enable close checkbox
|
|
- Verify complaint status changes to "closed"
|
|
- Verify status update timeline entry
|
|
|
|
4. **Keep Complaint Open**:
|
|
- Disable close checkbox
|
|
- Verify complaint status unchanged
|
|
- Verify only conversion timeline entry
|
|
|
|
5. **Already Converted**:
|
|
- Convert a complaint
|
|
- Try to convert again
|
|
- Verify error message
|
|
- Verify appreciation link shown
|
|
|
|
6. **Wrong Complaint Type**:
|
|
- Create regular "complaint" type
|
|
- Verify no convert button
|
|
- Attempt API call directly
|
|
- Verify error response
|
|
|
|
## Related Documentation
|
|
|
|
- [Complaint System Overview](../COMPLAINTS_IMPLEMENTATION_STATUS.md)
|
|
- [Appreciation System](../IMPLEMENTATION_COMPLETE.md#appreciation-system)
|
|
- [Complaint Types](../COMPLAINT_TYPE_CLASSIFICATION_IMPLEMENTATION.md)
|
|
- [Audit Service](../ARCHITECTURE.md#audit-service)
|
|
|
|
## Support
|
|
|
|
For issues or questions about the Complaint to Appreciation Conversion feature:
|
|
1. Check the Audit Log for conversion events
|
|
2. Review complaint metadata for `appreciation_id`
|
|
3. Verify appreciation record exists
|
|
4. Check timeline for conversion entries
|
|
5. Review browser console for JavaScript errors
|
|
6. Check Django logs for API errors
|