PX Sources App
A standalone Django app for managing the origins of patient feedback (Complaints and Inquiries).
Features
- Full CRUD Operations: Create, Read, Update, and Delete PX Sources
- Bilingual Support: Names and descriptions in both English and Arabic
- Flexible Source Types: Sources can be configured for complaints, inquiries, or both
- Usage Tracking: Track how sources are used across the system
- Soft Delete: Deactivate sources without deleting them (maintains data integrity)
- Role-Based Access: PX Admins have full access, others have restricted access
- REST API: Complete API endpoints for integration with other apps
- Admin Interface: Full Django admin interface for management
- UI Templates: Complete HTML interface following project conventions
Models
PXSource
The main model for managing feedback sources.
Fields:
code(CharField): Unique code for programmatic reference (e.g., 'PATIENT', 'FAMILY')name_en(CharField): Source name in Englishname_ar(CharField): Source name in Arabic (optional)description_en(TextField): Description in English (optional)description_ar(TextField): Description in Arabic (optional)source_type(CharField): Type - 'complaint', 'inquiry', or 'both'order(IntegerField): Display order (lower numbers appear first)is_active(BooleanField): Active status (can be deactivated without deletion)icon_class(CharField): CSS class for icon display (optional)color_code(CharField): Hex color code for UI display (optional)metadata(JSONField): Additional configuration or metadata
Methods:
get_localized_name(language): Get name in specified languageget_localized_description(language): Get description in specified languageactivate(): Activate the sourcedeactivate(): Deactivate the sourceget_active_sources(source_type=None): Class method to get active sourcesget_by_code(code): Class method to get source by code
SourceUsage
Tracks usage of sources across the system for analytics.
Fields:
source(ForeignKey): Reference to PXSourcecontent_type(ForeignKey): Type of related object (Complaint, Inquiry, etc.)object_id(UUIDField): ID of related objecthospital(ForeignKey): Hospital context (optional)user(ForeignKey): User who selected the source (optional)
API Endpoints
REST API
Base URL: /px-sources/api/sources/
Endpoints:
GET /px-sources/api/sources/- List all sourcesPOST /px-sources/api/sources/- Create a new sourceGET /px-sources/api/sources/{id}/- Retrieve source detailsPUT /px-sources/api/sources/{id}/- Update source (full)PATCH /px-sources/api/sources/{id}/- Update source (partial)DELETE /px-sources/api/sources/{id}/- Delete sourceGET /px-sources/api/sources/choices/?source_type=complaint- Get choices for dropdownsPOST /px-sources/api/sources/{id}/activate/- Activate a sourcePOST /px-sources/api/sources/{id}/deactivate/- Deactivate a sourceGET /px-sources/api/sources/types/- Get available source typesGET /px-sources/api/sources/{id}/usage/- Get usage statistics
UI Views
/px-sources/- List all sources/px-sources/new/- Create a new source/px-sources/{id}/- View source details/px-sources/{id}/edit/- Edit source/px-sources/{id}/delete/- Delete source/px-sources/{id}/toggle/- Toggle active status (AJAX)/px-sources/ajax/search/- AJAX search endpoint/px-sources/ajax/choices/- AJAX choices endpoint
Usage Examples
Using the API
import requests
# Get active sources for complaints
response = requests.get('http://localhost:8000/px-sources/api/sources/choices/?source_type=complaint')
sources = response.json()
print(sources)
# Create a new source
new_source = {
'code': 'NEW_SOURCE',
'name_en': 'New Source',
'name_ar': 'مصدر جديد',
'description_en': 'A new source for feedback',
'source_type': 'both',
'order': 10,
'is_active': True
}
response = requests.post('http://localhost:8000/px-sources/api/sources/', json=new_source)
print(response.json())
Using in Code
from apps.px_sources.models import PXSource, SourceType
# Get active sources for complaints
complaint_sources = PXSource.get_active_sources(source_type=SourceType.COMPLAINT)
# Get a source by code
patient_source = PXSource.get_by_code('PATIENT')
# Get localized name
name_ar = patient_source.get_localized_name('ar')
name_en = patient_source.get_localized_name('en')
# Deactivate a source
patient_source.deactivate()
Integration with Other Apps
To integrate PX Sources with Complaint or Inquiry models:
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from apps.px_sources.models import PXSource, SourceUsage
# In your model (e.g., Complaint)
class Complaint(models.Model):
source = models.ForeignKey(
PXSource,
on_delete=models.PROTECT,
related_name='complaints'
)
# ... other fields
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
# Track usage
SourceUsage.objects.create(
source=self.source,
content_type=ContentType.objects.get_for_model(self.__class__),
object_id=self.id,
hospital=self.hospital,
user=self.created_by
)
Default Sources
Common sources that can be seeded:
PATIENT- Direct patient feedbackFAMILY- Family member reportsSTAFF- Staff reportsSURVEY- Survey responsesSOCIAL_MEDIA- Social media feedbackCALL_CENTER- Call center interactionsMOH- Ministry of HealthCHI- Council of Health InsuranceOTHER- Other sources
Permissions
- PX Admins: Full access (create, read, update, delete, activate/deactivate)
- Hospital Admins: Can create, read, update sources
- Other Users: Read-only access to active sources
Templates
px_sources/source_list.html- List view with filterspx_sources/source_form.html- Create/Edit formpx_sources/source_detail.html- Detail view with usage statisticspx_sources/source_confirm_delete.html- Delete confirmation
Admin Configuration
The app includes a full Django admin interface with:
- List view with filters (source type, active status, date)
- Search by code, names, and descriptions
- Inline editing of order field
- Detailed fieldsets for organized display
- Color-coded badges for source type and status
Database Indexes
Optimized indexes for performance:
is_active,source_type,order(composite)code(unique)created_at(timestamp)
Audit Logging
All source operations are logged via the AuditService:
- Creation events
- Update events
- Deletion events
- Activation/Deactivation events