HH/COMPLAINT_CATEGORIES_FIX.md

4.5 KiB

Complaint Categories Fix - Multi-Hospital Support

Problem

The ComplaintCategory model had a ForeignKey relationship to Hospital, which prevented categories from being shared across multiple hospitals. Each category could only belong to one hospital.

Solution

Changed the ComplaintCategory model from a ForeignKey to a ManyToMany relationship with Hospital. This allows:

  • Categories to be assigned to multiple hospitals
  • Categories with no hospitals (system-wide) to be available to all hospitals
  • Each hospital to have its own custom categories while also accessing system-wide categories

Changes Made

1. Model Changes (apps/complaints/models.py)

  • Changed hospital = models.ForeignKey(...) to hospitals = models.ManyToManyField(...)
  • Removed Meta.indexes that referenced the old hospital field
  • Removed hospital-related Meta.constraints
  • Updated docstrings to reflect the new relationship

2. Migration Created (apps/complaints/migrations/0003_alter_complaintcategory_options_and_more.py)

  • Removes the old hospital field and its index
  • Adds the new hospitals ManyToMany field
  • Applies the changes successfully

3. Admin Interface Updated (apps/complaints/admin.py)

  • Added filter_horizontal = ['hospitals'] for better UI
  • Updated hospitals_display method to handle ManyToMany
  • Shows hospital count or "System-wide" for categories

4. Management Command Updated (apps/complaints/management/commands/load_complaint_categories.py)

  • Removed hospital reference from category/subcategory creation
  • Categories are now created without hospital assignments (system-wide)
  • Works correctly with the ManyToMany field

5. API Endpoint Updated (apps/complaints/ui_views.py)

# Old code:
categories_queryset = ComplaintCategory.objects.filter(
    Q(hospital_id=hospital_id) | Q(hospital__isnull=True),
    is_active=True
).order_by('-hospital', 'order', 'name_en')

# New code:
categories_queryset = ComplaintCategory.objects.filter(
    Q(hospitals__id=hospital_id) | Q(hospitals__isnull=True),
    is_active=True
).distinct().order_by('order', 'name_en')

Key changes:

  • Changed hospital_id=hospital_id to hospitals__id=hospital_id
  • Changed hospital__isnull=True to hospitals__isnull=True
  • Added .distinct() to remove duplicates
  • Removed -hospital from ordering (no longer applicable)

Testing Results

Database Verification

Total parent categories: 5
Categories with hospitals: 0
System-wide categories: 5

API Endpoint Test

Response status: 200
Categories count: 21
Sample categories:
  - Cleanliness (Parent ID: 8952a7e3..., ID: 43ec2d94...)  ← Subcategory
  - Diagnosis concerns (Parent ID: 9e99195c..., ID: 20ce76ab...)  ← Subcategory
  - Privacy & Confidentiality (Parent ID: 755b053e..., ID: 564583fd...)  ← Subcategory
  - Quality of Care & Treatment (Parent ID: None, ID: 9e99195c...)  ← Parent
  - Staff attitude (Parent ID: b6302801..., ID: ffa88ba9...)  ← Subcategory

How It Works

System-Wide Categories (Default)

Categories created without any hospital assignments are available to ALL hospitals:

category = ComplaintCategory.objects.create(
    code='quality_care',
    name_en='Quality of Care & Treatment',
    # No hospitals specified → available to all
)

Hospital-Specific Categories

Categories can be assigned to specific hospitals:

from apps.organizations.models import Hospital

hospitals = Hospital.objects.filter(status='active')
category = ComplaintCategory.objects.create(
    code='special_category',
    name_en='Special Category'
)
category.hospitals.add(*hospitals)  # Assign to multiple hospitals

Querying Categories

The API endpoint returns:

  1. Hospital-specific categories (assigned to the hospital)
  2. System-wide categories (no hospital assignment)
  3. Both parent categories and their subcategories

Benefits

  1. Flexibility: Hospitals can share common categories while maintaining custom ones
  2. Efficiency: No need to duplicate categories for each hospital
  3. Scalability: Easy to add new categories that apply to all hospitals
  4. Maintainability: System-wide changes can be made in one place

Future Enhancements

  1. Category Prioritization: Add a field to prioritize hospital-specific over system-wide categories
  2. Category Copying: Create a management command to copy system-wide categories to hospital-specific
  3. Category Versioning: Track changes to categories over time
  4. Category Analytics: Report on which categories are most used per hospital