""" Referrals models for the Tenhal Multidisciplinary Healthcare Platform. This module handles inter-discipline and external referrals. """ from django.db import models from django.utils.translation import gettext_lazy as _ from core.models import ( UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ) class Referral(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin): """ Inter-discipline and external referrals. Tracks referrals between clinics and to external providers. """ class Discipline(models.TextChoices): MEDICAL = 'MEDICAL', _('Medical') NURSING = 'NURSING', _('Nursing') OT = 'OT', _('Occupational Therapy') SLP = 'SLP', _('Speech-Language Pathology') ABA = 'ABA', _('Applied Behavior Analysis') EXTERNAL = 'EXTERNAL', _('External Provider') class Urgency(models.TextChoices): ROUTINE = 'ROUTINE', _('Routine') URGENT = 'URGENT', _('Urgent') EMERGENCY = 'EMERGENCY', _('Emergency') class Status(models.TextChoices): PENDING = 'PENDING', _('Pending') ACCEPTED = 'ACCEPTED', _('Accepted') REJECTED = 'REJECTED', _('Rejected') COMPLETED = 'COMPLETED', _('Completed') CANCELLED = 'CANCELLED', _('Cancelled') # Core Relationships patient = models.ForeignKey( 'core.Patient', on_delete=models.CASCADE, related_name='referrals', verbose_name=_("Patient") ) # From (Source) from_clinic = models.ForeignKey( 'core.Clinic', on_delete=models.CASCADE, related_name='referrals_from', verbose_name=_("From Clinic") ) from_discipline = models.CharField( max_length=20, choices=Discipline.choices, verbose_name=_("From Discipline") ) from_provider = models.ForeignKey( 'core.User', on_delete=models.SET_NULL, null=True, related_name='referrals_made', verbose_name=_("From Provider") ) # To (Destination) - Internal or External to_clinic = models.ForeignKey( 'core.Clinic', on_delete=models.SET_NULL, null=True, blank=True, related_name='referrals_to', verbose_name=_("To Clinic") ) to_discipline = models.CharField( max_length=20, choices=Discipline.choices, blank=True, verbose_name=_("To Discipline") ) to_provider = models.ForeignKey( 'core.User', on_delete=models.SET_NULL, null=True, blank=True, related_name='referrals_received', verbose_name=_("To Provider") ) external_provider_name = models.CharField( max_length=200, blank=True, help_text=_("Name of external provider if referral is external"), verbose_name=_("External Provider Name") ) external_provider_contact = models.CharField( max_length=200, blank=True, verbose_name=_("External Provider Contact") ) # Referral Details reason = models.TextField( verbose_name=_("Reason for Referral") ) urgency = models.CharField( max_length=20, choices=Urgency.choices, default=Urgency.ROUTINE, verbose_name=_("Urgency") ) status = models.CharField( max_length=20, choices=Status.choices, default=Status.PENDING, verbose_name=_("Status") ) # Timestamps responded_at = models.DateTimeField( null=True, blank=True, verbose_name=_("Responded At") ) completed_at = models.DateTimeField( null=True, blank=True, verbose_name=_("Completed At") ) # Additional Information notes = models.TextField( blank=True, verbose_name=_("Notes") ) response_notes = models.TextField( blank=True, verbose_name=_("Response Notes") ) # Attachments (clinical documents, reports, etc.) clinical_summary = models.TextField( blank=True, help_text=_("Summary of clinical findings to share with receiving provider"), verbose_name=_("Clinical Summary") ) class Meta: verbose_name = _("Referral") verbose_name_plural = _("Referrals") ordering = ['-created_at'] indexes = [ models.Index(fields=['patient', 'status']), models.Index(fields=['from_clinic', 'created_at']), models.Index(fields=['to_clinic', 'status']), models.Index(fields=['status', 'urgency']), models.Index(fields=['tenant', 'created_at']), ] def __str__(self): if self.to_clinic: return f"Referral: {self.from_clinic.name_en} → {self.to_clinic.name_en} - {self.patient}" else: return f"Referral: {self.from_clinic.name_en} → {self.external_provider_name} - {self.patient}" @property def is_internal(self): """Check if referral is internal (within the same facility).""" return self.to_clinic is not None @property def is_external(self): """Check if referral is external.""" return self.to_clinic is None and bool(self.external_provider_name) @property def is_pending(self): """Check if referral is pending.""" return self.status == self.Status.PENDING @property def response_time(self): """Calculate response time in hours.""" if self.responded_at: delta = self.responded_at - self.created_at return round(delta.total_seconds() / 3600, 2) return None class ReferralAutoRule(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin): """ Automatic referral rules based on diagnoses or conditions. E.g., ASD diagnosis → auto-suggest referral to Pediatrician """ name = models.CharField( max_length=200, verbose_name=_("Rule Name") ) description = models.TextField( blank=True, verbose_name=_("Description") ) # Trigger Conditions trigger_clinic = models.ForeignKey( 'core.Clinic', on_delete=models.CASCADE, related_name='referral_auto_rules', verbose_name=_("Trigger Clinic") ) trigger_keywords = models.JSONField( default=list, help_text=_("Keywords in diagnosis/assessment that trigger this rule"), verbose_name=_("Trigger Keywords") ) # Target target_clinic = models.ForeignKey( 'core.Clinic', on_delete=models.SET_NULL, null=True, blank=True, related_name='referral_auto_rules_target', verbose_name=_("Target Clinic") ) target_external_provider = models.CharField( max_length=200, blank=True, verbose_name=_("Target External Provider") ) # Rule Configuration urgency = models.CharField( max_length=20, choices=Referral.Urgency.choices, default=Referral.Urgency.ROUTINE, verbose_name=_("Default Urgency") ) auto_create = models.BooleanField( default=False, help_text=_("Automatically create referral (vs. just suggest)"), verbose_name=_("Auto Create") ) is_active = models.BooleanField( default=True, verbose_name=_("Is Active") ) class Meta: verbose_name = _("Referral Auto Rule") verbose_name_plural = _("Referral Auto Rules") ordering = ['trigger_clinic', 'name'] def __str__(self): return f"{self.name} - {self.trigger_clinic.name_en}"