""" PX Sources models - Manages origins of patient feedback This module implements the PX Source management system that: - Tracks sources of patient feedback (Complaints and Inquiries) - Supports bilingual naming (English/Arabic) - Enables status management """ from django.db import models from django.utils.translation import gettext_lazy as _ from apps.core.models import UUIDModel, TimeStampedModel class PXSource(UUIDModel, TimeStampedModel): """ PX Source model for managing feedback origins. Simple model with bilingual naming and active status management. """ # Bilingual names name_en = models.CharField( max_length=200, help_text="Source name in English" ) name_ar = models.CharField( max_length=200, blank=True, help_text="Source name in Arabic" ) # Description description = models.TextField( blank=True, help_text="Detailed description" ) # Status is_active = models.BooleanField( default=True, db_index=True, help_text="Whether this source is active for selection" ) class Meta: ordering = ['name_en'] verbose_name = 'PX Source' verbose_name_plural = 'PX Sources' indexes = [ models.Index(fields=['is_active', 'name_en']), ] def __str__(self): return self.name_en def get_localized_name(self, language='en'): """Get localized name based on language""" if language == 'ar' and self.name_ar: return self.name_ar return self.name_en def get_localized_description(self): """Get localized description""" return self.description def activate(self): """Activate this source""" if not self.is_active: self.is_active = True self.save(update_fields=['is_active']) def deactivate(self): """Deactivate this source""" if self.is_active: self.is_active = False self.save(update_fields=['is_active']) @classmethod def get_active_sources(cls): """ Get all active sources. Returns: QuerySet of active PXSource objects """ return cls.objects.filter(is_active=True).order_by('name_en') class SourceUser(UUIDModel, TimeStampedModel): """ Links users to PX Sources for management. A user can be a source manager for a specific PX Source, allowing them to create complaints and inquiries from that source. """ user = models.OneToOneField( 'accounts.User', on_delete=models.CASCADE, related_name='source_user_profile', help_text="User who manages this source" ) source = models.ForeignKey( PXSource, on_delete=models.CASCADE, related_name='source_users', help_text="Source managed by this user" ) # Status is_active = models.BooleanField( default=True, db_index=True, help_text="Whether this source user is active" ) # Permissions can_create_complaints = models.BooleanField( default=True, help_text="User can create complaints from this source" ) can_create_inquiries = models.BooleanField( default=True, help_text="User can create inquiries from this source" ) class Meta: ordering = ['source__name_en'] verbose_name = 'Source User' verbose_name_plural = 'Source Users' indexes = [ models.Index(fields=['user', 'is_active']), models.Index(fields=['source', 'is_active']), ] unique_together = [['user', 'source']] def __str__(self): return f"{self.user.email} - {self.source.name_en}" def activate(self): """Activate this source user""" if not self.is_active: self.is_active = True self.save(update_fields=['is_active']) def deactivate(self): """Deactivate this source user""" if self.is_active: self.is_active = False self.save(update_fields=['is_active']) @classmethod def get_active_source_user(cls, user): """ Get active source user for a user. Returns: SourceUser object or None """ return cls.objects.filter(user=user, is_active=True).first() class SourceUsage(UUIDModel, TimeStampedModel): """ Tracks usage of sources across the system. This model can be used to analyze which sources are most commonly used, track trends, and generate reports. """ source = models.ForeignKey( PXSource, on_delete=models.CASCADE, related_name='usage_records' ) # Related object (could be Complaint, Inquiry, or other feedback types) content_type = models.ForeignKey( 'contenttypes.ContentType', on_delete=models.CASCADE, help_text="Type of related object" ) object_id = models.UUIDField(help_text="ID of related object") # Hospital context (optional) hospital = models.ForeignKey( 'organizations.Hospital', on_delete=models.SET_NULL, null=True, blank=True, related_name='source_usage_records', help_text="Hospital where this source was used" ) # User who selected this source (optional) user = models.ForeignKey( 'accounts.User', on_delete=models.SET_NULL, null=True, blank=True, related_name='source_usage_records', help_text="User who selected this source" ) class Meta: ordering = ['-created_at'] verbose_name = 'Source Usage' verbose_name_plural = 'Source Usages' indexes = [ models.Index(fields=['source', '-created_at']), models.Index(fields=['content_type', 'object_id']), models.Index(fields=['hospital', '-created_at']), models.Index(fields=['created_at']), ] unique_together = [['content_type', 'object_id']] def __str__(self): return f"{self.source} - {self.created_at.strftime('%Y-%m-%d %H:%M')}"