from django.db import models from django.contrib.auth import get_user_model from django.utils.translation import gettext_lazy as _ from core.models import Patient User = get_user_model() class DocumentTemplate(models.Model): """ Reusable document templates for clinical notes and other documents. """ CATEGORY_CHOICES = [ ('medical', _('Medical')), ('nursing', _('Nursing')), ('aba', _('ABA')), ('ot', _('Occupational Therapy')), ('slp', _('Speech-Language Pathology')), ('assessment', _('Assessment')), ('progress', _('Progress Report')), ('discharge', _('Discharge Summary')), ('other', _('Other')), ] name = models.CharField(_('Template Name'), max_length=200) category = models.CharField(_('Category'), max_length=50, choices=CATEGORY_CHOICES) description = models.TextField(_('Description'), blank=True) content = models.TextField(_('Template Content'), help_text=_('Use {{variable_name}} for dynamic fields')) is_active = models.BooleanField(_('Active'), default=True) created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='created_templates') created_at = models.DateTimeField(_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(_('Updated At'), auto_now=True) class Meta: verbose_name = _('Document Template') verbose_name_plural = _('Document Templates') ordering = ['category', 'name'] def __str__(self): return f"{self.name} ({self.get_category_display()})" class ClinicalNote(models.Model): """ Clinical notes and documentation for patient care. """ STATUS_CHOICES = [ ('draft', _('Draft')), ('final', _('Final')), ('amended', _('Amended')), ('deleted', _('Deleted')), ] patient = models.ForeignKey(Patient, on_delete=models.CASCADE, related_name='clinical_notes') template = models.ForeignKey(DocumentTemplate, on_delete=models.SET_NULL, null=True, blank=True, related_name='notes') title = models.CharField(_('Title'), max_length=200) content = models.TextField(_('Content')) status = models.CharField(_('Status'), max_length=20, choices=STATUS_CHOICES, default='draft') # Metadata author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='authored_notes') created_at = models.DateTimeField(_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(_('Updated At'), auto_now=True) finalized_at = models.DateTimeField(_('Finalized At'), null=True, blank=True) finalized_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='finalized_notes') # Versioning version = models.IntegerField(_('Version'), default=1) parent_note = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='amendments') class Meta: verbose_name = _('Clinical Note') verbose_name_plural = _('Clinical Notes') ordering = ['-created_at'] permissions = [ ('can_finalize_note', 'Can finalize clinical notes'), ('can_amend_note', 'Can amend finalized notes'), ] def __str__(self): return f"{self.title} - {self.patient.get_full_name()} ({self.created_at.strftime('%Y-%m-%d')})" class NoteAddendum(models.Model): """ Addendums to clinical notes for corrections or additional information. """ note = models.ForeignKey(ClinicalNote, on_delete=models.CASCADE, related_name='addendums') content = models.TextField(_('Addendum Content')) reason = models.CharField(_('Reason'), max_length=200) author = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) created_at = models.DateTimeField(_('Created At'), auto_now_add=True) class Meta: verbose_name = _('Note Addendum') verbose_name_plural = _('Note Addendums') ordering = ['-created_at'] def __str__(self): return f"Addendum to {self.note.title} - {self.created_at.strftime('%Y-%m-%d %H:%M')}" class NoteAuditLog(models.Model): """ Audit trail for clinical note changes. """ ACTION_CHOICES = [ ('created', _('Created')), ('updated', _('Updated')), ('finalized', _('Finalized')), ('amended', _('Amended')), ('deleted', _('Deleted')), ('viewed', _('Viewed')), ] note = models.ForeignKey(ClinicalNote, on_delete=models.CASCADE, related_name='audit_logs') action = models.CharField(_('Action'), max_length=20, choices=ACTION_CHOICES) user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) timestamp = models.DateTimeField(_('Timestamp'), auto_now_add=True) ip_address = models.GenericIPAddressField(_('IP Address'), null=True, blank=True) changes = models.JSONField(_('Changes'), null=True, blank=True) class Meta: verbose_name = _('Note Audit Log') verbose_name_plural = _('Note Audit Logs') ordering = ['-timestamp'] def __str__(self): return f"{self.get_action_display()} - {self.note.title} by {self.user} at {self.timestamp}"